I have a subclassed DataGridView
with a DataSource
of SortableBindingList<T>
. I use this thing everywhere, with the same underlying configuration. The current subclassed version mostly changes the designer defaults for properties, so they don't need to be re-set for each component instance.
I want to pack a lot more functionality into the subclassed control, such as...
- Intelligent column sorting, with the ability to sort descending on the first click of a column.
- The ability for mouse clicks and hotkeys to raise an events to the parent, with the item
T
that was clicked on. - Clean and integrated icon display for certain columns
- Easy row selection (from item T)
- Easy row updating (for item T)
- Smart context menus
- Smart tooltips
All of the permutations I can think of require a generic class approach SortableDataGridView<T>
, which breaks the designer. According to this post, there isn't a way to have your cake and eat it too, so T
in the class signature is out. I need the designer support.
Is there another design pattern or approach I can that will keep the designer happy, but still give me the ability to store my SortableBindingList<T>
within the component and use T
in raised events?
Essentially I think I'm looking for a way to use anonymous types within the class, without using them in the class signature-
public class SortableDataGridView : System.Windows.Forms.DataGridView
{
protected SortableBindingList<T> _data;
...
}
These approaches don't seem likely to work-
- A non-generic subclass of a generic base class (probably not possible)
- A special factory approach, where the factory method accepts but the base constructor doesn't.
The most likely solution approach is possibly to use a manager class, which interfaces closely with the SortableDataGridView
. All of the type-specific operations are recast as objects
for the benefit of the non-generic DataGridView
, and the manager class recasts them to T
before it raises events to the container.
Pseudocode;
public class SortableDataGridView : System.Windows.Forms.DataGridView
{
protected IDataGridManager _manager;
...
}
public interface IDataGridManager
{
object DataSource { get; };
void ItemDoubleClicked(object item);
...
}
public class MyDataGridManager<T> : IDataGridManager
{
protected SortableBindingList<T> _data;
public object DataSource
{
get
{
return _data;
}
}
public void ItemDoubleClicked(object item)
{
// raise event with item as T
}
...
}
Is the above a reasonable approach, or is there a better and more concise way?