问题描述
我在 UserControl
中放入了 DataGridView
,并在用户控件中创建了一个公共属性,该属性公开了datagridview的columns属性.
这是示例代码:
I put a DataGridView
in a UserControl
and create a public property in my usercontrol that exposes datagridview's columns property.
Here is the sample code:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public DataGridViewColumnCollection MyDataGridColumns
{
get
{
return dataGridView1.Columns;
}
}
}
然后,在表单中添加 UserControl1
,然后在属性窗口中单击 MyDataGridColumns
属性,然后添加1个或更多列.当我重建解决方案时会发生问题;重建后,我刚刚添加的所有列都消失了.
Then I add UserControl1
in my form and I click on MyDataGridColumns
property in property window and add 1 or more columns. The problem happens when I rebuild my solution; All of the columns that I have just added disappear after rebuilding.
有人可以向我解释为什么会这样吗?以及如何解决?
Can anyone explain to me why this happens? and how to solve it?
推荐答案
这对我有用:我创建了一个特定的列编辑器,因为似乎无法对不扩展任何控件的默认控件使用默认列编辑器DataGridView
.
This works for me : I created a specific columns editor as it seems it is impossible to use the default columns editor for any control that does not extend 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;
}
}
这篇关于在UserControl中公开DataGridView的columns属性不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!