用户控制其他开发人员可以向其添加控件并“继承”我控件上所有控件的行为

时间:2014-10-03 12:52:42

标签: c# winforms user-controls drag-and-drop designer

大家好抱歉这个令人困惑的标题......找不到合适的单词了。 出于好奇,我正在玩c#用户控件,我创建了一个从面板构建的控件,一个用作过滤器的文本框,以及一些正在过滤的标签/按钮/等等。 当您更改文本框的文本时,面板上的所有控件都是可见/不可见的,具体取决于它们的Text属性是否包含文本框的Text。非常简单。

但是我希望这个用户控件是这样的,使用它的用户可以删除更多的标签或控件,它们会表现相同,我无法弄清楚如何做到这一点。

当我编辑控件(向其添加控件)时,它按预期工作,并且新控件的行为与没有代码修改的旧控件相同,但仅在我编辑用户控件时而不是在使用它时。

当我将用户控件拖动到表单时,我无法添加控件...当我尝试向控件添加标签时 - 它只是添加到表单而不是控件,因此文本框不影响添加的标签。如果我希望能够将控件添加到表单然后向控件添加一些控件,我该怎么办?

我会很乐意接受一些指示。 这是相关的代码:

private void textBox1_TextChanged(object sender, EventArgs e)
    {
        foreach (Control c in panel1.Controls)
        {
            if (c.Text.Contains(textBox1.Text))
            {
                c.Visible = true;
            }
            else
            {
                c.Visible = false;
            }
        }
    }

编辑 - 添加了图片。

this is the user control

with another bad label

你可以看到

- 我在过滤器文本框中键入1,除了button1之外的所有控件现在都是不可见的 - 当然还有不良行为标签。

谢谢, 吉姆。

2 个答案:

答案 0 :(得分:2)

遵循以下指南可以轻松解决此问题 https://support.microsoft.com/en-us/kb/813450一步一步地描述如何通过使用Visual C#

使UserControl对象充当控件容器设计时间

为了将用户控件修改为设计时控件容器 将以下代码添加到声明部分:

using System.ComponentModel.Design;

将System.ComponentModel.DesignerAttribute属性应用于控件,如下所示:

[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 
public class UserControl1 : System.Windows.Forms.UserControl
{
          ...
}

然后构建解决方案。 控件将像往常一样显示在工具箱中,并可以添加到表单中。可以根据需要将其他控件(如丁酮,文本框等)添加到控件中。

答案 1 :(得分:1)

您描述了我几乎从不使用UserControls的原因之一。任何对原始UC都没有做过的事情必须在代码中完成..

你可以改为使它成为一个不是UserControl的类,即使它成为Panel(或FlowLayoutPanel的简单子类,就像我在这里做的只是为了方便,同时丢弃东西在我的测试期间)。

class FilterPanel : FlowLayoutPanel
{
    TextBox tb_filterBox { get; set; }
    Label st_filterLabel { get; set; }
    public FilterPanel()
    {
        st_filterLabel = new Label();
        st_filterLabel.Text = "Filter:";
        this.Controls.Add(st_filterLabel);
        tb_filterBox = new TextBox();
        this.Controls.Add(tb_filterBox);
        // st_filterLabel.Location = new Point(10, 10);  // not needed for a FLP
        // tb_filterBox.Location = new Point(100, 10);   // use it for a Panel!

        tb_filterBox.TextChanged += tb_filterBox_TextChanged;
    }

    void tb_filterBox_TextChanged(object sender, EventArgs e)
    {
        foreach(Control ctl in this.Controls)
        {
            if (ctl != tb_filterBox && ctl != st_filterLabel)
                ctl.Visible = ctl.Text.Contains(tb_filterBox.Text);
        }
    }
}

现在将其放置在表单(或其他任何内容)之后,您(或任何人)可以在设计器中将Controls放到其上,并且它们将成为其Controls集合的一部分,就像你想要它,并将按预期行事..

关于子类控制的两个注释:

  • 如果您在开发期间破坏了一个,那么使用它的表格也将被破坏,直到您解决问题为止。所以请多加小心!

  • 要让Designer显示Control,它总是需要一个无参数构造函数,如上所示。即使你更愿意提交参数,一个无参数构造函数仍然必须存在,否则设计师就会遇到麻烦!

相关问题