2009-09-05 12 views
23

私は非常に単純なWPFウィンドウを持っています - その中の唯一のものは右揃えのボタンです。左の境界線をドラッグしてウィンドウのサイズを変更すると、ボタンが飛びます。自分で試して、左の境界線を前後にドラッグしてください。WPFフォームのサイズを変更するにはどうすればいいですか?

また、黒の背景は、サイズ変更中に一時的に露出します。 this質問に

、私は、Windowsフォームについて同様の質問をしました。私はこれがWPFで修正されたという唯一の答えですが、驚くほど、修正されているだけでなく、一時的な黒い背景であるもう一つの視覚的なバグも追加されています。

制御の遅れは次のようになります。これは私がその上部の境界線によってウィンドウのサイズを変更するときに発生する(画面-キャップは作ることによって、それはあまり明らかに作られたので、カメラで撮影したすべてのものが遅い):

                                                enter image description here

黒い枠線の例:これはウィンドウのサイズを変更するときにキャプチャされました。それは一瞬のためにこれだけのようだが、それは非常に顕著です:

                                      enter image description here

私が何か間違ったことをやっていますか?サイズ変更中にコントロールを視覚的に1か所に保持するにはどうすればよいですか?どのように黒い枠線を避けることができますか?

:ボタンが正しい場所結局で終わる - それは唯一のサイズ変更中に周りの簡単にをジャンプします。

+0

アイデアを示すためにスクリーンショットのリストを作成しました。 –

+5

それは私にショックを与え続けます。マイクロソフトでは、美しいユーザーインターフェイスを設計する素晴らしいテクノロジを作成し、このひどいビジュアルバグを導入しました。 –

答えて

10

これはWieser Software Ltdの第2の解決策に基づく完全な作業コードです。

public partial class MainView : Window 
{ 
    public MainView() 
    { 
     InitializeComponent(); 

     //ensure win32 handle is created 
     var handle = new WindowInteropHelper(this).EnsureHandle(); 

     //set window background 
     var result = SetClassLong(handle, GCL_HBRBACKGROUND, GetSysColorBrush(COLOR_WINDOW)); 
    } 

    public static IntPtr SetClassLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong) 
    { 
     //check for x64 
     if (IntPtr.Size > 4) 
      return SetClassLongPtr64(hWnd, nIndex, dwNewLong); 
     else 
      return new IntPtr(SetClassLongPtr32(hWnd, nIndex, unchecked((uint)dwNewLong.ToInt32()))); 
    } 

    private const int GCL_HBRBACKGROUND = -10; 
    private const int COLOR_WINDOW = 5; 

    [DllImport("user32.dll", EntryPoint = "SetClassLong")] 
    public static extern uint SetClassLongPtr32(IntPtr hWnd, int nIndex, uint dwNewLong); 

    [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")] 
    public static extern IntPtr SetClassLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong); 

    [DllImport("user32.dll")] 
    static extern IntPtr GetSysColorBrush(int nIndex); 
} 
+0

これは、表示される黒いビットの色を変更するために機能します。これにより、ウィンドウの内容に応じて問題がある程度緩和されます。もちろん、複雑な背景(画像など)の場合、基本的な問題(コントロールのレイアウトの遅れや、ウィンドウの塗装されていない部分が簡単に見える)がまだ残っているため、表示されるビットはまだ間違っています。 –

1

は、私は一時的な黒の背景は、WPFレンダリングメカニズムとしてのDirectXを使用し、あなたは窓のサイズを変更するとき、それはウィンドウシステムで描画を同期させるために持っているという事実に関連するWPFの問題であると考えています。これは、ウィンドウの境界線をドラッグしているときに、ボタンがウィンドウに対して配置されていない理由を説明します。ウィンドウの非クライアント領域を描画するのは、ウィンドウ内の描画よりもはるかに遅く、遅いコンピュータでマウスを高速に動かすと、ウィンドウの境界内の矛盾が目立つようになります。

たぶんこれが唯一の有効なエアロとVista上で起こり、それはVistaのSP1で修正されている必要があります。しかし、私はSP2でテストしましたが、まだ黒の背景が少ししか見えませんでしたが、Aeroが有効になっていたときだけでした。私のグラフィックスカードはかなり速いのでほとんど目立たなかった。

私の分析が正しい場合は、問題を解決できる唯一の方法は、より速いグラフィックカードを取得するか、Aeroをオフにすることです。

+0

ありがとうございます、あなたの提案はこれを目立たないようにするかもしれませんが、それを完全に排除することはできません。この問題は、どのくらい見えているかではなく、目に見えるものです...ところで、この問題はWin7 RTMでも発生しています。 –

+5

私はWPF4.0とWin7 64bit SP1で見ています – sprocket12

2

これは現在のバージョンのWPFでは可能ではないようです。

4

あり、ここで説明した2つのソリューション、以下のとおりです。 http://wieser-software.blogspot.co.uk/2012/06/wpf-window-rendering-woes.html

  1. フックのWndProcをとWM_ERASEBKGNDを処理し、バックグラウンドのシステムWINDOW_COLOR、またはアプリケーションのテーマに合わせて別の色を描画します。
  2. コールSetClassLongはウィンドウクラス背景ブラシ

    SetClassLongを設定する(ハンドルGCL_HBRBACKGROUND、GetSysColorBrush(COLOR_WINDOW))。

+0

これは実際には+1の色を変えますが、色を最初から表示しないようにしようとしています。私は、すべてがバックツーフロントで再描画されるGDIの日のようなものだということです。ダブルバッファーできませんか... ... –

+0

クライアントを別のエフェクトのためにクライアント領域に拡張することはできますが、エアロがオンの場合にのみ機能します。 –

関連する問題