सवाल मेरी दो स्क्रीनों में से एक पर DataGridView का भयानक रेड्रो प्रदर्शन


मैंने वास्तव में इसे हल किया है, लेकिन मैं इसे जन्म के लिए पोस्ट कर रहा हूं।

मैं अपने दोहरी-मॉनीटर सिस्टम पर DataGridView के साथ एक बहुत ही अजीब समस्या में भाग गया। यह मुद्दा खुद को नियंत्रण की बेहद धीमी गति के रूप में प्रकट करता है (एक पूर्ण repaint के लिए 30 सेकंड की तरह), लेकिन केवल जब यह मेरी स्क्रीन में से एक पर है। दूसरी तरफ, पश्चाताप की गति ठीक है।

मेरे पास नवीनतम गैर-बीटा ड्राइवरों (175. कुछ) के साथ एक एनवीडिया 8800 जीटी है। क्या यह एक ड्राइवर बग है? मैं इसे हवा में छोड़ दूंगा, क्योंकि मुझे इस विशेष विन्यास के साथ रहना है। (यह अति कार्ड पर नहीं होता है, हालांकि ...)

पेंट स्पीड के पास सेल सामग्री के साथ कुछ लेना देना नहीं है, और कस्टम ड्राइंग प्रदर्शन में सुधार नहीं करता है - यहां तक ​​कि जब एक ठोस आयताकार चित्रित होता है।

बाद में मुझे पता चला कि फॉर्म पर ElementHost (System.Windows.Forms.Ingrationization नामस्थान से) को समस्या को ठीक करता है। इसे गड़बड़ नहीं करना है; इसे केवल डेटाग्रिड व्यू के रूप में फॉर्म के बच्चे होने की आवश्यकता है। इसे तब तक आकार दिया जा सकता है जब तक कि 0 (0) 0 तक दर्शनीय संपत्ति सच है।

मैं स्पष्ट रूप से अपने आवेदन के लिए .NET 3 / 3.5 निर्भरता को जोड़ना नहीं चाहता; मैं प्रतिबिंब का उपयोग कर रनटाइम (यदि यह कर सकता है) पर इस नियंत्रण को बनाने के लिए एक विधि बनाते हैं। यह काम करता है, और कम से कम यह उन मशीनों पर गर्व से विफल रहता है जिनके पास आवश्यक पुस्तकालय नहीं है - यह धीमा होने के लिए वापस चला जाता है।

यह विधि मुझे ऐप चलने के दौरान भी ठीक करने के लिए लागू करने देती है, जिससे यह देखने में आसान हो जाता है कि मेरे फॉर्म पर डब्ल्यूपीएफ पुस्तकालय क्या बदल रहे हैं (जासूस ++ का उपयोग कर)।

बहुत सारे परीक्षण और त्रुटि के बाद, मैंने देखा कि नियंत्रण पर डबल बफरिंग को सक्षम करना (केवल फॉर्म के विपरीत) इस मुद्दे को सुधारता है!


इसलिए, आपको केवल DataGridView के आधार पर एक कस्टम क्लास बनाने की आवश्यकता है ताकि आप इसकी डबलबफरिंग सक्षम कर सकें। बस!

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

जब तक ग्रिड के मेरे सभी उदाहरण इस कस्टम संस्करण का उपयोग कर रहे हैं, तब तक सब कुछ ठीक है। यदि मैं कभी भी इस स्थिति के कारण एक स्थिति में भाग लेता हूं जहां मैं सबक्लास समाधान का उपयोग नहीं कर पा रहा हूं (यदि मेरे पास कोड नहीं है), तो मुझे लगता है कि मैं उस नियंत्रण को फॉर्म पर इंजेक्ट करने का प्रयास कर सकता हूं :) (हालांकि मैं डबलबफर्ड संपत्ति को बाहर से एक बार फिर निर्भरता से बचने के लिए प्रतिबिंब का उपयोग करने की कोशिश करने की अधिक संभावना रखूंगा)।

यह दुख की बात है कि इस तरह की एक छोटी सी चीज ने मेरे इतने सारे समय खा लिया ...


76
2017-09-23 01:01


