C# - 在Parent&之间传递参考。儿童控制

时间:2018-02-14 17:07:39

标签: c# winforms

我创建了一个控件,它将2个控件组合在一起 - combobox和datagridview。我需要在两个类中的许多代码位置都引用它们。我为沟通所做的就是这个

 public class CustomCombobox : ComboBox
 {
      public static CustomCombobox cmb;
      private CustomDataGridView My_DGV = new CustomDataGridView();

   protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
           cmb=this;
        }
}

 public class CustomDataGridView: DataGridView
    {
 protected override void OnCellClick(DataGridViewCellEventArgs e)
        {
            base.OnCellClick(e);

            if (e.RowIndex > -1)
            {
                //Send some text to CustomCombobox
                Sending_text(CustomCombobox.cmb);
            }
        }
}

这只是我所做的一个例子。但是你可以看到我覆盖了两个类中的属性,所以我需要引用两个控件的相同实例。输出控件实际上是一个带有自定义下拉菜单(ToolStripDropDown)的Combobox,它可以工作如果在表单上只添加了一个控件。当我添加第二个时,引用被混淆了 - 文本从一个组合框下拉发送到另一个组合框,而不是发送到相同的组合框。

有人能告诉我以两种方式传递每个控件实例的引用的最简单方法吗?

2 个答案:

答案 0 :(得分:0)

如果组合框将保留在gridview中,您可以将组合框放在自定义gridview类中并在使用之前进行设置。像这样:

public class CustomDataGridView: DataGridView
{
    public CustomCombobox CustomCmb { get;set }

    protected override void OnCellClick(DataGridViewCellEventArgs e)
    {
        base.OnCellClick(e);

        if (e.RowIndex > -1)
        {
            //Send some text to CustomCombobox
            CustomCmb.ReceiveText(text); //Create this method in the custom combobox class, to separate responsibilities.
        }
    }
}

从自定义组合框类中删除静态变量public static CustomCombobox cmb;。因为在这种情况下,将从所有CustomDataGrids访问相同的ComboBox,而不是每个都有一个单独的实例。

答案 1 :(得分:0)

因为您已经编写了数据网格视图来更新最近创建的组合框的文本。你不想那样做。这就是为什么static状态通常应该避免的原因。整个应用程序中没有一个CustomComboBox是您要更新的那个。

您的自定义修改应该反映您正在扩展的控件的行为。也就是说,当您希望父控件能够执行某些操作以响应UI操作时,您将触发一个事件。这就是DataGridView使用CellClick事件所做的事情,因此,如果需要,这就是你的控件应该通过你自己的事件做的事情。

定义事件非常简单,您可以订阅DGV的CellClick并在该处理程序中激活您自己的事件:

public class CustomDataGridView : DataGridView
{
    //TODO come up with meaningful name to represent the action that's taking place, 
    //and to differentiate it from CellClick
    public event Action<string> YourNewEvent;

    public CustomDataGridView()
    {
        CellClick += (sender, args) =>
        {
            if (args.RowIndex >= 1)
            {
                string text = GenerateTextToSendOnClick();
                YourNewEvent?.Invoke(text);
            }
        };
    }

    private string GenerateTextToSendOnClick()
    {
        throw new NotImplementedException();
    }
}

然后,组合框可以自由订阅该事件,并在DGV为其提供文本时执行任何操作:

public class CustomCombobox : ComboBox
{
    private CustomDataGridView dataGridView = new CustomDataGridView();
    public CustomCombobox()
    {
        dataGridView.YourNewEvent += DoStuffWithText;
    }

    private void DoStuffWithText(string text)
    {
        throw new NotImplementedException();
    }
}

请注意,这具有一个重要的优势,即自定义DGV永远不需要知道任何类可能使用它的任何信息。这意味着它可以被ComboBox或可能想要使用它的任何其他类型的自定义控件使用,因为它所做的只是触发一个事件,该控件的任何父级都可以自由使用