WPF Generic DataGrid CellTemplate - snap to cell cost?

I had a problem understanding the basics of data binding in WPF. I have a generic DataGrid (with a set of AutoGenerateColumns) that is bound to a DataTable with column names that differ for each load. When the dataTable contains boolean columns, I want to display a column containing custom images representing true and false.

For this, I have a StaticResource declared on the page for celltemplate, and I have C # code that catches the AutoGenerateColumn event and uses this template:

<DataTemplate x:Key="CheckmarkColumnTemplate"> <Image x:Name="CheckmarkImage" Source="..\..\images\check.png" Height="16" Width="16" /> <DataTemplate.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value}" Value="False"> <Setter TargetName="CheckmarkImage" Property="Source" Value="..\..\images\nocheck.png" /> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> 

C # code:

 private void dgData_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (e.PropertyType == typeof(bool)) { DataGridTemplateColumn col = new DataGridTemplateColumn(); Binding binding = new Binding(e.PropertyName); col.CellTemplate = (this.Resources["CheckmarkColumnTemplate"] as DataTemplate); col.Header = e.PropertyName; e.Column = col; } } 

This basically works, except that my DataTrigger Binding property is confused. It never detects that the column value is false, so it never displays the image nocheck.png. I donโ€™t know how to write the Binding property to refer to the value of the column database (remember that the column name is different every time, so I canโ€™t hardcode the column name in part of the binding path).

Can someone tell me what the Binding property should look like so that it just captures the column value?

+4
source share
2 answers

I achieved the result that I used using a different method. Instead of using a DataGridTemplateColumn, I used a DataGridCheckBoxColumn and set a custom ElementStyle based on the sample style used in the WPF Practical Lab Toolkit:

 <Style x:Key="NoBorderCheckBoxStyle" TargetType="{x:Type CheckBox}"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/> <Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="IsEnabled" Value="false"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CheckBox}"> <BulletDecorator SnapsToDevicePixels="true" Background="Transparent"> <BulletDecorator.Bullet> <Canvas x:Name="canvas" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"> <Image x:Name="checkImage" Source="..\..\images\check.png" Height="16" Width="16"></Image> </Canvas> </BulletDecorator.Bullet> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/> </BulletDecorator> <ControlTemplate.Triggers> <Trigger Property="HasContent" Value="True"> <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/> <Setter Property="Padding" Value="4,0,0,0"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> <Trigger Property="IsChecked" Value="False"> <Setter Property="Source" TargetName="checkImage" Value="..\..\images\nocheck.png" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 

I'm having trouble reading the IsEnabled property from the actual parameters of the DataGrid column (its property is IsReadOnly), but since my use of the DataGrid is read-only, I just set it to false here.

+1
source

I have the same problem and am still looking for an answer. My current solution is to create a DataTemplate in AutoGeneratingColumn event handler, so the DataTemplate knows the name of the property.

 private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { e.Column = new DataGridTemplateColumn { Header = e.PropertyName, CellTemplate = CreateSimpleCellTemplate(e.PropertyName) } } private static DataTemplate CreateSimpleCellTemplate(string propertyName) { DataTemplate template = new DataTemplate(); template.VisualTree = new FrameworkElementFactory(typeof(Label)); template.VisualTree.SetBinding(ContentProperty, new Binding(propertyName)); return template; } 
+2
source

All Articles