سؤال

في الواقع لقد حل هذا, ولكن أنا نشر هذا للأجيال القادمة.

ركضت إلى قضية غريبة مع DataGridView على ثنائي-نظام مراقبة.المسألة يتجلى بطيئة للغاية رسم عنصر التحكم (مثل 30 ثانية كاملة رسم) ، ولكن فقط عندما يكون على أحد الشاشات.عندما جهة أخرى ، فإن إعادة رسم السرعة على ما يرام.

لدي Nvidia 8800 GT مع أحدث غير برامج بيتا (175.شيء).هو سائق علة ؟ سأترك هذا في الهواء ، حيث يجب أن يعيش مع هذا التكوين.(فإنه لا يحصل على بطاقات ATI ، على الرغم من...)

الطلاء السرعة لا علاقة له مع محتويات الخلية ، والعرف الرسم لا تحسين الأداء في كل شيء - حتى عندما فقط اللوحة الصلبة المستطيل.

لقد وجدت في وقت لاحق إلى أن وضع ElementHost (من النظام.يقوم نظام ويندوز.أشكال.التكامل مساحة) على شكل بتصحيح المشكلة.فإنه لا يجب أن يكون عابث ؛ فإنه يحتاج فقط إلى أن يكون الطفل من شكل DataGridView أيضا.يمكن تغيير حجمها إلى (0, 0) طالما مرئية الملكية الحقيقية.

أنا لا أريد صراحة إضافة .صافي 3/3.5 التبعية إلى التطبيق ؛ لقد جعل طريقة لخلق هذه السيطرة في وقت التشغيل (إذا كان يمكن) باستخدام التفكير.يعمل, على الأقل فشل بأمان على الأجهزة التي لا تحتوي المطلوبة المكتبة - فقط يعود إلى كونها بطيئة.

هذا الأسلوب أيضا يتيح لي تطبيق لإصلاح أثناء تشغيل التطبيق ، مما يجعل من السهل أن نرى ما WPF المكتبات تغيير على شكل (باستخدام Spy++).

بعد الكثير من التجربة والخطأ ، لاحظت أن تمكين التخزين المؤقت المزدوج على التحكم في نفسه (بدلا من مجرد شكل) بتصحيح المشكلة!


لذا تحتاج فقط إلى جعل فئة مخصصة على الخروج من DataGridView لذلك يمكنك تمكين DoubleBuffering.هذا هو!

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    }
}

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

ومن المحزن أن مثل هذا مسلي شيء بسيط أكلت الكثير من وقتي...

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

المحلول

تحتاج فقط إلى جعل فئة مخصصة على الخروج من DataGridView لذلك يمكنك تمكين DoubleBuffering.هذا هو!


class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    } 
}

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

ومن المحزن أن مثل هذا مسلي شيء بسيط أكلت الكثير من وقتي...

ملاحظة:مما يجعل الإجابة إجابة السؤال يمكن أن تكون علامة الإجابة

نصائح أخرى

هنا بعض التعليمات البرمجية التي تحدد المنشأة باستخدام التفكير ، دون subclassing كما بينوا يوحي.

typeof(DataGridView).InvokeMember(
   "DoubleBuffered", 
   BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
   null, 
   myDataGridViewObject, 
   new object[] { true });

للبحث عن كيفية القيام بذلك في VB.NET هنا هو رمز:

DataGridView1.GetType.InvokeMember("DoubleBuffered", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.SetProperty, Nothing, DataGridView1, New Object() {True})

إضافة إلى المشاركات السابقة, ويندوز أشكال تطبيقات هذا هو ما يمكنني استخدام DataGridView المكونات لجعلها سريعة.رمز الطبقة DrawingControl أدناه.

DrawingControl.SetDoubleBuffered(control)
DrawingControl.SuspendDrawing(control)
DrawingControl.ResumeDrawing(control)

دعوة DrawingControl.SetDoubleBuffered(التحكم) بعد InitializeComponent() في منشئ.

دعوة DrawingControl.SuspendDrawing(التحكم) قبل القيام البيانات الكبيرة التحديثات.

دعوة DrawingControl.ResumeDrawing(التحكم) بعد القيام البيانات الكبيرة التحديثات.

هذه الأخيرة 2 أفضل القيام به مع محاولة/أخيرا كتلة.(أو حتى أفضل كتابة الفئة IDisposable و الاتصال SuspendDrawing() في منشئ ، ResumeDrawing() في Dispose().)

using System.Runtime.InteropServices;

public static class DrawingControl
{
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

    private const int WM_SETREDRAW = 11;

