1

I am creating a DataGridViewCalendarCell based on this MSDN sample and I want to override the Clone of the base class DataGridViewTextBoxCell because I have added two properties to DataGridViewCalendarCell. The problem is that I'm not sure of how to go about this.

Why I think I need to override Clone:

The DateTimePicker has two properties: CustomFormat and Format that I want to expose on through properties on my CalendarColumn Class that I can set when initializing the CalendarColumn. These properties will then set the properties on the DataGridViewCalendarCell that the column uses as a template like so:

public string CustomFormat { 
    get {
        return ((DataGridViewCalendarCell)base.CellTemplate).CustomFormat;
    }
    set {
        ((DataGridViewCalendarCell)base.CellTemplate).CustomFormat = value;
    }
}

public DateTimePickerFormat Format {
    get {
        return ((DataGridViewCalendarCell)base.CellTemplate).Format;
    }
    set {
        ((DataGridViewCalendarCell)base.CellTemplate).Format = value;
    }
}

In the DataGridViewCalendarCell.InitializeEditingControl function the properties are again passed on to the DateTimePicker used to edit the cell value.

The problem I have is that when DataGridViewCalendarCell.InitializeEditingControl is called the Format and CustomFormat are not set anymore.

I am guessing this is because the actual DataGridViewCalendarCells are clones of the template. As I didn't override the Clone method of DateGridViewTextBoxCell, my extra properties are not cloned as well.

Also, there is a nice note in the MSDN article:

When you derive from DataGridViewCell or DataGridViewColumn and add new properties to the derived class, be sure to override the Clone method to copy the new properties during cloning operations. You should also call the base class's Clone method so that the properties of the base class are copied to the new cell or column.

Why I don't know how to override Clone:

This makes me feel like there is a standard way to do this for WinForms controls, but I can't find anything about it.

There is no copy constructor on DataGridViewTextBoxCell to which I can pass the clone returned from base.Clone(). I prefer not to use Reflection because I'm not sure how to tell which properties I should and shouldn't copy. I wonder if I could do something with serialization, but I am afraid of any side effects that I can't oversee, right now.

Is there a standard way to override Clone on a custom control?

EDIT: I editted the question title because the cloning is not relevant for all custom controls, just for DataGridViewCells

4

1 回答 1

3

基于这个关于克隆的另一个问题的答案。

另一种方法是在 Clone 的实现中使用 Object.MemberwiseClone - 这将确保结果始终是正确的类型,并允许覆盖扩展

显然DataGridViewTextBoxCell正在使用Object.MemberwiseClone,因为我能够将结果转换为base.Clone()to DataGridViewCalendarCell

这是我的实现方法Clone()

class DataGridViewCalendarCell : DataGridViewTextBoxCell
{
    (...)

    public string CustomFormat { get; set; }
    public DateTimePickerFormat Format { get; set; }

    public override object Clone()
    {
        var clone = (DataGridViewCalendarCell)base.Clone();

        clone.Format = Format;
        clone.CustomFormat = CustomFormat;

        return clone;
    }
}
于 2013-04-29T11:31:02.193 回答