मूल


हमारे पास ग्राहकों के साथ एक समान समस्या थी Multimon स्थापित। किसी भी कारण से, जब वे मल्टीमोन बंद करते हैं, तो समस्या दूर हो जाती है। - BlueRaja - Danny Pflughoeft


जवाब:


आपको केवल DataGridView के आधार पर एक कस्टम क्लास बनाने की आवश्यकता है ताकि आप इसकी डबलबफरिंग सक्षम कर सकें। बस!


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

जब तक ग्रिड के मेरे सभी उदाहरण इस कस्टम संस्करण का उपयोग कर रहे हैं, तब तक सब कुछ ठीक है। यदि मैं कभी भी इस स्थिति के कारण एक स्थिति में भाग लेता हूं जहां मैं सबक्लास समाधान का उपयोग नहीं कर पा रहा हूं (यदि मेरे पास कोड नहीं है), तो मुझे लगता है कि मैं उस नियंत्रण को उस फॉर्म पर इंजेक्ट करने का प्रयास कर सकता हूं :) (हालांकि मैं ' डबलबफर्ड संपत्ति को बाहर से एक बार फिर निर्भरता से बचने के लिए मजबूर करने के लिए प्रतिबिंब का उपयोग करने की अधिक संभावना होगी)।

यह दुख की बात है कि इस तरह की एक छोटी सी चीज ने मेरे इतने सारे समय खा लिया ...

नोट: उत्तर को उत्तर देना ताकि प्रश्न को उत्तर के रूप में चिह्नित किया जा सके


60
2017-10-01 19:49



WPF के लिए विंडोज फॉर्म एकीकरण के साथ आप यह कैसे कर सकते हैं ?? - Partial
जवाब के लिए धन्यवाद। आप कभी-कभी सबक्लास समाधान का उपयोग करने में सक्षम नहीं होंगे? (मुझे समझ में नहीं आया "अगर मेरे पास कोड नहीं है" बिट)। - Dan W
बहुत खुबस! मेरी परियोजना में एक आकर्षण की तरह काम करता है जो अजीब मंदी से पीड़ित था और मेज को स्क्रॉल करने पर दोनों (: - knut


यहां कुछ कोड है जो प्रतिबिंब का उपयोग करके संपत्ति को सेट करता है, बेनोइट के सुझाव के अनुसार उप-वर्गीकरण के बिना।

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

58
2018-04-24 18:52



मदद करने में खुशी! मैंने लगभग इसे पोस्ट नहीं किया क्योंकि यह प्रश्न पहले से ही एक वर्ष पुराना था। - Brian Ensink
नीह, यह हमेशा भविष्य में किसी की मदद करेगा, जैसे कि शायद मुझे भी, जो Google से यह धागा मिला है। धन्यवाद! बीटीडब्ल्यू, क्या इसे फॉर्म 1_लोड अनुभाग में रखना बेहतर है? - Dan W
किसी और को देने के लिए जो इसे एक विचार पाता है: यह एक उपयोगी विस्तार विधि है Control कक्षा। public static void ToggleDoubleBuffered(this Control control, bool isDoubleBuffered)। - Anthony


VB.NET में इसे कैसे करना है, यह जानने के लिए, यहां कोड है:

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

13
2018-05-18 15:15





पिछली पोस्ट में जोड़ना, विंडोज फॉर्म अनुप्रयोगों के लिए मैं डेटाग्रिड व्यू घटकों के लिए तेज़ बनाने के लिए उपयोग करता हूं। कक्षा DrawingControl के लिए कोड नीचे है।

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

कन्स्ट्रक्टर में InitializeComponent () के बाद Draw DrawingControl.SetDoubleBuffered (नियंत्रण) पर कॉल करें।

बड़े डेटा अपडेट करने से पहले DrawingControl.SuspendDrawing (नियंत्रण) पर कॉल करें।

बड़े डेटा अपडेट करने के बाद Draw 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();
    }
}

7
2018-04-13 16:45





इसका जवाब भी मेरे लिए काम किया। मैंने सोचा कि मैं एक परिशोधन जोड़ूंगा जो मुझे लगता है कि समाधान को लागू करने वाले किसी के लिए मानक अभ्यास होना चाहिए।

