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

发布于 2024-08-11 05:49:39 字数 381 浏览 4 评论 0原文

我使用 .NET C# 和标准 WinForms,而不是 WPF。

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

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

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

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

I'm using .NET C# with standard WinForms, not WPF.

I have this situation.
I'm creating a user control for a month calendar, similar to the .NET one but with a little more functionality.
I have a user control form, that fills with button objects representing dates.
The buttons can be colored with different color depending on their state(selected, mouse over, weekend...)

The way I'd like it to work is extending the button class to accept states, which determine colors, rather than coloring them from the parent (user control) class. There are 10 colors at the moment and I'd really wouldn't like to mess up the user control code with coloring conditions.

Also I would like to select all the colors at design time, using browsable designer properties.
The problem is that the designer shows only properties defined in the user control class, and not its children (buttons).

Is there any workaround for this problem?
So to put it short I want to change colors using internal button properties, and to be able to select them at design time, using designer properties, and not hard coding them manually.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

慕巷 2024-08-18 05:49:39

好吧,我将尝试通过代码来解释:

例如,我有一个用户控件和一个按钮类。
我想公开 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 个按钮(一个月中的几天),并且我不能仅引用一个对象。

Ok, I'll try to explain trough code:

For example, I have a user control and a button class.
I want to expose Button properties, and make them visible among MyControl properties in designer.

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; }
     }
}

This is a simple example. Normally I have 5 different styles including background and foreground color for each of them. So instead of managing colors in MyControl class, I'd like to define them in MyButton class. But the problem this way is that the properties in the MyButton class aren't visible in designer, because it only focuses on MyControl properties.

Btw. ignore the missing constructors and other basic classes stuff in the code example

I can't use:

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

because I have 30 buttons in MyControl (days in month), and I can't reference just a single object.

世界等同你 2024-08-18 05:49:39

为了使属性在设计器中可见,它们必须是具有 getter 和 setter 的公共属性 - 根据您的说法,属性只是 getter。您还可以尝试指定 BrowsableAttributeBindableAttribute 强制设计器显示它们。 。

For a property to be visible in the designer, they have to be public properties with a getter and setter - from what you're saying, the properties are only getters. You could also try specifying BrowsableAttribute and BindableAttribute on the properties to coerce the designer to display them...

不弃不离 2024-08-18 05:49:39

您可以在这里做很多事情 - 您可以(尽管这是一个糟糕的答案)在公共界面上公开有问题的控件 - 但我不确定这是一个好主意。

就我个人而言,我只会重新公开我感兴趣的属性,也许将它们放入不同的 [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);
        }

    }
}

There are various things you can do here - you could (although it is a bad answer) expose the controls in question on the public interface - but I'm not sure that is a great idea.

Personally, I would just re-expose the properties I am interested in, perhaps putting them into a different [Category(...)] - making sure to have both setters and getters.

A bit like:

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);
        }

    }
}
谷夏 2024-08-18 05:49:39

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

If all of the buttons within the control will share the same appearance, why not put the property at the control level and have the property setter propogate any changes to all of the buttons? Also, using 30 individual button controls seems like lot of overhead... have you considered drawing the labels for the days and handling mouse click/hover events to determine when a particular day is clicked?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文