Mapping DataGridView column property in UserControl does not work properly

I put a DataGridView in the UserControl and create a public property in my usercontrol that provides the column property of the datagridview.
Here is a sample code:

 public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } public DataGridViewColumnCollection MyDataGridColumns { get { return dataGridView1.Columns; } } } 

Then I add UserControl1 to my form and click on the MyDataGridColumns property in the properties window and add 1 or more columns. The problem arises when I restore my solution; All columns that I just added disappear after recovery.

Can someone explain to me why this is happening? and how to solve it?

+5
source share
2 answers

This works for me: I created a special column editor, since it seems impossible to use the default column editor for any control that does not extend the 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 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; } } 
+4
source

This is because you did not specify a column type. You must specify the type of column when adding a column (e.g. DataGridViewTextBoxColumn or DataGridViewCheckBoxColumn ). In Form1.cs do the following:

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

Source: https://habr.com/ru/post/1242590/


All Articles