简体   繁体   English

防止Winforms Designer生成继承控件的属性值

[英]Prevent Winforms Designer from Generating Property Values for Inherited Controls

I have a custom DataGridView , let's say as such: 我有一个自定义DataGridView ,我们这样说:

public MyGridView : DataGridView
{
    public MyGridView()
    {
         BackgroundColor = Color.Red;
    }
}

Now, when I use this control in a project using the designer, for some reason it feels a need to also set the property in the designer.cs file. 现在,当我在使用设计器的项目中使用此控件时,由于某种原因,感觉到还需要在designer.cs文件中设置该属性。

So in the designer file, I would have: 因此,在设计器文件中,我将拥有:

this.MyGridView1.BackgroundColor = System.Drawing.Color.FromArgb((byte)(int)255, (byte)(int)0, (byte)(int)0);

The problem me with this is that it prevents me from being able to change the color in the constructor of my MyGridView , without having to go through all the forms in which I used to control and change it per instance, rendering my custom control useless. 我的问题是,这使我无法在MyGridView的构造函数中更改颜色,而不必遍历用于控制和更改实例的所有形式,从而使自定义控件无效。

With some properties which offer a virtual getter, this is no problem, but most properties do not have it. 对于某些提供虚拟吸气剂的属性,这没有问题,但是大多数属性都没有。

How can I prevent the designer from generating this code? 如何防止设计人员生成此代码?

I should emphasize that this isn't normally the way you do this, the [DefaultValue] attribute is normally the correct choice. 我应该强调,这通常不是您执行此操作的方式, [DefaultValue]属性通常是正确的选择。 But you are working with a property of type Color, it is not simple to write the attribute for that in a flexible way. 但是,您正在使用Color类型的属性,以灵活的方式为该属性编写属性并不简单。 The arguments you can pass to an attribute constructor can be only a select few data types, Color isn't one of them. 您可以传递给属性构造函数的参数只能是少数几种数据类型,Color并不是其中之一。 You'd have to craft a string that ColorConverter can understand, that's both ugly and hard to maintain. 您必须制作一个ColorConverter可以理解的字符串 ,既难看又难以维护。

PropertyGrid has a secondary way of providing defaults for "difficult" properties, it will also look for specially named private members in the class. PropertyGrid具有为“困难”属性提供默认值的第二种方法,它还将在类中查找专门命名的私有成员。 Given a property named "Xxxx", it looks for the following: 给定名为“ Xxxx”的属性,它将查找以下内容:

  • DefaultXxxx, a property with just a getter that returns the default value DefaultXxxx,仅具有一个getter的属性,该属性返回默认值
  • ResetXxxx(), a method that can run when the user selects the Reset context menu item ResetXxxx(),当用户选择“重置上下文”菜单项时可以运行的方法
  • ShouldSerializeXxxx(), a method that should return false if the value of the property should not be persisted. ShouldSerializeXxxx(),如果属性的值不应该保留,则应返回false的方法。

Which makes this code work: 这使此代码起作用:

public class MyGridView : DataGridView {
    public MyGridView() {
        this.BackgroundColor = DefaultBackgroundColor;
    }
    public new Color BackgroundColor {
        get { return base.BackgroundColor; }
        set { base.BackgroundColor = value;  }
    }
    private bool ShouldSerializeBackgroundColor() {
        return !this.BackgroundColor.Equals(DefaultBackgroundColor);
    }
    private void ResetBackgroundColor() {
        this.BackgroundColor = DefaultBackgroundColor;
    }
    private static Color DefaultBackgroundColor {
        get { return Color.Red; }
    }
}

Note that the ResetBackgroundColor() method is not actually necessary since no special effects are required when the user resets the property, I just included it for completeness. 请注意,实际上并没有必要使用ResetBackgroundColor()方法,因为当用户重置属性时,不需要任何特殊效果,我只是为了完整性而将其包括在内。

Try using InitLayout instead and DesignMode. 尝试改用InitLayout和DesignMode。 You can't use DesignMode in the ctor, but after the control is constructed you can access the Designmode property correctly to set the colour. 您不能在ctor中使用DesignMode,但是在构造控件之后,您可以正确访问Designmode属性以设置颜色。 Note: this will not be styled in the designer, just at run time. 注意:这不会在设计器中设置样式,而只是在运行时设置。

public class MyGridView : DataGridView
{

    protected override void InitLayout()
    {
        base.InitLayout();

        if (!DesignMode)
            BackgroundColor = Color.Red;
    }
}

There is a simpler way to assign DefaultValue to Color: 有一种将DefaultValue分配给Color的简单方法:

public class MyGridView : DataGridView
{
    public MyGridView()
    {
        BackgroundColor = Color.Red;
    }

    [DefaultValue(typeof(Color), "Red")]
    public new Color BackgroundColor
    {
        get { return base.BackgroundColor; }
        set { base.BackgroundColor = value; }
    }
}

If needs are simple and design appearance is no issue, try writing an extension or two, eg, 如果需求很简单并且设计外观没问题,请尝试编写一两个扩展名,例如,

public static class Extensions
{
    public static void ApplyStyle( this DataGridView dataGridView )
    {
        dataGridView.RowHeadersVisible = false;
        ...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM