So, for example I have some MVVM WPF application with simple model:
public class MyObject
{
public string F1 { get; set; }
public string F2 { get; set; }
}
and simple view model that creates 3 rows:
public class MyViewModel
{
public ObservableCollection<MyObject> Objects { get; set; }
public MyViewModel()
{
Objects = new ObservableCollection<MyObject>
{
new MyObject{F1 = "V1",F2 = "B1"},
new MyObject{F1 = "V2",F2 = "B2"},
new MyObject{F1 = "V3",F2 = "V3"}
};
}
}
And in view I have a DataGrid
with manually defined columns and for each column I set CellStyle
. Both styles defined in Window.Resources
block. But for first column, I use StaticResource
and for the second DynamicResource
View XAML:
<Window x:Class="WpfApplication12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" x:Name="WholeWindow">
<Window.Resources>
<Style x:Key="BaseCellClass" TargetType="DataGridCell">
<Setter Property="Foreground" Value="Blue" />
</Style>
</Window.Resources>
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=WholeWindow, Path=ViewModel.Objects}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding F1}" Header="F1" CellStyle="{StaticResource BaseCellClass}" />
<DataGridTextColumn Binding="{Binding F2}" Header="F2" CellStyle="{DynamicResource BaseCellClass}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
So the problem is: in the second column, the resource doesn't get applied to the column.
You could create resources for the properties in your DataGridCell
Style
and then reference them as a DynamicResource
within the Style
definition:
Based on your example it would look like this:
<Window.Resources>
<SolidColorBrush x:Key="ForegroundBrush" Color="Blue"/>
<Style x:Key="BaseCellClass" TargetType="DataGridCell">
<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}" />
</Style>
</Window.Resources>
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=WholeWindow, Path=ViewModel.Objects}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding F1}" Header="F1" CellStyle="{StaticResource BaseCellClass}" />
<DataGridTextColumn Binding="{Binding F2}" Header="F2" CellStyle="{StaticResource BaseCellClass}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
The resources would of course be located in separate resource files.
I found solution with using a little service. In few words I write in xaml this code:
<wpfApplication12:DataGridColumnDynamicStyleService TargetGrid="{Binding ElementName=Grid}">
<wpfApplication12:DataGridColumnDynamicStyleService.ColumnStyles>
<wpfApplication12:DataGridColumnStyleBinding ColumnTag="C1" DynamicStyle="{DynamicResource BaseCellClass}" />
</wpfApplication12:DataGridColumnDynamicStyleService.ColumnStyles>
</wpfApplication12:DataGridColumnDynamicStyleService>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=WholeWindow, Path=ViewModel.Objects}" x:Name="Grid">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding F1}" Header="F1" wpfApplication12:DataGridColumnDynamicStyle.ColumnTag="C1" />
<DataGridTextColumn Binding="{Binding F2}" Header="F2" wpfApplication12:DataGridColumnDynamicStyle.ColumnTag="C2" />
</DataGrid.Columns>
</DataGrid>
Here, as you can see, I use attached property ColumnTag to identify columns. And I create a service control that defines styles for columns and set target datagrid as TargetGrid
If you want to see all the code, here is the link to the solution on google drive
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With