2009-09-05 14 views
23

Çok basit bir WPF pencerem var - içindeki tek şey sağa hizalanmış bir düğme. Pencereyi sol sınır sürükleyerek yeniden boyutlandırdığımda, düğme etrafa atlar - çok fazla. Kendiniz deneyin, sol sınırını ileri geri sürükleyin.WPF formunu yeniden boyutlandırma nasıl düzeltilir - arkadan ve siyah arka plandan geri kalma kontrol eder?

Ayrıca, siyah bir arka plan boyutlandırır sırasında geçici olarak açıkta kalır.

this soru, ben, Windows Formlar ile ilgili benzer bir soru sordu. Tek cevabım, bunun WPF'de düzeltildiğini gösterdi, ancak şaşırtıcı bir şekilde, sadece sabit değil, WPF de ikinci bir görsel hata - geçici siyah arka plan ekler.

Kontrol gecikmesi aşağıdaki gibi görünüyor; Bu ben üst sınırında pencereyi yeniden boyutlandırmak oluşur (ekran-cap yaparak daha az belli yapılmış çünkü bir kamera ile kaydedilmiş her şey yavaş):

                                                  enter image description here

Siyah kenarlık örneği: bu pencere yeniden boyutlandırılırken yakalandı; o bir an için yalnızca bu gibi ama çok fark var:

                                      enter image description here

Yanlış mı yapıyorum? Yeniden düzenlemeler sırasında denetimlerim görsel olarak tek bir yerde nasıl kalabilir? Siyah sınırı nasıl önleyebilirim?

Not: düğme doğru yerde sonunda içinde biter - bu sadece yeniden boyutlandırma sırasında etrafında kısaca atlar.

+0

Sadece bu fikri göstermek için ekran görüntülerinin bir listesini oluşturdum. –

+5

Bu beni şok ediyor. Microsoft, güzel kullanıcı arayüzlerini tasarlamak ve bu korkunç görsel hatayı tanıtmak için harika bir teknoloji oluşturuyor. –

cevap

10

Bu, Wieser Software Ltd'nin 2. çözümüne dayanan eksiksiz bir çalışma kodudur.

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

Bu, gösterilen siyah bitin rengini değiştirmek için çalışır. Bu, pencerenin içeriğine bağlı olarak sorunu bir ölçüde hafifletebilir. Tabii ki karmaşık arkaplanlar için (bir görüntü gibi), ortaya çıkan problemin altta yatan problemi (kontrol düzeni gecikmesi ve pencerenin boyanmamış kısımlarının kısa süreli olarak görülebilmesi) hâlâ hala yanlıştır. –

1

Ben geçici siyah arka plan WPF render mekanizması olarak DirectX kullanır ve pencereleri yeniden boyutlandırmak zaman pencereleme sistemi ile çizim eşitlemek zorunda olduğu gerçeği ile ilgili bir WPF sorunu olduğuna inanıyoruz. Bu ayrıca pencere kenarlığını sürüklerken düğmenin pencereye göre neden yanlış olduğunu açıklayabilir. Pencerenin istem dışı alanını çizmek, pencerenin içinde ne çizdiğinden çok daha yavaştır ve fareyi hızlı bir şekilde hızlı bir şekilde hareket ettirirseniz, kenarlık arasındaki farklar pencerenin iç tarafları arasında muhtemelen daha fazla fark edilir.

Sözde bu sadece Aero etkin olan Vista oluyor ve Vista SP1 sabit olması gerekirdi. Bununla birlikte, sadece SP2 üzerinde test ettim ve hala biraz siyah arka plan gördüm, ancak sadece Aero etkinken. Grafik kartım oldukça hızlı ve bu nedenle neredeyse hiç fark edilmiyordu.

Analizim doğruysa, sorununuzu çözmenin tek yolu daha hızlı bir grafik kartı almak veya Aero'yu kapatmaktır.

+0

Teşekkürler, öneriniz bunu daha az fark edilebilir kılabilir ama tamamen ortadan kaldıramaz. Sorun ne kadar uzun süre göründüğü değil, ama görünürde de ... Bu arada, sorun Win7 RTM'de de var. –

+5

WPF4.0 ve Win7 64bit SP1 ile birlikte görüyorum. – sprocket12

2

Bu, WPF'nin geçerli sürümlerinde mümkün görünmüyor.

4

Orada burada açıklanan iki çözüm vardır: http://wieser-software.blogspot.co.uk/2012/06/wpf-window-rendering-woes.html

  1. Kanca WndProc ve WM_ERASEBKGND işlemek ve arka plan veya başvurunuz tema uygun başka bir renk sistem WINDOW_COLOR çizin.
  2. Çağrı SetClassLong Pencere sınıfı Background Fırça

    SetClassLong ayarlamak için (Kulp GCL_HBRBACKGROUND, GetSysColorBrush (COLOR_WINDOW));

+0

Bu, rengi değiştirir +1, ancak ben ilk etapta renk göstermeye çalışıyorum. Demek istediğim, her şeyin arka arkaya yeniden doldurulan GDI günleri gibi. Çift-tampon yapamaz mı? ... :) –

+0

Farklı bir efekt için camı istemci alanına genişletebilirsiniz, ancak sadece aero açıksa çalışır. –

İlgili konular