WPF:Using checkbox IsChecked property in DataTrigger - c#

I am trying to use WPF checkbox's IsChecked property in a DataTrigger.Based on the value i am setting particular DataGridRow's background.
My NOT WORKING code
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkbox, Path=IsChecked}" Value="true">
<Setter Property="Background" Value="LightCyan" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataGrid x:Name="dataGrid1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="40" Width="Auto" Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="chkbox" IsChecked="{Binding Selected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Then I checked this link and changed the code as below and it is working fine.Here Selected is my public property.
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Selected}" Value="true">
<Setter Property="Background" Value="LightCyan" />
</DataTrigger>
</Style.Triggers>
</Style>
Please help me to understand why my original code is not working? am i missing anything.
google did not help.surprisingly there is no thread for this on SO also! Thank you for the help.

The original code is not working because you're trying to locate an object via ElementName which exists as a templated object, and thus isn't created until after the binding tries to resolve. Generally, you should only use ElementName when referring to ancestor objects in the visual tree, and not to children, particularly templated children.
As mentioned in comments, it would also not be possible to use a {RelativeSource FindAncestor... binding here because the CheckBox is a child, not an ancestor, of the DataGridRow

Related

WPF DataGrid setting text wrap when IsSelected

I'm trying to set a WPF DataGrid row TextBlock's TextWrapping property to Wrap when that row is selected, using the same technique shown in this answer.
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="LightBlue" />
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
The background colour changes fine, but the wrapping property does not appear to be set.
I've also tried creating a TextBlock style, but then had other issues accessing the IsSelected property. I get the feeling there's a minor change I should be making here.
Edit: It also seems like I might be able to go down the route of styling each DataGridTextColumn, though I was looking for a more global option especially when columns may be automatically generated.
I've also tried creating a TextBlock style, but then had other issues accessing the IsSelected property.
This ElementStyle should work:
<DataGridTextColumn Binding="{Binding Name}" Width="100">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridCell}}" Value="True">
<Setter Property="TextWrapping" Value="Wrap" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
If you are auto generating your columns, you could define the ElementStyle as a resource and handle the AutoGeneratingColumn event:
private void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGrid dataGrid = (DataGrid)sender;
DataGridTextColumn column = e.Column as DataGridTextColumn;
if (column != null)
{
column.ElementStyle = dataGrid.Resources["ElementStyle"] as Style;
}
}
XAML:
<DataGrid x:Name="dataGrid" AutoGeneratingColumn="dataGrid_AutoGeneratingColumn">
<DataGrid.Resources>
<Style x:Key="ElementStyle" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridCell}}" Value="True">
<Setter Property="TextWrapping" Value="Wrap" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>

DataTrigger for IconTemplate in RadWindow

I have a WPF application and I use Telerik.
I'm trying to set the Icon Template so that it has a default value and only on a certain condition will it bind the image source:
<telerik:RadWindow.Resources>
<Style x:Key="CustomIconStyle" TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsConditionMet, ElementName=MyWindow, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="Source" Value="{Binding Path=IconImageSource, ElementName=MyWindow, UpdateSourceTrigger=PropertyChanged}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadWindow.Resources>
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Style="{StaticResource CustomIconStyle}" Source="/MyAssembly;Component/Resources/myIcon.ico" Height="16" Margin="0,0,5,0"/>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
For some reason it always show the default icon.
I would also like to mention that I did implement the property changed - and I copied the same style just to a control inside the window and not in the template and it worked - so the problem isn't with the property changed
Any ideas?
You can use Triggers like that :
<telerik:RadWindow.Resources>
<Style TargetType="Image" x:Key="Style1">
<Setter Property="Source" Value="default.ico"/>
<Style.Triggers>
<DataTrigger Binding="{Binding MyCondition}" Value="true">
<Setter Property="Source" Value="custom.ico"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadWindow.Resources>
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Style="{StaticResource Style1}" Height="16" Margin="0,0,5,0"/>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
So the problem was that once the RadWindow was loaded it didn't change the Icon.
The solution:
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Height="16" Margin="0,0,5,0">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/MyAssembly;Component/Resources/myIcon.ico" />
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsConditionMet, ElementName=MyWindow}">
<Setter Property="Source" Value="{Binding Path=IconImageSource, ElementName=MyWindow}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
But the trick is to give the correct value of IsConditionMet in the windows constructor before the load.
Thanks for the help everyone.

