I'm developing a wpf-based application and I'm currently struggling to find the best way of supporting a recurring scenario in it.
This app uses grids a lot. There are a bunch of features I want in it that are meant to be used in grids, such as drag & drop, multiple row edition, conditional row coloring, etc. But at the same time, I want my data objects to derive from a specific, data-oriented class that is unaware of any UI context and could be used by a single form, with standalone editors.
Therefore, I'd like to have a DataGridViewModel
class that will in turn expose two collections: Rows
as DataGridRowViewModel
and Columns
as DataGridColumnViewModel
. The row view model would expose a RowData
property which will be the actual data object, while the column view model would have a PropertyDescriptor
(from System.ComponentModel
namespace) that will indicate which data object field the column is meant for.
You can think of the DataGridRowViewModel
as a container for the "real" row object.
The goal is to allow separation of concerns between grid-specific functionalities (controlling row height, color, selection, etc) and data-specific functionalities, so that one doesn't need to know about the other. Ideally, a third component will be aware of both and ensure proper communication between the two layers (observing a data field and change the row color under condition x or y, for example).
Does this approach makes any sense? What kind of complications should I expect out of this (binding issues, performance and the likes)?
Best Answer
I've been working with grids for a while and had simmilar idea and scenarios. There is a flaw in this approach: you want many features on your grid, but this means you'll have many very different kinds of data in it. So your grid will have to visualize and edit all this data.
This isn't a problem by itself, but, this means that grid will become "God Object" itself. There is a different approach to solve this: make grid as a "thin" container. I mean don't think of a grid as a cells with text.
Think of it as a layouts.
Then:
The approach I proposed is quite complex to implement though. Maybe you don't need such complex cases. Also be warned that having this many components requires optimizations (specifically in simple and most common cases). But in the result you can have a swiss-knife solution for all scenarios with grids.
Comparing to your proposial it have some benefits (and your proposial have limitations in this areas): it can take data from deep fields inside your objects, it can have computed values, you don't have to convert your objects to "RowData@, it can handle several hungry components in one cell.
For your question "Is this really ok?" - yes it is. There are several big frameworks do grids your way, from what comes to my mind right now: Qt have this way of binding. So your approach is a well known good practice anyway too whith some known problems and limits though.