Перегрузить DataGridViewCellStyle и дать значение по умолчанию - PullRequest
2 голосов
/ 10 февраля 2010

Я пишу пользовательский объект 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 является классом, я не могу сделать из него константу. Я попытался изменить все параметры так, чтобы они были в конструкторе классов, и это прекрасно работает, за исключением того, что изменения, внесенные в свойства конструктора, просто возвращаются обратно, как только приложение запускается. Поэтому внесение изменений в конструктор не поможет.

Есть ли еще где-нибудь, где я могу поместить код, который запускается только тогда, когда элемент управления впервые отброшен на конструкторе? или любой другой способ установки по умолчанию?

Ответы [ 2 ]

2 голосов
/ 09 ноября 2010

Я тоже столкнулся с этой проблемой. Мое решение работает вокруг требования, чтобы аргумент 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); }
}
1 голос
/ 11 февраля 2010

На самом деле, я подумал об этом немного дольше и нашел более простое решение для моей проблемы. Это не работает для всех случаев, потому что оно основано на том факте, что человек, использующий пользовательский компонент, скорее всего, никогда не захочет вернуть весь 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

То, что у вас есть золотой молот, говорит о том, что каждая проблема - это гвоздь.

...