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.
Related
I need to change the background color of a Textbox that is inside DataGridTemplateColumn cell based on whether or not if the data cell is selected.
Currently what I managed to do is, changing the background color of the template cell, which became useless because of error management.
Thus, I want to change the background of the Textbox, and revert it back on selection changed.
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="DarkBlue"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn IsReadOnly="True" MinWidth="150" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=TwoDLineName, Mode=TwoWay,UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
HorizontalAlignment="Stretch" Style="{StaticResource TextBoxValidated}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
You could use a Style with a DataTrigger that binds to the IsSelected property of the parent row:
<DataGridTemplateColumn IsReadOnly="True" MinWidth="150" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=TwoDLineName, Mode=TwoWay,UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True, NotifyOnValidationError=True}">
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource TextBoxValidated}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=DataGridRow}}"
Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I am new to WPF and want to create something like this:
As you can see in my xaml file below, I have made all the columns read only (except the checkbox column) and since the default behavior of DataGrid is to highlight the row when directly clicking on it, I've hidden that by making the background color transparent.
However, what I do want to have happen is that when you click the checkbox, the entire row will highlight. So, I don't want row highlighting when you click other stuff (including within the checkbox column but not in the checkbox itself) but highlight the row when you click the checkbox.
Can anyone help me achieve this desired behavior?
<DataGrid Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
ItemsSource="{Binding StudentData}"
AutoGenerateColumns="False"
RowHeight="30"
ColumnWidth="150"
GridLinesVisibility="Horizontal"
HeadersVisibility="Column"
SelectionMode="Extended"
>
<DataGrid.Resources>
<!-- Set the color, height, and padding of colum headers -->
<Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#7AC040" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Height" Value="30" />
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="BorderThickness" Value="0,0,1,0"/>
<Setter Property="Padding" Value="10 0 0 0" />
</Style>
<!-- When selecting a row, sets its highlight color to a light blue and its text to be black -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#CFECFF"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
<!-- Stylizes the checkbox column and makes it so that clicking the checkbox will select it instead of having to click twice -->
<Style x:Key="DataGridCheckboxStyle" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<!-- Pads the text of the actual data and makes the font size a bit bigger -->
<Style x:Key="GridCellStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="10 0 0 0"/>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontSize" Value="13" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Width="40">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource DataGridCheckboxStyle}" IsChecked="{Binding Path=Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="270" Header="Name" Binding="{Binding Name}" ElementStyle="{StaticResource GridCellStyle}" IsReadOnly="True" />
<DataGridTextColumn Width="250" Header="University" Binding="{Binding University}" ElementStyle="{StaticResource GridCellStyle}" IsReadOnly="True" />
<DataGridTextColumn Width="100" Header="Age" Binding="{Binding Age}" ElementStyle="{StaticResource GridCellStyle}" IsReadOnly="True" />
<DataGridTemplateColumn Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding StatusImage}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<!-- Removes any highlighting of rows when clicking on a cell -->
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
</DataGrid>
First, I would replace the DataTemplateColumn with a DataGridCheckBoxColumn, like so:
<DataGridCheckBoxColumn Binding="{Binding Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
Then, I would add a RowStyle to your DataGrid, like so:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Selected}"
Value="True">
<Setter Property="IsSelected"
Value="True" />
<Setter Property="Background"
Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
Note that I'm just changing the background to red so it's super clear what's happening.
I have a WPF app.
I use the datagrid.
Inside one of the columns I am using a hyperlink. The style sets this link to green.
When I highlight a row in the datagrid the forecolor of the hyperlink does not chnage to white. it remains green and as such not easiliy read/seen.
I have tried to add a triiger but there does not seem to be a propery/event for hightlighted - only isMouseOver.
This is my grid:
<DataGrid
<DataGrid.Columns>
<DataGridTextColumn Header="Work Item" Width="*" IsReadOnly="True" Binding="{Binding Description}" />
<DataGridTemplateColumn Header="">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Style="{StaticResource Field_Hyperlink}">Remove</Hyperlink>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
and my style at the moment:
<Style TargetType="Hyperlink" x:Key="Field_Hyperlink" >
<Setter Property="Foreground" Value="DarkGreen"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Your Relative Source needs to be the DataGridRow, There you go:
<Style TargetType="Hyperlink" x:Key="Field_Hyperlink">
<Setter Property="Foreground" Value="DarkGreen"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource= {RelativeSource
AncestorType={x:Type DataGridRow}}}"
Value="True">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
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
I would like to set Triggers for the controls in a DataTemplate. Whenever I set a property of the control within the DataTemplate, it seems not working. However, If do not set the property within the TextBlock inside the DataTemplate, then I can see the effect of Trigger in the style (it works). I am not sure whether using Style Triggers with DataTemplate is good or not! The XAML is below;
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock" x:Key="BlockOf">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="ExtraBold" />
<Setter Property="FontSize" Value="22" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
...........
DataTemplate for the button,
<Button.ContentTemplate>
<DataTemplate DataType="Button">
<TextBlock Style="{DynamicResource BlockOf}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"
FontStyle="Italic" FontSize="9"/>
</DataTemplate>
</Button.ContentTemplate>
I can see two problems here. First one is that current trigger will work only for TextBlock inside Button, not over whole Button. You can change that by using DataTrigger with RelativeSource binding. Second problem is that even when mouse is over TextBlock Style.Trigger cannot overwrite local value that you set against TextBlock so you need to bring default values as Setter into your Style. Check Dependency Property Setting Precedence List
<Style TargetType="TextBlock" x:Key="BlockOf">
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontSize" Value="9"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsMouseOver}" Value="True">
<Setter Property="FontWeight" Value="ExtraBold" />
<Setter Property="FontSize" Value="22" />
</DataTrigger>
</Style.Triggers>
</Style>
and then TextBlock simply
<TextBlock Style="{DynamicResource BlockOf}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />