2016-02-09 10 views
5

मैंने को UserControl में रखा है और मेरे उपयोगकर्ता नियंत्रण में सार्वजनिक संपत्ति बनायी है जो डेटाग्रिडव्यू के कॉलम प्रॉपर्टी का खुलासा करती है।UserControl में DataGridView की कॉलम प्रॉपर्टी का खुलासा ठीक से काम नहीं करता

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    public DataGridViewColumnCollection MyDataGridColumns 
    { 
     get 
     { 
      return dataGridView1.Columns; 
     } 
    } 
} 

तब मैं अपने रूप में UserControl1 जोड़ सकते हैं और मैं संपत्ति विंडो में MyDataGridColumns संपत्ति पर क्लिक करें और 1 या अधिक स्तंभ जोड़ने:
यहाँ नमूना कोड है। समस्या तब होती है जब मैं अपने समाधान का पुनर्निर्माण करता हूं; पुनर्निर्माण के बाद जो कॉलम मैंने अभी जोड़े हैं, वे गायब हो गए हैं।

क्या कोई मुझे बता सकता है कि ऐसा क्यों होता है? और इसे कैसे हल करें?

+0

आप कॉलम कैसे जोड़ रहे हैं? डिजाइन मोड या प्रोग्रामेटिक रूप से? –

+0

डिज़ाइन मोड में। –

+0

अपनी संपत्ति 'MyDataGridColumns' में एक सेटटर जोड़ने का प्रयास करें। – Bioukh

उत्तर

4

यह मेरे लिए काम करता है: मैंने एक विशिष्ट कॉलम संपादक बनाया है क्योंकि ऐसा लगता है कि किसी भी नियंत्रण के लिए डिफ़ॉल्ट कॉलम संपादक का उपयोग करना असंभव है जो DataGridView का विस्तार नहीं करता है।

public partial class UserControl1 : UserControl, IDataGridView 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    [Browsable(false)] 
    public DataGridView DataGridView 
    { 
     get { return dataGridView1; } 
    } 

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    [Editor(typeof(ExtendedDataGridViewColumnCollectionEditor), typeof(UITypeEditor))] 
    [MergableProperty(false)] 
    public DataGridViewColumnCollection MyDataGridColumns 
    { 
     get { return dataGridView1.Columns; } 
    } 

} 

public interface IDataGridView 
{ 
    DataGridView DataGridView { get; } 
} 

class ExtendedDataGridViewColumnCollectionEditor : UITypeEditor 
{ 
    private Form dataGridViewColumnCollectionDialog; 

    private ExtendedDataGridViewColumnCollectionEditor() { } 

    private static Form CreateColumnCollectionDialog(IServiceProvider provider) 
    { 
     var assembly = Assembly.Load(typeof(ControlDesigner).Assembly.ToString()); 
     var type = assembly.GetType("System.Windows.Forms.Design.DataGridViewColumnCollectionDialog"); 

     var ctr = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0]; 
     return (Form)ctr.Invoke(new object[] { provider }); 
    } 

    public static void SetLiveDataGridView(Form form, DataGridView grid) 
    { 
     var mi = form.GetType().GetMethod("SetLiveDataGridView", BindingFlags.NonPublic | BindingFlags.Instance); 
     mi.Invoke(form, new object[] { grid }); 
    } 

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) 
    { 
     if (provider != null && context != null) 
     { 
      var service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); 
      if (service == null || context.Instance == null) 
       return value; 

      var host = (IDesignerHost)provider.GetService(typeof(IDesignerHost)); 
      if (host == null) 
       return value; 

      if (dataGridViewColumnCollectionDialog == null) 
       dataGridViewColumnCollectionDialog = CreateColumnCollectionDialog(provider); 

      //Unfortunately we had to make property which returns inner datagridview 
      //to access it here because we need to pass DataGridView into SetLiveDataGridView() method 
      var grid = ((IDataGridView)context.Instance).DataGridView; 
      //we have to set Site property because it will be accessed inside SetLiveDataGridView() method 
      //and by default it's usually null, so if we do not set it here, we will get exception inside SetLiveDataGridView() 
      var oldSite = grid.Site; 
      grid.Site = ((UserControl)context.Instance).Site; 
      //execute SetLiveDataGridView() via reflection 
      SetLiveDataGridView(dataGridViewColumnCollectionDialog, grid); 

      using (var transaction = host.CreateTransaction("DataGridViewColumnCollectionTransaction")) 
      { 
       if (service.ShowDialog(dataGridViewColumnCollectionDialog) == DialogResult.OK) 
        transaction.Commit(); 
       else 
        transaction.Cancel(); 
      } 
      //we need to set Site property back to the previous value to prevent problems with serializing our control 
      grid.Site = oldSite; 
     } 

     return value; 
    } 

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
     return UITypeEditorEditStyle.Modal; 
    } 
} 
2

ऐसा इसलिए है क्योंकि आपने कॉलम के प्रकार को निर्दिष्ट नहीं किया है। कॉलम जोड़ने पर आपको कॉलम का प्रकार देना चाहिए (उदाहरण के लिए DataGridViewTextBoxColumn या DataGridViewCheckBoxColumn)। आपके Form1.cs में निम्न कार्य करें:

public Form1() 
{ 
    InitializeComponent(); 
    DataGridViewColumn dgViewColumn = new DataGridViewTextBoxColumn();//Or DataGridViewCheckBoxColumn 
    dgViewColumn.DataPropertyName = "dgViewColumn"; 
    dgViewColumn.HeaderText = @"dgViewColumn"; 
    dgViewColumn.Name = "dgViewColumn"; 
    userControl11.MyDataGridColumns.Add(dgViewColumn); 
} 
+2

@Afshin Aghazadeh, आप डिजाइनर का उपयोग करने पर जोर क्यों देते हैं? कोड डिजाइनर की तुलना में अधिक नियंत्रण प्रदान करता है। – Oceans

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