2010-08-13 13 views
8

उदाहरण के लिए, मैं एक ब्लू BackgroundColor संपत्ति आदि के साथ एक DataGridView नियंत्रण है .., वहाँ एक रास्ता है जो मैं हस्तांतरण या प्रोग्राम के एक और DataGridView नियंत्रित करने के लिए इन गुणों से पारित सकता है?एक निश्चित नियंत्रण के सभी गुणों की प्रतिलिपि बनाना संभव है? (सी # खिड़की रूपों)

कुछ इस तरह:

dtGrid2.Property = dtGrid1.Property; // but of course, this code is not working 

धन्यवाद ...

उत्तर

4

आप प्रतिबिंब का उपयोग करना होगा। अपने लक्ष्य नियंत्रण करने के लिए कि मान निर्दिष्ट -

आप अपने स्रोत नियंत्रण (अपने प्रकार के आधार पर), तो "मिल" अपने मूल्य की प्रत्येक प्रॉपर्टी के लिए एक संदर्भ हड़पने।

यहाँ एक कच्चे उदाहरण है:

private void copyControl(Control sourceControl, Control targetControl) 
    { 
     // make sure these are the same 
     if (sourceControl.GetType() != targetControl.GetType()) 
     { 
      throw new Exception("Incorrect control types"); 
     } 

     foreach (PropertyInfo sourceProperty in sourceControl.GetType().GetProperties()) 
     { 
      object newValue = sourceProperty.GetValue(sourceControl, null); 

      MethodInfo mi = sourceProperty.GetSetMethod(true); 
      if (mi != null) 
      { 
       sourceProperty.SetValue(targetControl, newValue, null); 
      } 
     } 
    } 
+2

CodeSawyGeek के उत्तर के तहत टिप्पणी पर ध्यान दें - यह कोड अंधेरे से प्रत्येक संपत्ति की प्रतिलिपि बनाता है। खतरनाक हो सकता है। –

+1

एचएम, आप एक सेट विधि की जांच करते हैं लेकिन प्राप्त विधि के लिए नहीं (हालांकि मैं केवल लिखने वाले गुण स्वीकार करता हूं)। लेकिन ध्यान दें कि आपका कोड 'माता-पिता', 'नाम' और 'स्थान' जैसी गुणों की प्रतिलिपि बनाएगा जो वांछित नहीं हो सकते हैं। – Timwi

+0

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

2

आप प्रतिबिंब इस्तेमाल कर सकते हैं प्रकार के सभी सार्वजनिक गुण हो और किसी अन्य के लिए एक उदाहरण से मूल्यों को कॉपी करने के लिए, लेकिन यह खतरनाक है और वास्तव में वस्तु की पूरी स्थिति को डुप्लिकेट नहीं कर सकता है। वहाँ कुछ गुण है कि आप कॉपी नहीं करना चाहते हैं (उदा जनक, साइट), और अन्य महत्वपूर्ण गुण (जैसे कॉलम, पंक्तियां) है कि आप सीधे सेट नहीं कर सकते हो सकता है। इसके अलावा, ऐसे गुण हो सकते हैं जो संदर्भ प्रकार हैं; आपका प्रतिलिपि नियंत्रण उसी ऑब्जेक्ट को आपके मूल के संदर्भ में समाप्त कर देगा, जो अवांछित हो सकता है। राज्य की जानकारी भी हो सकती है जिसे केवल विधि कॉल के माध्यम से सेट किया जा सकता है, जिसे इस तरह से कॉपी नहीं किया जाएगा। संक्षेप में, प्रतिबिंब शायद वह समाधान नहीं है जिसे आप ढूंढ रहे हैं।

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

+1

... लेकिन, आप करने की आवश्यकता है सावधान रहें क्योंकि यदि आप इसे अंधाधुंध करते हैं, तो आप 'माता-पिता', 'नाम' और 'स्थान' जैसी गुणों की प्रतिलिपि बना सकते हैं जिन्हें आप नहीं चाहते हैं। – Timwi

+0

@ तिमवी: मैंने इस तरह के प्रतिबिंब का उपयोग करने के खतरों को इंगित करने के लिए मेरे उत्तर को संशोधित किया। –

+0

+1 फ़ैक्टरी विधि के लिए, हालांकि संभवतः पहले से ही तत्काल नियंत्रण को कॉन्फ़िगर करने की अधिक संभावना होगी, इसलिए वास्तविक कारखाना नहीं, लेकिन एक ही विचार और यह तरीका है कि मैं इसके बारे में सोचूंगा। – andyhasit

0

मैं क्लोन के लिए इस कोड का इस्तेमाल किया नियंत्रण, क्योंकि मैं केवल चयनित गुणों की प्रतिलिपि बनाना चाहता हूं।

public static void CloneControl(Control SourceControl, Control DestinationControl) 
{ 
    String[] PropertiesToClone = new String[] { "Size", "Font", "Text", "Tag", "BackColor", "BorderStyle", "TextAlign", "Width", "Margin" }; 
    PropertyInfo[] controlProperties = SourceControl.GetType().GetProperties(); 

    foreach (String Property in PropertiesToClone) 
    { 
     PropertyInfo ObjPropertyInfo = controlProperties.First(a => a.Name == Property); 
     ObjPropertyInfo.SetValue(DestinationControl, ObjPropertyInfo.GetValue(SourceControl)); 
    } 
} 
1

यहाँ कोड है कि मैं के साथ आया है। मैंने केवल लेबल, टेक्स्टबॉक्स, पैनल, और DataGridView नियंत्रणों के साथ इसका परीक्षण किया है। एक पैनल नियंत्रण के लिए आपको सभी निहित नियंत्रण (क्लोन उदाहरण) मिलेंगे। डेटाग्रिड व्यू नियंत्रण के लिए आपको डेटा बाध्यकारी मिलेगा और यह वही डेटा होगा जो स्रोत डेटाग्रीड व्यू नियंत्रण से जुड़ा हुआ है। बेशक, यदि बाध्यकारी नहीं है तो क्लोन उदाहरण में बाध्यकारी नहीं होगा। चाहे ये व्यवहार वांछनीय हैं या नहीं, आपकी आवश्यकताओं पर निर्भर करता है।

private Control CloneControl(Control srcCtl) 
{ 
    var cloned = Activator.CreateInstance(srcCtl.GetType()) as Control; 
    var binding = BindingFlags.Public | BindingFlags.Instance; 
    foreach(PropertyInfo prop in srcCtl.GetType().GetProperties(binding)) 
    { 
     if (IsClonable(prop)) 
     { 
      object val = prop.GetValue(srcCtl); 
      prop.SetValue(cloned, val, null); 
     } 
    } 

    foreach(Control ctl in srcCtl.Controls) 
    { 
     cloned.Controls.Add(CloneControl(ctl)); 
    } 

    return cloned; 
} 

private bool IsClonable(PropertyInfo prop) 
{ 
    var browsableAttr = prop.GetCustomAttribute(typeof(BrowsableAttribute), true) as BrowsableAttribute; 
    var editorBrowsableAttr = prop.GetCustomAttribute(typeof(EditorBrowsableAttribute), true) as EditorBrowsableAttribute; 

    return prop.CanWrite 
     && (browsableAttr == null || browsableAttr.Browsable == true) 
     && (editorBrowsableAttr == null || editorBrowsableAttr.State != EditorBrowsableState.Advanced); 
} 
+0

'System.ComponentModel.DefaultValueAttribute' और' System.ComponentModel.CategoryAttribute' जांचने के लिए 2 अन्य हैं; यदि वे मौजूद हैं, तो संपत्ति डिजाइनर में दिखने के लिए है। डीजीवी के कई गुणों में ब्राउज़ करने योग्य या संपादक ब्राउज़ करने योग्य नहीं हैं, लेकिन इनमें से एक या दोनों हैं, उदा। 'AllowUserTo *' गुण। –

0

this post यहाँ के आधार पर कि

  • सही नियंत्रण प्रकार बनाता है और

public static class ControlExtensions 
{ 
    public static T Clone<T>(this T controlToClone) where T : Control 
    { 
     PropertyInfo[] controlProperties = 
      typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     //T instance = Activator.CreateInstance<T>(); 
     Control instance = (Control) Activator.CreateInstance(controlToClone.GetType()); 

     foreach (PropertyInfo propInfo in controlProperties) 
     { 
      if (propInfo.CanWrite) 
      { 
       if (propInfo.Name != "WindowTarget") 
        propInfo.SetValue(instance, 
             propInfo.GetValue(controlToClone, null), null); 
      } 
     } 

     foreach(Control ctl in controlToClone.Controls) 
     { 
      instance.Controls.Add(ctl.Clone()); 
     } 
     return (T) instance; 
    } 
} 

तुम अब भी चाहते हो सकता है के लिए इतना रिकर्सिवली करता है एक संस्करण है वें से अधिक अगर परीक्षण करें ई WindowTarget संपत्ति फ़िल्टर किया जाना चाहिए ..

अजीब बात है एक तरफ: क्लोन करने के लिए नियंत्रण (पर) है, तो एक नहीं चुना जाताTabPage यह अदृश्य हो जाएगा ..

0

मैं इस प्रयोग किया है:

Control NewControl=new Control(ControlToClone,ControlToClone.Name); 
+0

क्लाउड आप अपने समाधान को थोड़ा सा समझाते हैं। यह ठीक दिखता है लेकिन आगे स्पष्टीकरण के बिना कम गुणवत्ता के कारण उत्तर हटाया जा सकता है। जवाब देने के लिए साथी आगंतुकों की सहायता करें और इसका उपयोग करने के कारण प्रदान करें। –

संबंधित मुद्दे