समाधान दूरस्थ डेस्कटॉप के तहत क्लाइंट सत्र के रूप में चलाया जा रहा है, इसके अलावा समाधान अच्छी तरह से काम करता है, खासकर जहां उपलब्ध नेटवर्क बैंडविड्थ कम है। ऐसे मामले में, डबल-बफरिंग के उपयोग से प्रदर्शन खराब हो सकता है। इसलिए, मैं निम्नलिखित पूर्ण उत्तर के रूप में निम्नलिखित का सुझाव देता हूं:

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

अधिक जानकारी के लिए, देखें दूरस्थ डेस्कटॉप कनेक्शन का पता लगाना


6
2017-10-07 20:28





मुझे समस्या का समाधान मिला। उन्नत प्रदर्शन गुणों में समस्या निवारण टैब पर जाएं और हार्डवेयर त्वरण स्लाइडर की जांच करें। जब मुझे आईटी से मेरा नया कंपनी पीसी मिला, तो इसे पूरी तरह से एक टिक पर सेट किया गया था और मुझे डेटाग्रिड्स के साथ कोई समस्या नहीं थी। एक बार जब मैंने वीडियो कार्ड ड्राइवर को अद्यतन किया और इसे पूर्ण करने के लिए सेट किया, तो डेटाग्रिड नियंत्रणों का चित्रण बहुत धीमा हो गया। इसलिए मैंने इसे वापस रीसेट कर दिया जहां समस्या थी और समस्या दूर हो गई।

आशा है कि यह चाल आपके लिए भी काम करेगी।


1
2018-02-26 22:35





बस इस मुद्दे को ठीक करने के लिए हमने जो कुछ किया है उसे जोड़ने के लिए: हमने नवीनतम एनवीडिया ड्राइवरों को अपग्रेड किया समस्या को हल किया। कोई कोड फिर से लिखा जाना था।

पूर्णता के लिए, कार्ड मार्च 2008 (v। 16 9) के ड्राइवरों के साथ एक एनवीडिया क्वाड्रो एनवीएस 2 9 0 था। नवीनतम (v। 182 दिनांकित फरवरी 200 9) में अपग्रेड करने से विशेष रूप से डेटाग्रिड व्यू के लिए मेरे सभी नियंत्रणों के लिए पेंट इवेंट्स में काफी सुधार हुआ।

यह मुद्दा किसी भी अति कार्ड (जहां विकास होता है) पर नहीं देखा गया था।


1
2018-06-10 16:54





श्रेष्ठ!:

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

1
2017-10-07 19:45





हमने दोहरी मॉनिटर सिस्टम पर .NET 3.0 और DataGridView का उपयोग करके एक समान समस्या का अनुभव किया है।

हमारा आवेदन ग्रे ग्रे पृष्ठभूमि के साथ ग्रिड प्रदर्शित करेगा, यह दर्शाता है कि कोशिकाओं को बदला नहीं जा सका। एक "परिवर्तन सेटिंग्स" बटन का चयन करने पर, प्रोग्राम सेल को बदलने के लिए उपयोगकर्ता को इंगित करने के लिए सफेद कोशिकाओं के पृष्ठभूमि रंग को बदल देगा। एक "रद्द करें" बटन उपरोक्त कोशिकाओं के पृष्ठभूमि रंग को भूरे रंग में बदल देगा।

चूंकि पृष्ठभूमि रंग बदल गया है, वहां एक झिलमिलाहट होगी, जो पंक्तियों और स्तंभों की एक ही संख्या के साथ एक डिफ़ॉल्ट आकार के ग्रिड का एक संक्षिप्त प्रभाव होगा। यह समस्या केवल प्राथमिक मॉनिटर (कभी द्वितीयक नहीं) पर होती है और यह एक एकल मॉनीटर सिस्टम पर नहीं होती है।

उपर्युक्त उदाहरण का उपयोग करते हुए नियंत्रण को डबल बफरिंग, हमारी समस्या हल हो गई। हमने आपकी मदद की बहुत सराहना की।


0