Winform アプリケーションでフォームの背景がちらつく問題を解決する

Winform アプリケーションでフォームの背景がちらつく問題を解決する

最近、コードにいくつかの最適化が行われ、テスト後の効果は悪くありませんでしたが、インターフェイスがちらつきます。具体的には TreeView コントロールがちらつきます。言語は C#、IDE は VS2005 です。いくつかの情報を参照し、いくつかの基本的なテクニック (ダブル バッファリングをオンにするなど) を使用した結果、効果がないことがわかりました。

    于是使用Profiler工具,查找出瓶颈在于每次更新完界面的EndUpdate操作(使用这个是为了减少界面更新次数,但这里不理想是因为控件中中的元素很多),猜想大概每次更新,.Net底层都会更新重绘每个图元,所以速度会慢,造成闪烁。但是如果这样,使用双缓冲应该会有较好效果。再看代码,发现可能是更新动作太过频繁,于是降低速度,有所好转,但还是不行。

   继续在网上查阅,最终找到一个方案比较合适。原来底层重绘每次会清除画布,然后再全部重新绘制,这才是导致闪烁最主要的原因。于是重载消息发送函数操作,禁掉这条消息。代码如下:

protected オーバーライド void WndProc(ref Message m)

{

    if (m.Msg == 0x0014) // 禁掉清除背景消息

        return;

    base.WndProc(ref m);

}

    成功!

注: ダブル バッファリングは、更新がそれほど頻繁ではなく、コントロールに含まれる要素が多すぎない場合には依然として役立ちます。要素が多くなりすぎると毎回の更新に時間がかかり、ダブルバッファリングをしてもちらつきの問題は解決できません。個人的には、最終的な理想的な方法は、バックグラウンド メッセージを無効にして消去することだと考えています。

添付: 試みられたが失敗したいくつかの記録

1) setStyle を使用する

  网上有说使用setStyle函数去设置该控件的参数,具体为:

  SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);

  这三个选项参数后者是依赖前者的,必须并存,否则无效。并且这个函数本身是protected的,所以首先需要继承某控件再使用。

  这个目标是跟前面正确解决方案一致,也是禁止清除背景并开启双缓冲,但需要使用用户绘制选项,而且是全部交由用户绘制。这需要自己实现控件的全部绘制,比较麻烦。所以这个方法不是完全不可行,但是需要额外工作量,不推荐。我也没有使用。

2) BeginUpdate と EndUpdate を使用する

  这一对操作对于需要批量操作更新控件的情景有比较好的效果,比如初始化时批量添加了大量节点。坏处就在于不能即时更新。所以,对于频繁的更新节点并希望立即反映到界面的情况不适用。如果使用并且没有禁掉清除界面消息的话,则控件看起来就会不停的闪烁,而且以白底为主,内容几乎不可见(这个视频繁程度而定)。因为界面更新都在EndUpdate处完成,操作太多导致EndUpdate阻塞时间过长,且清空在先,更新在后,导致界面看起来长时间处于空白状态。

3) ControlStyles.EnableNotifyMessage オプションを使用します。

  这个选项的作用和正确解决方案也是一致的。使用方法是:

  SetStyle(ControlStyles.EnableNotifyMessage, true);

  protected override void onNotifyMessage(Message m)

  {

           // 此处书写过滤消息代码

  }

  但是实际实验显示无效果,不知是什么原因,没有细究。

私のオペレーティング システムは Win7 で、使用する VS のバージョンは VS2012 です。この記事のコードはすべて C# コードです。

ここ数日間、次の図に示すように、画像が埋め込まれたパネルを Winform アプリケーションの背景として使用しているという問題が発生しました。

これは Winform フォームで、Panel が内部に配置されており、Dock プロパティは Fill、BackgroundImage は「Youth Electric World」2003 年 02 号の表紙画像を使用し、BackgroundImageLayout はストレッチを使用しています。

このインターフェースには現在 2 つの問題があります。

1.初めてフォームを開いたとき、背景画像がちらつきます

2. フォームの境界線を引いてフォームのサイズを変更すると、背景画像がちらつきません。

この問題に対処するために、いくつかの情報を確認し、一つずつ試してみましたが、代表的な 2 つの方法について説明します。

方法 1: ダブル バッファリングを直接使用する

SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 背景の消去を無効にします
SetStyle(ControlStyles.DoubleBuffer, true); // ダブルバッファリング
このコードをコンストラクター内のフォームに追加してみます問題は解決しませんが、ちらつきは依然として非常に明白です

MSDN には「フォームとコントロールにダブル バッファリングを使用してグラフィックスのちらつきを軽減する方法」という記事もあります。

アドレス: https://msdn.microsoft.com/zh-cn/library/3t7htc9c%28v=vs.80%29.aspx

この記事では、ダブル バッファリングを使用する方法も紹介します。

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
このメソッドではまだ問題を解決できません。

方法 2: CreateParams メソッドをオーバーライドする

方法 2 では、Form クラスのコードに次のコードを挿入する必要があります。

protected override CreateParams CreateParams
{
    
    
    get
    {
    
    
        CreateParams paras = base.CreateParams;
        paras.ExStyle |= 0x02000000;用双缓冲绘制窗口的所有子控件
        return paras;
    }


}

最初にこの方法を試したときは効果があると思ったのですが、しばらく使ってみると次のような問題が見つかりました。

1. この方法では問題 1 は解決できますが、問題 2 は解決できません。

2. このメソッドは、他のいくつかのコントロールやコンポーネントの再描画に影響します (これは致命的です)。

したがって、この方法でも問題を解決することはできません。

上記 2 つの方法のどちらも問題を解決できなかったので、私は Du Niang に助けを求め続け、最終的に次のページで解決策を見つけました。

方法 3:Panel クラスをカプセル化する

http://blog.chinaunix.net/uid-14414741-id-2814313.html

このメソッドでは、Panel クラスを継承する新しいPanelEnhanced クラスを作成する必要があります。コードは次のとおりです。

/// <summary>
/// 加强版 Panel
/// </summary>
class PanelEnhanced : Panel
{
    
    
    /// <summary>
    /// OnPaintBackground 事件
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaintBackground(PaintEventArgs e)
    {
    
    
        // 重载基类的背景擦除函数,
        // 解决窗口刷新,放大,图像闪烁
        return;
    }
 
    /// <summary>
    /// OnPaint 事件
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    {
    
    
        // 使用双缓冲
        this.DoubleBuffered = true;
        // 背景重绘移动到此
        if (this.BackgroundImage != null)
        {
    
    
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            e.Graphics.DrawImage(
                this.BackgroundImage,
                new System.Drawing.Rectangle(0, 0, this.Width, this.Height),
                0,
                0,
                this.BackgroundImage.Width,
                this.BackgroundImage.Height,
                System.Drawing.GraphicsUnit.Pixel);
        }
        base.OnPaint(e);
    }
}

以前に作成したフォームのPanelコンテナを新しくパッケージ化したPanelEnhancedコンテナに置き換え、その中にプログラムの背景画像を入れてプログラムを実行すると、プログラムの背景がちらつく問題は完全に解決されました。

終わり

おすすめ

転載: blog.csdn.net/kalvin_y_liu/article/details/128136015