How to Bind an another Control on the Setter Value Property by using a Trigger?

i've a little Problem with the Databinding in WPF an hope you can help me.
I want to bind the SelectedDate Parameter of a DatePicker on a TextBlock, but only when a CheckBox is checked. The CheckBox and the TextBlock are in a DataView, the DatePicker is outside.
In the Moment i try to use it with a Trigger an set the Binding in the Value-Property in the Setter Part.
<TextBlock Text="">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=StandartPitBis, Path=SelectedDate, StringFormat='dd.MM.yyyy'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
But this will not works. Has anywone a Tipp what i can do?
Here is the Code-Parts there i'm using:
Inside the GridView
The CheckBox
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="" x:Name="check_Anlage" IsChecked="{Binding Path=IsChecked}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
The TextBlock
<TextBlock Text="">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=StandartPitBis, Path=SelectedDate, StringFormat='dd.MM.yyyy'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Outside the GridView
The DatePicker
<DatePicker Grid.Column="1" Margin="0,5,0,5" SelectedDate="{x:Static sys:DateTime.Now}" x:Name="StandartPitVon" />
What i want to make is, that the SelectedDate from the DatePicker is shown in the TextBlock, but only when the CheckBox is Checked.
Thanks a lot
So. I've found the Problem. The Problem is, when a Property is set in the Object self, then it can't be overridet. When you need a Default-Value and a Trigger, then you must define the Default-Value in the Style too.
Example:
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{x:Null}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=StandartPitVon, Path=SelectedDate, StringFormat='dd.MM.yyyy'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>

DataGridTemplateColumn.HeaderTemplate issue

Please help on this issue and I'm not sure how to handle this.
I've combox box and datagrid. When ever I've selected combox value datagrid should be loaded with new data and that works perfectly. But I've DataGridTemplateColumn.HeaderTemplate with checkbox when I checked all the column with checkbox is also checked and also worked with unchecked as well. Both are fine.
Now my issue is when i selected combobox, datagrid --> headertemplate checkbox should be unchecked. IS there any event I can fire for this? My code below.
Combox is outside the datagrid.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="checkadded" Margin="6,0" IsChecked="{Binding IsSelected, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Name="ChkAllAdd" IsChecked="False" Width="50" Loaded="chkallLoaded" Checked="ChkAll_Checked" Unchecked="ChkAll_Unchecked" IsThreeState="False" Padding="4,3,4,3" HorizontalContentAlignment="Left" HorizontalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="#686868"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style TargetType="{x:Type DataGridCell}" >
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="white"/>
<Setter Property="Background" Value="#93A8A9"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
Create a ControlTemplate for Content Control and place your DataGrid and ComboBox Xaml in that. Now you can create an EventTrigger for Combobox and there you can set the CheckedBox Checked using element name in binding. This can be helpfull.

How do I overwrite AlternatingRowBackground inside the DataGridRow template?

I'm creating a DataGrid with rows with AlternatingRowBackground property. However, the data in the rows must be amended and that takes some time.
I'm trying to make the background color of the rows appear light gray while they are initializing. Here's what I'm doing in the RowTemplate:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Initialized}" Value="False">
<Setter Property="Background" Value="LightGray"/>
</DataTrigger>
</ControlTemplate.Triggers>
But this does not work for the odd rows which still have the color specified in AlternatingRowBackground.
How do I overwrite this so all rows which are not initialized appear light gray?
I had the same problem and worked for me next:
Set the AlternatingRowBackground in the style, but not in the DataGrid.
<Grid.Resources>
<Style x:Key="dg" TargetType="DataGrid">
<Setter Property="AlternatingRowBackground" Value="Orange"/>
<Setter Property="AutoGenerateColumns" Value="False"/>
</Style>
</Grid.Resources>
<DataGrid ItemsSource="{Binding Source={StaticResource one}, Path=Persons}" Style="{StaticResource dg}">
<DataGrid.Columns>
<DataGridTextColumn Width="*" Header="Name" Binding="{Binding Path=Name}"/>
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Mature}" Value="True">
<Setter Property="Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>

Categories