在UserControl中公开DataGridView的columns属性不能正常工作 [英] Exposing DataGridView's columns property in UserControl doesn't work properly

查看:38
本文介绍了在UserControl中公开DataGridView的columns属性不能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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属性不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