重载DataGridViewCellStyle并给出默认值

发布于 2024-08-21 04:42:54 字数 764 浏览 8 评论 0原文

我正在为一个大型项目编写一个自定义 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 是一个类,因此我无法从中创建常量。我尝试将所有设置更改为我希望它们在类构造函数中的设置,效果很好,除了设计器属性中所做的更改会在应用程序运行后立即恢复。因此,将更改放入构造函数中是行不通的。

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

I'm writing a custom DataGridView object for a large project to hand out to a bunch of developers to make our app sections look consistent.

I want to set defaults for many of the properties of the DataGridView, and I can set many of them like this:

<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

These properties overload with their defaults just fine. Its when I started trying to make default Cell styles that I ran into the issue. Since the DataGridViewCellStyle is a class, I cannot make a constant out of it. I've tried changing all of the settings to what I want them to be in the class constructor, and that works great, except that changes made in the designer properties just get set back as soon as the app runs. So putting the changes in the constructor won't do.

Is there anywhere else I can put code that only runs when the control is first dropped on the designer? or any other way of setting a default?

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

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

发布评论

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

评论(2

丢了幸福的猪 2024-08-28 04:42:54

我也遇到了这个问题。我的解决方案围绕将 DefaultValue 参数作为编译时常量的要求进行工作。我想,难道在类构造函数(C# 中由静态构造函数定义,VB 中由共享构造函数定义)中设置值就足够了吗?

在我的情况下,这似乎是一个很好的解决方法,尽管在某些情况下它可能会中断,因为在加载类时调用类构造函数之前它实际上并不存在于元数据中,但对于设计器属性来说,应该可以接受。因为 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); }
}

I ran into this problem too. My solution works around the requirement for the DefaultValue argument to be a compile-time constant. I thought, wouldn't it be sufficient to set the value in the class constructor (defined by the static constructor in C#, and the shared constructor in VB) instead?

This seems to be an good work-around in my case, though there are probably instances where it might break since it's not actually present in the meta-data until the class constructor is called upon loading the class, but for a Designer attribute that should be acceptable. Because DefaultValueAttribute.SetValue is protected, I had to define a derived class that makes it public.

This works fine in the designer, it recognizes when the value is the same as the default and omits it from the generated code when possible, and only generates the differences from the default.

Here's the code in C#, this should work in VB too but I'm not overly familiar with its syntax so I'll have to leave that up to you.

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); }
}
在风中等你 2024-08-28 04:42:54

事实上,我想了一会儿,发现了一个更简单的解决方案来解决我的问题。这并不适用于所有情况,因为它依赖于这样一个事实:使用自定义组件的人可能永远不想将整个 CellStyle 恢复为 Windows 默认值。我最终将新的 CellStyle 与构造函数中的当前 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

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

Actually, I thought about it a while longer and came across a simpler solution for my issue. This does not work for all cases because it relies on the fact that the person using the custom component will likely never want to revert an entire CellStyle back to windows defaults. I ended up comparing a new CellStyle to the current one in the constructor, and only setting the style if they matched. This way it won't overwrite changes, but it will set it up the first time.

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

Just goes to show, Just because you have a golden hammer, doesn't mean that every problem is a nail.

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