كيفية مضاعفة المخزن المؤقت لعناصر تحكم .NET في النموذج؟

StackOverflow https://stackoverflow.com/questions/76993

سؤال

كيف يمكنني ضبط المحمية DoubleBuffered خاصية الضوابط على النموذج الذي يعاني من وميض؟

هل كانت مفيدة؟

المحلول

إليك نسخة أكثر عمومية من حل الدمية.

يمكننا استخدام التأمل للوصول إلى المحمية DoubleBuffered الخاصية، وبعد ذلك يمكن ضبطها على حقيقي.

ملحوظة:يجب دفع ضرائب المطور الخاص بك و لا استخدم التخزين المؤقت المزدوج إذا كان المستخدم يعمل في جلسة خدمات طرفية (على سبيل المثالسطح المكتب البعيد) لن تقوم طريقة المساعد هذه بتشغيل التخزين المؤقت المزدوج إذا كان الشخص يعمل على سطح المكتب البعيد.

public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
   //Taxes: Remote Desktop Connection and painting
   //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
   if (System.Windows.Forms.SystemInformation.TerminalServerSession)
      return;

   System.Reflection.PropertyInfo aProp = 
         typeof(System.Windows.Forms.Control).GetProperty(
               "DoubleBuffered", 
               System.Reflection.BindingFlags.NonPublic | 
               System.Reflection.BindingFlags.Instance);

   aProp.SetValue(c, true, null); 
}

نصائح أخرى

يفحص هذا الموضوع

بتكرار جوهر هذه الإجابة، يمكنك تشغيل علامة النمط WS_EX_COMPOSITED في النافذة للحصول على تخزين مؤقت مزدوج للنموذج وجميع عناصر التحكم الخاصة به.علامة النمط متاحة منذ XP.إنه لا يجعل الرسم أسرع ولكن يتم رسم النافذة بأكملها في مخزن مؤقت خارج الشاشة ويتم لصقها على الشاشة بضربة واحدة.جعلها تبدو فورية لعين المستخدم دون وجود تحف فنية مرئية.إنه ليس خاليًا من المشاكل تمامًا، حيث يمكن لبعض عارضي الأنماط المرئية حدوث خلل فيه، خاصة TabControl عندما يحتوي على عدد كبير جدًا من علامات التبويب.YMMV.

الصق هذا الرمز في فئة النموذج الخاص بك:

protected override CreateParams CreateParams {
    get {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;    // Turn on WS_EX_COMPOSITED
        return cp;
    } 
}

الفرق الكبير بين هذه التقنية ودعم التخزين المؤقت المزدوج لـ Winform هو أن إصدار Winform يعمل فقط على عنصر تحكم واحد في كل مرة.ستظل ترى كل تحكم فردي يرسم نفسه.والذي يمكن أن يبدو كتأثير وميض أيضًا، خاصة إذا كان مستطيل التحكم غير المطلي يتناقض بشكل سيئ مع خلفية النافذة.

System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
    .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);

إيان لديه المزيد من المعلومات حول استخدام هذا على خادم طرفي.

public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}

تتمثل إحدى الطرق في توسيع عنصر التحكم المحدد الذي تريد مضاعفة المخزن المؤقت فيه وتعيين خاصية DoubleBuffered داخل أداة التحكم الخاصة بعنصر التحكم.

على سبيل المثال:

class Foo : Panel
{
    public Foo() { DoubleBuffered = true; }
}

com.nobugz حصل على الفضل في الطريقة الموجودة في الرابط الخاص به، وأنا أعيد النشر فقط.أضف هذا التجاوز إلى النموذج:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

كان هذا أفضل بالنسبة لي، ففي نظام التشغيل Windows 7 كنت أتلقى كتلًا سوداء كبيرة تظهر عندما أقوم بتغيير حجم نموذج التحكم الثقيل.التحكم الآن يرتد بدلاً من ذلك!ولكن هذا أفضل.

طريقة التمديد لتشغيل التخزين المؤقت المزدوج أو إيقاف تشغيله لعناصر التحكم

public static class ControlExtentions
{
    /// <summary>
    /// Turn on or off control double buffering (Dirty hack!)
    /// </summary>
    /// <param name="control">Control to operate</param>
    /// <param name="setting">true to turn on double buffering</param>
    public static void MakeDoubleBuffered(this Control control, bool setting)
    {
        Type controlType = control.GetType();
        PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(control, setting, null);
    }
}

الاستخدام (على سبيل المثال كيفية إنشاء DataGridView DoubleBuffered):

DataGridView _grid = new DataGridView();
//  ...
_grid.MakeDoubleBuffered(true);

قبل تجربة التخزين المؤقت المزدوج، تأكد مما إذا كان SuspendLayout()/ResumeLayout() قد حل مشكلتك.

وهذا سبب لي أ كثير من الحزن لمدة يومين مع سيطرة طرف ثالث حتى تعقبته.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

لقد واجهت مؤخرًا الكثير من الثغرات (الفضلات) عند إعادة تغيير حجم/إعادة رسم عنصر تحكم يحتوي على العديد من عناصر التحكم الأخرى.

لقد جربت WS_EX_COMPOSITED وWM_SETREDRAW ولكن لم ينجح شيء حتى استخدمت هذا:

private void myPanel_SizeChanged(object sender, EventArgs e)
{
     Application.DoEvents();
}

أردت فقط أن أنقلها.

نسخة vb.net من هذا الحل الجيد ....:

Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Dim cp As CreateParams = MyBase.CreateParams
        cp.ExStyle = cp.ExStyle Or &H2000000
        Return cp
    End Get
End Property

يمكنك أيضًا وراثة عناصر التحكم في فئاتك الخاصة، وتعيين الخاصية هناك.تعد هذه الطريقة رائعة أيضًا إذا كنت تميل إلى القيام بالكثير من الإعدادات المتماثلة في جميع عناصر التحكم.

لقد وجدت أن تعيين إعداد DoubleBuffered في النموذج يقوم تلقائيًا بتعيين كافة الخصائص المدرجة هنا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top