我在DataGridView
中添加UserControl
并在我的usercontrol中创建一个公共属性,公开datagridview的columns属性。
以下是示例代码:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public DataGridViewColumnCollection MyDataGridColumns
{
get
{
return dataGridView1.Columns;
}
}
}
然后我在表单中添加UserControl1
,然后在属性窗口中单击MyDataGridColumns
属性并添加1个或更多列。 当我重建我的解决方案时会出现问题;我重新添加的所有列都会在重建后消失。
任何人都可以向我解释为什么会这样吗?以及如何解决?
答案 0 :(得分:5)
这对我有用:我创建了一个特定的列编辑器,因为对于任何不扩展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;
}
}
答案 1 :(得分: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);
}