2008-09-16 15 views

उत्तर

81

यहां Dummy's solution का एक और सामान्य संस्करण है।

हम संरक्षित DoubleBuffered संपत्ति पर जाने के लिए प्रतिबिंब का उपयोग कर सकते हैं, और फिर इसे सत्य पर सेट किया जा सकता है।

नोट: आप pay your developer taxes और नहीं use double-buffering if the user is running in a terminal services session (जैसे दूरस्थ डेस्कटॉप) यह सहायक विधि अगर व्यक्ति दूरस्थ डेस्कटॉप में चल रहा है डबल बफरिंग चालू नहीं हो रहा चाहिए।

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); 
} 
+0

इस कोड ने बिना किसी संशोधन के मेरी समस्या हल की। धन्यवाद! – Mykroft

+0

मजेदार, मुझे लगता है कि रिमोटिंग के दौरान डबल-बफर के लिए और भी महत्वपूर्ण है, ताकि आप तार पर पश्चातापों का एक गुच्छा भेजना न पड़े? –

+11

यह वही है जो आप नहीं चाहते हैं। टर्मिनल सत्र में जीडीआई सिस्टम कमांड भेज सकता है (यहां ड्रॉ लाइन, ड्रिल सर्कल, यहां भरें, इत्यादि)। डबल बफरिंग आपके द्वारा बिटमैप पर हर चीज ड्राइंग करके और फिर अपने पूरे फॉर्म को बिटमैप के रूप में पेंट करने के लिए जीडीआई का उपयोग करके पूरा किया जाता है। तार पर एक असम्पीडित बिटमैप भेजना * मूल * जीडीआई कमांड भेजने से धीमा * धीमा है। –

10
public void EnableDoubleBuffering() 
{ 
    this.SetStyle(ControlStyles.DoubleBuffer | 
     ControlStyles.UserPaint | 
     ControlStyles.AllPaintingInWmPaint, 
     true); 
    this.UpdateStyles(); 
} 
18
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control) 
    .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | 
    System.Reflection.BindingFlags.Instance); 
aProp.SetValue(ListView1, true, null); 

Ian एक टर्मिनल सर्वर पर इस प्रयोग के बारे में कुछ और जानकारी है।

+0

यह काम कर देता है। मैंने इसे एक सामान्य सहायक समारोह बनाया और इसे यहां पोस्ट किया। –

+0

यह वास्तव में * टर्मिनल सर्वर पर नहीं है, क्योंकि मेरे कोई भी ग्राहक दूरस्थ डेस्कटॉप सत्र से सॉफ़्टवेयर चलाता है। लेकिन आपको अपने डेवलपर करों का भुगतान करना चाहिए, और मैं उस कोड को नहीं रखना चाहता था जिसमें करों को पहले से शामिल नहीं किया गया था। –

1

आप अपने स्वयं के वर्गों में नियंत्रण भी प्राप्त कर सकते हैं, और वहां संपत्ति सेट कर सकते हैं। यह विधि भी अच्छी है यदि आप बहुत सारे सेट अप कर रहे हैं जो सभी नियंत्रणों पर समान है।

8

एक तरीका है कि आप उस विशिष्ट नियंत्रण को विस्तारित करना चाहते हैं जिसे आप डबल बफर करना चाहते हैं और डबलबफरर्ड प्रॉपर्टी को नियंत्रण के सीटीआर के अंदर सेट करना है।

उदाहरण के लिए:

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

मैं एक व्युत्पन्न कक्षा में एक सूची खींचे ListView के साथ काम कर रहा हूँ। इसने पूरी तरह से समस्या हल की! –

+0

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

4

इससे पहले कि आप डबल बफरिंग की कोशिश, अगर SuspendLayout()/ResumeLayout() अपनी समस्या को हल देखते हैं।

+3

सस्पेंड/रेज़्यूमेलाइट पेंटिंग करते समय झिलमिलाहट की समस्या का समाधान नहीं करता है। –

0

