【问题标题】:How to add property to existing Winforms control如何将属性添加到现有的 Winforms 控件
【发布时间】:2014-07-14 21:07:54
【问题描述】:

我不确定这是否可能。我做了一些研究,但还没有找到任何结论性的东西。有一个类似的问题here,但它是针对 WPF 的。

我想做的是将自定义属性添加到表单上现有的 WinForms GroupBox(或任何控件)。对于这个例子,我们将使用“链接”。假设我的程序中的每个 GroupBox 都包含一个超链接,然后我在启动程序时需要做的就是这样做:

MyGroupBox.Link = "http:\\www.google.com\"

稍后在我的程序中,我可以将我的超链接内容设置为引用MyGroupBox.Link

是否可以像这样操作 Winforms 控件?如果没有必要,我宁愿不制作自定义控件。

我从this question 看到我可以扩展我的控制权,但在我的特定情况下我会怎么看?和创建自定义控件一样吗?

【问题讨论】:

  • 为什么不直接继承 GroupBox 并添加属性?
  • @Savanna 不幸的是,我不知道该怎么做。你能发布答案吗?
  • WinForms 中的每个控件都有Tag 属性,基本上就是object,所以你可以给它设置任何数据,然后使用它。您可以为其设置任何 url,然后获取它并转换回字符串。
  • @SergeyLitvinov 我知道有一个 Tag 属性,但我不确定这是否有用?如果我没有得到满意的答案,我可能会使用它。
  • 如果您不想使用Tag,那么您必须创建一个派生的自定义控件。有关示例,请参见 msdn.microsoft.com/en-us/library/7h62478z(v=vs.90).aspx

标签: c# .net winforms properties groupbox


【解决方案1】:

一种方法是使用 Extender Providers。它们的作用类似于ToolTip 组件,当它被添加到表单时,它会为该表单上的每个控件提供一个名为ToolTip 的属性。你可以创建这个类:

[ProvideProperty("Link", typeof(Control))]
public class ExtendControls : Component, IExtenderProvider
{
    private Dictionary<Control, string> links =
                               new Dictionary<Control, string>();

    public bool CanExtend(object extendee)
    {
        return !(extendee is Form);
    }

    public void SetLink(Control extendee, string value)
    {
        if (value.Length == 0)
        {
            links.Remove(extendee);
        }
        else
        { 
            links[extendee] = value; 
        }
    }

    [DisplayName("Link")]
    [ExtenderProvidedProperty()]
    public string GetLink(Control extendee)
    {
        if (links.ContainsKey(extendee))
        {
            return links[extendee];
        }
        else
        {
            return string.Empty;
        }
    }
}

它的作用是将Link 属性提供给除窗体之外的所有控件。现在您在您的 Windows 窗体项目中创建这个类并构建它,然后您转到工具箱中的窗体设计器。您应该会看到ExtendControls 组件,将其拖到表单上,它将被放置在组件托盘中。快搞定了……

接下来,您可以使用新的Link 属性,在所需控件的属性窗口中或在类似这样的代码中(假设您将组件保留为其默认名称):

// assuming of course you have a button called button1
// I used button as the example, you can use panel, datagridview, label, etc...
// to set it...
extendControls1.SetLink(button1, "sometest");
// to get it back...
string myLink = extendControls1.GetLink(button1);

【讨论】:

  • 最好也将[DefaultValue("")] 属性添加到GetLink,否则设计器会为每个控件生成带有空字符串的额外SetLink 调用。
【解决方案2】:

我没有用 GroupBox 尝试过这个,但我想你可以用这里的 Button 做一些类似的例子。

http://msdn.microsoft.com/en-us/library/7h62478z(v=vs.90).aspx

只需创建一个新类,将其命名为 MyGroupBox 或任何您想要的名称:

public class MyGroupBox : GroupBox {
    private string link;

    public string Link {get {return link;} set{link=value;} }
}

这继承了 GroupBox 的所有行为/属性,并为链接添加了一个新属性。

那么你可以这样使用它:

MyGroupBox groupBox = new MyGroupBox();
groupBox.Link = "www.google.com";

老实说,我认为这比使用 tag 属性更干净。主要是因为它不是标签,而是链接,我喜欢能够适当地命名属性。 :) 虽然如果您需要为许多控件而不只是 GroupBox 执行此操作,标记可能会更容易。

【讨论】:

  • 感谢您的回答!如果我想将我的 GroupBox 放在设计师那里,我将如何使用它?
  • 我自己没有这样做,但这篇文章似乎解释了如何这样做。 blackwasp.co.uk/VSControlInToolbox.aspx 其实这对我来说也是一个不错的发现,过去我在使用自定义控件时总是停止使用设计器。将控件添加到工具箱似乎真的很容易......很高兴知道。
【解决方案3】:

为了响应 Savanna,您可以使用 Savanna 描述的方法创建扩展类,然后将实际类拖到工具箱中。神奇的是,您将把它放在您的工具箱中,准备好以设计器模式拖到您的表单中,并包含您添加的任何自定义属性。

【讨论】:

    猜你喜欢
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多