    /// <summary>
    /// Some controls, such as the DataGridView, do not allow setting the DoubleBuffered property.
    /// It is set as a protected property. This method is a work-around to allow setting it.
    /// Call this in the constructor just after InitializeComponent().
    /// </summary>
    /// <param name="control">The Control on which to set DoubleBuffered to true.</param>
    public static void SetDoubleBuffered(Control control)
    {
        // if not remote desktop session then enable double-buffering optimization
        if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
        {

            // set instance non-public property with name "DoubleBuffered" to true
            typeof(Control).InvokeMember("DoubleBuffered",
                                         System.Reflection.BindingFlags.SetProperty |
                                            System.Reflection.BindingFlags.Instance |
                                            System.Reflection.BindingFlags.NonPublic,
                                         null,
                                         control,
                                         new object[] { true });
        }
    }

    /// <summary>
    /// Suspend drawing updates for the specified control. After the control has been updated
    /// call DrawingControl.ResumeDrawing(Control control).
    /// </summary>
    /// <param name="control">The control to suspend draw updates on.</param>
    public static void SuspendDrawing(Control control)
    {
        SendMessage(control.Handle, WM_SETREDRAW, false, 0);
    }

    /// <summary>
    /// Resume drawing updates for the specified control.
    /// </summary>
    /// <param name="control">The control to resume draw updates on.</param>
    public static void ResumeDrawing(Control control)
    {
        SendMessage(control.Handle, WM_SETREDRAW, true, 0);
        control.Refresh();
    }
}

الجواب على هذا عملت بالنسبة لي أيضا.فكرت في إضافة الصقل التي أعتقد أنه يجب أن يكون مستوى ممارسة لأي شخص تنفيذ الحل.

الحل يعمل بشكل جيد إلا عندما واجهة المستخدم يتم تشغيل العميل الدورة في إطار "سطح المكتب البعيد" ، وخاصة من حيث النطاق الترددي لشبكة الاتصال المتوفرة منخفضة.في مثل هذه الحالة ، يمكن أن يكون الأداء سوءا بسبب استخدام التخزين المؤقت المزدوج.ولذلك أقترح ما يلي: أكثر إجابة كاملة:

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        // if not remote desktop session then enable double-buffering optimization
        if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
            DoubleBuffered = true;
    } 
}

للحصول على مزيد من التفاصيل ، يرجى الرجوع إلى الكشف عن اتصال سطح المكتب البعيد

لقد وجدت حلا لهذه المشكلة.انتقل إلى علامة التبويب استكشاف الأخطاء وإصلاحها المتقدمة خصائص العرض والتحقق من مربع التمرير تسريع الأجهزة.عندما حصلت الشركة الجديدة PC من ذلك ، كان من المقرر أن علامة واحدة من الكامل لم يكن لدي أي مشاكل مع datagrids.مرة واحدة لقد قمت بتحديث برنامج تشغيل بطاقة الفيديو و مجموعة كاملة, لوحة تحكم datagrid أصبحت بطيئة جدا.لذلك أنا إعادة تعيين مرة أخرى إلى حيث كانت المشكلة ذهبت بعيدا.

نأمل أن تكون هذه الخدعة تعمل بالنسبة لك أيضا.

فقط لإضافة ما فعلناه لإصلاح هذه المشكلة:نحن ترقية إلى أحدث برامج تشغيل Nvidia حل المشكلة.أي أن إعادة كتابة.

للتأكد من اكتمالها ، بطاقة Nvidia Quadro NVS 290 مع السائقين مؤرخة في آذار / مارس 2008 (v.169).الترقية إلى أحدث (v.182 بتاريخ فبراير 2009) تحسنت بشكل ملحوظ الطلاء الأحداث كل الضوابط ، خاصة بالنسبة DataGridView.

هذه المسألة لا ينظر إليه على أي بطاقات ATI (حيث تحدث التنمية).

أفضل!:

Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" _
  (ByVal hWnd As Integer, ByVal wMsg As Integer, _
  ByVal wParam As Integer, ByRef lParam As Object) _
  As Integer

Const WM_SETREDRAW As Integer = &HB

Public Sub SuspendControl(this As Control)
    SendMessage(this.Handle, WM_SETREDRAW, 0, 0)
End Sub

Public Sub ResumeControl(this As Control)
    RedrawControl(this, True)
End Sub

Public Sub RedrawControl(this As Control, refresh As Boolean)
    SendMessage(this.Handle, WM_SETREDRAW, 1, 0)
    If refresh Then
        this.Refresh()
    End If
End Sub

لقد عانينا من مشكلة مماثلة باستخدام .NET 3.0 و DataGridView على شاشة مزدوج النظام.

لدينا التطبيق عرض الشبكة مع خلفية رمادية ، مشيرا إلى أن الخلايا لا يمكن تغييرها.عند اختيار "تغيير إعدادات" الزر, برنامج تغيير لون خلفية الخلايا البيضاء للإشارة إلى المستخدم الذي الخلية النص يمكن أن تتغير.و "إلغاء" الزر تغيير لون الخلفية المذكورة الخلايا مرة أخرى إلى اللون الرمادي.

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

التخزين المؤقت المزدوج التحكم باستخدام المثال أعلاه ، حللنا المشكلة.ونحن نقدر مساعدتكم.

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