मुझे पता चला है कि फॉर्म पर डबलबफर्ड सेटिंग सेट करने से स्वचालित रूप से यहां सूचीबद्ध सभी गुणों को सेट किया जाता है।

हालांकि; मुझे Winforms द्वारा प्रदान किए गए डबल बफरिंग को बहुत कम से कम पाया गया है। This little gem of a code snippetवास्तव में एक फर्क पड़ता है, गंभीरता से इसे आजमाएं। मैं एक लंबे समय खर्च एक समाधान है कि काम किया और अंत में है कि :-)

+0

लिंक मर चुका है ... –

+0

हाँ मुझे पता है ... मैंने वह कोड खो दिया है और इसे t'internet पर कहीं और नहीं ढूंढ पाया है ... क्षमा करें! – ljs

54

चेक this thread

है कि इसका जवाब के मूल दोहरा पाया, तो आप प्राप्त करने के लिए खिड़की पर WS_EX_COMPOSITED शैली झंडा चालू कर सकते हैं की तलाश में फॉर्म और उसके सभी नियंत्रण डबल-बफर किए गए हैं। स्टाइल ध्वज XP के बाद उपलब्ध है। यह चित्रकला को तेज़ी से नहीं बनाता है लेकिन पूरी खिड़की को ऑफ-स्क्रीन बफर में खींचा जाता है और स्क्रीन पर एक व्हेक में लगाया जाता है। इसे चित्रकारी कलाकृतियों के बिना उपयोगकर्ता की आंखों के लिए तत्काल दिखाना। यह पूरी तरह मुसीबत रहित नहीं है, कुछ दृश्य शैलियों रेंडरर उस पर गड़बड़ कर सकते हैं, खासकर टैबकंट्रोल जब उसके बहुत सारे टैब होते हैं। YMMV।

पेस्ट अपने प्रपत्र वर्ग में यह कोड:

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

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

+0

वाह ... रात और दिन के बारे में बात करें; इस विधि का उपयोग कर मेरे लिए बड़ा अंतर। –

+1

404-ईडी। –

+4

+1 ओएमजी। संयुक्त राष्ट्र के हो-freakin-lievable। मैंने यहां वर्णित हर दूसरे समाधान की कोशिश की, और मैं अभी भी मोर्स कोड की तरह झटकेदार था। यहां वर्णित सरल काले जादू का पालन किया, और स्क्रीन पर एक ब्लिप नारा। धन्यवाद! –

5

nobugz अपने लिंक में विधि के लिए क्रेडिट प्राप्त करता है, मैं बस दोबारा पोस्ट कर रहा हूं। फार्म को यह ओवरराइड करें:

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

यह मेरे लिए सबसे अच्छा काम किया, विंडोज 7 पर मैं बड़े काले ब्लॉक प्रदर्शित होने जब मैं एक नियंत्रण भारी प्रपत्र का आकार परिवर्तन हो रही थी। नियंत्रण अब इसके बजाय उछाल! लेकिन यह बेहतर है।

+0

यह @ हंस पासेंट के उत्तर जैसा ही है, लेकिन यहां कोड डालने के लिए +1 है। –

+6

मैं nobugz हूँ, निक मैं एमएसडीएन मंचों पर वापस इस्तेमाल किया। –

4

एक्सटेंशन विधि नियंत्रण के लिए चालू या बंद डबल बफरिंग चालू करने के लिए

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); 
4

यह मैं की एक बहुत वजह से जब तक मैंने इसे ट्रैक नहीं किया, तब तक तीसरे पक्ष के नियंत्रण के साथ दो दिनों के लिए दुःख।

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

मैं हाल ही में छेद (गोबर) का एक बहुत था जब फिर से आकार/कई अन्य नियंत्रण युक्त नियंत्रण redrawing।

मैं WS_EX_COMPOSITED और WM_SETREDRAW कोशिश की, लेकिन कुछ भी नहीं काम किया जब तक मैं इस प्रयोग किया है:

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

बस चाहता था उस पर पारित करने के लिए। इस ठीक समाधान के

0

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