I am customizing WPF DataGrid in a generic way. consider that I have defined an enum of Creatures like this:
public enum CreatureType
{
Human,
Animal,
Insect,
Virus
}
then I have an attached property of the above type so it can be attached to any control I want, that called CreatureTypeProeprty. then I want to attach this property to DataGridTemplateColumn and I want to access this inside the Template. for example consider the following reproducible code of my problem:
<DataGridTemplateColumn local:CreatureTypeProeprty.Value = "Human" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=(local:CreatureTypeProeprty.Value), RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridTemplateColumn }}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
This doesn't work and I know why because DataGrid column is not part of the visual tree. but I can't find any way to solve this issue. I also tried This but this solution can not be used in a generic way and ends up in a very dirty solution! I'm looking for a more sophisticated and clean way. I also tried using the name for the column and specifying ElementName it works but also this can not be used when there is multiple columns and I have to repeat codes every time.
The datagrid column is more a conceptual thing. It's not so much not in the visual tree as not there at all.
There is no spoon.
One way to do this sort of thing would be to use a list and index it. In your window viewmode
Obviously, load that up with CreatureTypes in the same order as your columns.
You can then reference using something like
Unfortunately, you need a fixed number for indexing.
You could perhaps dynamically build your columns and add them to the datagrid.
I would do that by defining a string template and substituting values, then using xamlreader.parse() to build a datagrid column which you add to your datagrid.
In my sample I have a col.txt file. This is a sort of template for my datagrid columns.
It is pretty much a piece of datagrid column markup.
It's showing totals for months so obviously 12 months and my array here is monthtotals[12]. Obviously, this is a different thing and illustrating the approach.
I also have a dg.txt file which is of course something rather similar for my datagrid. But that'd be repetitive.
And I have some code substitutes strings, parses the result and appends a built column:
Might be more complicated than you need but maybe it'll help someone else down the line.
BTW
I suggest an "unknown" or "none" as the first in any enum. This is standard practice in my experience so you can differentiate between a set and unset value.
Q1 How common is this?
Not very. It solves problems I would describe as "awkward" bindings and can simplify UI logic in templating.
Or a sort of super auto generator for columns.
A similar approach can be very useful for user configurable UI or dynamic UI.
Imagine a dynamic UI where the user is working with xml and xml defines the UI. Variable stats or variable points calculation for a tabletop wargaming points calculator.
Or where the user picks the columns they want and how to display them. That can be built as strings and saved to their roaming profile. Loaded from there using xamlreader.load which gives you your entire datagrid definition.
q2 That's what the sample does.
dg.txt looks like
This line gets Columns
And this line append each column
It is so there are Xelement nodes you can find that the file is manipulated as xml rather than just as a string.