Reputation: 12870
I checked these answers, but none had the information I'm looking for:
How to setup a WPF datatemplate in code for a treeview?
How to set Control Template in code?
Create ControlTemplate programmatically in WPF
Here is the gist of my code:
DataGridTextColumn col = new DataGridTextColumn();
Style styl = null;
// Need to add this on a per-column basis
// <common:RequiredPropertyDisplayBrushConverter x:Key="requiredDisplayBrushConverter" />
string xaml = "<ControlTemplate TargetType=\"{x:Type DataGridCell}\"> <TextBox Background=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Text, Converter={StaticResource requiredDisplayBrushConverter} > </TextBox> </ControlTemplate>";
MemoryStream sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
ParserContext pc = new ParserContext();
pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
ControlTemplate ct = (ControlTemplate)XamlReader.Load(sr, pc);
styl.Setters.Add(new Setter(TemplateProperty, ct));
col.CellStyle = styl;
In the ControlTemplate, a binding refers to the converter mentioned in the comments. When the converter is defined in the xaml as a resource for the DataGrid, I get a runtime error: {"Cannot find resource named 'requiredDisplayBrushConverter'. Resource names are case sensitive."}
Can I add this as a resource to the column? Or add it to the DataGrid's resources at runtime?
Or is there some other technique?
Thanks --
Upvotes: 0
Views: 812
Reputation: 4322
You can add it to the xaml but you'll need to rearrange it. The resource will need to be defined before you can use it. Which means the background will need to be defined as a child tag.
Change your xaml to this:
string xaml = "<ControlTemplate TargetType=\"{x:Type DataGridCell}\"><TextBox><TextBox.Resources><common:RequiredPropertyDisplayBrushConverter x:Key=\"requiredDisplayBrushConverter\" /></TextBox.Resources><TextBox.Background><Binding RelativeSource=\"{RelativeSource TemplatedParent}\" Path=\"Content.Text\" Converter=\"{StaticResource requiredDisplayBrushConverter}\"/></TextBox.Background></TextBox></ControlTemplate>";
And you'll need to define the common namespace. Add this after your other namespaces (with the correct namespace/assembly, of course):
pc.XmlnsDictionary.Add("common", "clr-namespace:WPFApplication;assembly=WPFApplication");
OR, you could just add the resource to your App.xaml, if that is an option.
Upvotes: 2