2

我正在为一个大型项目编写一个自定义 DataGridView 对象,以分发给一群开发人员,以使我们的应用程序部分看起来一致。

我想为 DataGridView 的许多属性设置默认值,我可以像这样设置其中的许多属性:

<System.ComponentModel.Browsable(True), System.ComponentModel.DefaultValue(DataGridViewAutoSizeColumnsMode.Fill)>_
Public Overloads Property AutoSizeColumnsMode() As DataGridViewAutoSizeColumnMode
    Get
        Return MyBase.AutoSizeColumnsMode
    End Get
    Set(ByVal value As DataGridViewAutoSizeColumnMode)
        MyBase.AutoSizeColumnsMode = value
    End Set
End Property

这些属性以其默认值重载就好了。当我开始尝试制作默认的单元格样式时,我遇到了这个问题。由于 DataGridViewCellStyle 是一个类,因此我无法将其设为常量。我已经尝试将所有设置更改为我希望它们在类构造函数中的设置,并且效果很好,除了在设计器属性中所做的更改只会在应用程序运行后立即恢复。因此,将更改放在构造函数中是行不通的。

是否还有其他地方可以放置仅在控件首次放在设计器上时才运行的代码?或任何其他设置默认值的方式?

4

2 回答 2

2

我也遇到了这个问题。我的解决方案解决了 DefaultValue 参数是编译时常量的要求。我想,在类构造函数(由 C# 中的静态构造函数和 VB 中的共享构造函数定义)中设置值是否足够?

在我的情况下,这似乎是一个很好的解决方法,尽管可能存在它可能会中断的情况,因为它实际上并不存在于元数据中,直到在加载类时调用类构造函数,但是对于应该的 Designer 属性可以接受。因为 DefaultValueAttribute.SetValue 是受保护的,所以我必须定义一个派生类,使其公开。

这在设计器中工作正常,它识别出值何时与默认值相同,并在可能的情况下从生成的代码中省略它,并且只生成与默认值的差异。

这是 C# 中的代码,这也应该在 VB 中工作,但我对它的语法并不太熟悉,所以我不得不把它留给你。

public partial class HighlightGrid : DataGridView
{
    // Class constructor
    static MethodGrid()
    {
        // Get HighlightStyle attribute handle
        DefaultValueSettableAttribute attr =
            TypeDescriptor.GetProperties(typeof(HighlightGrid))["HighlightStyle"]
            .Attributes[typeof(DefaultValueSettableAttribute)]
            as DefaultValueSettableAttribute;

        // Set default highlight style
        DataGridViewCellStyle style = new DataGridViewCellStyle();
        style.BackColor = Color.Chartreuse;
        attr.SetValue(style);
    }
    [DefaultValueSettable, Description("Cell style of highlighted cells")]
    public DataGridViewCellStyle HighlightStyle
    {
        get { return this.highlightStyle; }
        set { this.highlightStyle = value; }
    }
    // ...
}

// Normally the value of DefaultValueAttribute can't be changed and has
// to be a compile-time constant. This derived class allows setting the
// value in the class constructor for example.
public class DefaultValueSettableAttribute : DefaultValueAttribute
{
    public DefaultValueSettableAttribute() : base(new object()) { }
    public new void SetValue(Object value) { base.SetValue(value); }
}
于 2010-11-09T10:06:58.780 回答
1

实际上,我考虑了一段时间,并为我的问题找到了一个更简单的解决方案。这并不适用于所有情况,因为它依赖于使用自定义组件的人可能永远不想将整个 CellStyle 恢复为 windows 默认值的事实。我最终在构造函数中将新的 CellStyle 与当前的进行了比较,并且只有在它们匹配时才设置样式。这样它就不会覆盖更改,但它会在第一次设置它。

Public Class CustomDataGridView
    Inherits System.Windows.Forms.DataGridView
    Private RowStyle As New DataGridViewCellStyle

    Public Sub New()
        RowStyle.BackColor = Color.FromArgb(223, 220, 200)
        RowStyle.Font = New Font("Arial", 12.75, FontStyle.Bold, GraphicsUnit.Point)
        RowStyle.ForeColor = Color.Black
        RowStyle.SelectionBackColor = Color.FromArgb(94, 136, 161)

        If MyBase.RowsDefaultCellStyle.ToString = (New DataGridViewCellStyle).ToString Then
            MyBase.RowsDefaultCellStyle = RowStyle
        End If 
    End Sub
End Class

只是表明,仅仅因为你有一把金锤,并不意味着每个问题都是钉子。

于 2010-02-10T21:18:44.670 回答