C#在设计器中显示可浏览的子属性

时间:2009-11-13 11:41:31

标签: c# properties designer children componentmodel

我正在使用带有标准WinForms的.NET C#,而不是WPF。

我有这种情况。 我正在创建一个月份日历的用户控件,类似于.NET日历,但具有更多功能。 我有一个用户控件表单,填充表示日期的按钮对象。 按钮可以根据其状态(选中,鼠标悬停,周末......)以不同颜色着色

我希望它的工作方式是扩展按钮类以接受确定颜色的状态,而不是从父(用户控件)类中着色它们。目前有10种颜色,我真的不想用着色条件弄乱用户控制代码。

此外,我想在设计时选择所有颜色,使用可浏览的设计师属性。 问题是设计器只显示在用户控件类中定义的属性,而不显示其子项(按钮)。

此问题有解决方法吗? 所以简而言之,我想使用内部按钮属性更改颜色,并且能够在设计时使用设计器属性选择它们,而不是手动硬编码。

4 个答案:

答案 0 :(得分:5)

好的,我会尝试解释一下代码:

例如,我有一个用户控件和一个按钮类。 我想公开Button属性,并使它们在设计器中的MyControl属性中可见。

class MyControl : UserControl
{
     private MyButton button;
     button.ChangeStyle("Selected");
}

class MyButton : Button
{
     private Color buttonColor;

     public void ChangeStyle(string styleName)
     {
          if (styleName == "Selected")
              this.BackColor = buttonColor;
     }

     [Browsable(true)]
     [Category("Button style")]
     public Color ButtonColor
     {
          get { return buttonColor; }
          set { buttonColor = value; }
     }
}

这是一个简单的例子。通常我有5种不同的风格,包括每种风格的背景和前景色。因此,我不想在MyControl类中管理颜色,而是想在MyButton类中定义它们。但问题是,MyButton类中的属性在设计器中不可见,因为它只关注MyControl属性。

顺便说一下。忽略代码示例中缺少的构造函数和其他基本类的东西

我无法使用:

[Category("Wonder Control")]
public Color ButtonBackColor { get { return button.BackColor; } set { button.BackColor = value; }

因为我在MyControl中有30个按钮(几个月),我不能只引用一个对象。

答案 1 :(得分:2)

对于在设计器中可见的属性,它们必须是带有getter和setter的公共属性 - 从你所说的,属性只是getter。您还可以尝试在属性上指定BrowsableAttributeBindableAttribute来强制设计师显示它们......

答案 2 :(得分:1)

你可以在这里做各种各样的事情 - 你可以(虽然这是一个错误的答案)在公共界面上公开有问题的控件 - 但我不确定这是一个好主意。

就个人而言,我只是重新公开我感兴趣的属性,或许将它们放入不同的[Category(...)] - 确保同时拥有setter和getter。

有点像:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

class MyControl : UserControl
{
    private Button button;
    private Label label;
    public MyControl()
    {
        button = new Button { Dock = DockStyle.Right, Text = "Click me" };
        label = new Label { Dock = DockStyle.Left};
        Controls.Add(button);
        Controls.Add(label);
    }
    [Category("Wonder Control")]
    public string CaptionText { get { return label.Text; } set { label.Text = value; } }
    [Category("Wonder Control")]
    public Color ButtonBackColor { get { return button.BackColor; } set { button.BackColor = value; } }
}
static class Program
{

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        using (Form form = new Form())
        using (MyControl ctrl = new MyControl())
        using (PropertyGrid grid = new PropertyGrid())
        {
            ctrl.ButtonBackColor = Color.Red;
            ctrl.CaptionText = "Caption";
            ctrl.Dock = DockStyle.Fill;
            grid.Dock = DockStyle.Right;
            form.Controls.Add(ctrl);
            form.Controls.Add(grid);
            grid.SelectedObject = ctrl;
            Application.Run(form);
        }

    }
}

答案 3 :(得分:0)

如果控件中的所有按钮都共享相同的外观,为什么不将属性放在控件级别并让属性设置器传播所有按钮的任何更改?此外,使用30个单独的按钮控件似乎很多开销......您是否考虑过绘制日期标签并处理鼠标单击/悬停事件以确定何时单击特定日期?