We're customizing the presentation of certain columns in our grid, and overriding the Display and Edit templates of those cells. We're also applying some fialy complex logic behind the scenes that recalculates various content for all cells periodically. For example, based on some condition, certain cells' background color changes. Ideally the template for this would be as simple as possible, with the Background color bound to some property of the CellValuePresenter, allwoing me to adjust the properties of the CellValuePresenter in code. However, for that to work, I need to do one of two things:
1) Put all of the bindable content within the CellValuePresenter's "Tag" field. This works, but it seems like a hack.
2) Subclass CellValuePresenter (MyCellValuePresenter), so I can add additional properties to it.
Is there a viable approach to informing the XamDataGrid that it should create "MyCellValuePresenter" objects instead of standard CellValuePresenters when it initializes?
Hi Dan,
Subclassing the CellValuePresenter is not really an option as we don't expose a way for developers to provide their own cells. CellValuePresenters are created and managed internally.
An option you have is to use attached properties. Attached properties will allow you to add your own "properties" to the CVP which you can then use later on in your templates via RelativeSource bindings back up to the CVP.
The other option would be your Tag property idea. I don't really consider this a hack as you would be using the Tag property for its intended use. This property was meant to be used to store extra data on the object.
One thing you need to keep in mind is that CVPs are recycled amongst all the cells. So if you store data in one CVP, that CVP may get moved to a different cell and your data could end up being irrelevant to that new cell. I would recommend that instead of storing the data inside the CVP.Tag you should store it in the DataContext instead. The DataContext for a CVP is a DataRecord and this class has a Tag property. It also has a Cells collection and each individual Cell object has a Tag property as well.
Thanks, Rob. This was very helpful, and probably helped me avoid strange bugs. I opted for the approach of using an attached property to provide the CellValuePresenter with an object containing the data I wanted to access in the template. I'm creating the data when the DataRow is initialized, but only attaching it when the CellValuePresenter is initialized.