【问题标题】:C# show browsable child properties in designerC# 在设计器中显示可浏览的子属性
【发布时间】:2010-12-16 06:28:30
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 您的子类的一些代码示例会有所帮助
  • 子类是一个简单的类,扩展了Button类。根据大小、文本和位置,它有各种构造函数。我希望所有颜色都成为此类的属性。但是当我将用户控件拖到框架时,我想从用户控件(父)设计器属性窗口中选择它们。
  • 添加示例;那一百万英里远吗?

标签: c# properties designer children componentmodel


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    要让一个属性在设计器中可见,它们必须是带有 getter 和 setter 的公共属性 - 根据您的说法,这些属性只是 getter。您也可以尝试在属性上指定BrowsableAttributeBindableAttribute 以强制设计人员显示它们...

    【讨论】:

      【解决方案3】:

      您可以在此处执行各种操作 - 您可以(尽管这是一个糟糕的答案)在公共界面上公开相关控件 - 但我不确定这是一个好主意。

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

      【讨论】:

      • 重新曝光是什么意思?我可以使用 [Category] ​​在父类中公开它们。有什么方法可以只在子类中公开它们吗?
      【解决方案4】:

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

      【讨论】:

      • 这是当前的解决方案。我有颜色的控制属性并将它们传播到按钮。我考虑过手动绘制所有内容,但我希望按钮成为活动对象,而不仅仅是简单的图形。我想避免对整个用户控件进行命中测试以确定所选日期。同样这样,我不必在每次点击时重新绘制所有日期,只需重新绘制已更改的日期即可。
      • “大量开销”是什么意思?性能问题还是只是很多不必要的代码?我正在考虑手动创建按钮类,而不仅仅是从 Button 继承并实现我需要的功能
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 2016-04-25
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多