代码之家  ›  专栏  ›  技术社区  ›  bernhof

应用程序范围的控制默认值

  •  1
  • bernhof  · 技术社区  · 16 年前

    这是为了简化当客户(或我自己)第10次改变主意时更改控件默认外观/行为的过程。这尤其与以下控制有关 DataGridView

    DefaultValue 有几个原因:

    • 继承我想指定自定义属性的每种类型的控件都很麻烦,更不用说覆盖/隐藏属性和设置DefaultValue属性了。
    • 继承控件的数量会随着时间的推移而增加,并使工具箱变得混乱。

    • A. 数据网格视图 默认情况下具有背景颜色 SystemColors.Window 我设定了自己的目标 Color.Blue 反常的).在设计师中 使用默认背景颜色, 运行应用程序时,会执行一部分代码,导致网格旋转

    • 示例2: 相同的背景颜色 数据网格视图 设置为 Color.Red 在设计师。这 在网格中,无论是在设计时还是运行时。


    对我来说,解决方案是使用反射来检查 默认值 属性,如所建议的 Daniel Brückner .

    SetDefaultValues 对于每个控件。对于要设置的每个属性值,我调用 SetValue

    不过,这种方法有一个缺陷 。在设计器中明确设置但与默认值没有区别的属性将被覆盖 方法。

    void SetDefaultValues(Control control)
    {
      if (control is DataGridView)
      {
        SetValue(control, "BackColor", Color.Blue);
      }
      else if (control is TextBox)
      {
        // etc.
      }
    }
    
    private static void SetValue(object control, string propertyName, object newValue)
    {
      System.Reflection.PropertyInfo prop = control.GetType().GetProperty(propertyName);
      if (prop == null)
      {
        throw new ArgumentException(string.Format(
          "Specified property \"{0}\" does not exist on type \"{1}\".", prop.Name, control.GetType().FullName),
          "propertyName");
      }
    
      bool defaultValueFound = false;
      object defaultValue = null;
      foreach (object attr in prop.GetCustomAttributes(true))
      {
        if (attr is DefaultValueAttribute)
        {
          defaultValue = ((DefaultValueAttribute)attr).Value;
          defaultValueFound = true;
          break;
        }
      }
    
      if (!defaultValueFound && prop.PropertyType.IsValueType)
      {
        // Get default value for value types if no default value was specified by attributes:
        defaultValue = Activator.CreateInstance(prop.PropertyType);
      }
      if (defaultValue == null || defaultValue.Equals(prop.GetValue(control, null)))
      {
        // If default value matches current value, set new value:
        prop.SetValue(control, newValue, null);
      }
    }
    
    3 回复  |  直到 9 年前
        1
  •  2
  •   Daniel Brückner    16 年前

    Control Builders 实现这一目标。

    编辑:

    昨晚,我用ControlBuilder做了一个通用包装器控件的快速原型。我对结果不满意。虽然你可能可以让它工作,但我相信一个新的Page或Container类可能是一个更简单的结果。我在测试中使用的源代码可以在我的 blog .

        2
  •  3
  •   Matthew Whited    16 年前

    1. 继承控制权,但你已经提到了。
    2. 有时我会为控件创建扩展方法,并在用户控件或窗体的构造函数中调用它们。这是启用或禁用排序等功能集的一种简单方法。数据网格中的列重排序,并提供一致的行为和外观。
    3. 使用数据绑定并将属性绑定到某些配置数据。我相信甚至有一个内置功能——用户设置或类似的东西——但我从未使用过这个功能。
        3
  •  1
  •   wefwfwefwe    16 年前

    foreach (Control c in Page.Controls)
    {
       if (c is Textbox)
       {
           (Textbox)c.Color.blah.blah.blah ;)
       }
       ///etc
       Recurse through (c.Controls);
    }