4

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

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

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

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

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

4

4 回答 4

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 个按钮(一个月中的天数),我不能只引用一个对象。

于 2009-11-13T13:06:14.197 回答
3

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

于 2009-11-13T12:45:29.867 回答
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);
        }

    }
}
于 2009-11-13T12:35:01.260 回答
0

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

于 2009-11-13T14:00:46.547 回答