2016-02-09 29 views
5

UserControlDataGridViewを置き、datagridviewのcolumnsプロパティを公開するpublicプロパティをusercontrolに作成します。ここ
はサンプルコードです:UserControlでDataGridViewのcolumnsプロパティを公開しても正しく動作しない

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