I am new to XAML, but I would like the CheckBox option to be hidden on my application until the user mouses over the row and can check the box from there. Here is what I currently have and I'm not sure why it doesn't work.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbkSelect, Path=IsMouseOver}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
If you want to display the CheckBox only if a user hovers the row, meaning any cell of a row, you can use a RelativeSource binding to the IsMouseOver property the parent row.
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
If you want it to be dislayed only if a user hovers over the CheckBox column, your style will not work as you do not receive the mouse events on a hidden control. You can work around this with a Border that is visible.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border x:Name="cbkBorder" Background="Transparent">
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbkBorder, Path=IsMouseOver}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</Border>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Related
According to this picture the color of the selected row does not appear over the cells that have been changed color by Style, but appears in the cells that have not been colored by style
i want to set it over the cells that have been changed color by Style
<DataGridTextColumn Header=" 8 --- 7 " Binding="{Binding From_7_To_8}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}" >
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox x:Name="C8" Click="CHECK_CLICK"
Style="{DynamicResource CheckBoxStyle1}"
IsEnabled="{Binding Converter={StaticResource IsEnabled_Cell},ConverterParameter=C8}"
IsChecked="{Binding From_7_To_8,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
FontSize="12" Content=" 7 --- 8 "
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
FlowDirection="LeftToRight"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
</CheckBox>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Content.IsChecked, RelativeSource={RelativeSource Self}}"
Value="false" >
<Setter Property="Background" Value="{x:Null}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Order_Life_7_8,Mode=TwoWay}" Value="0">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Order_Life_7_8,Mode=TwoWay}" Value="1">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
<DataTrigger Binding="{Binding Order_Life_7_8,Mode=TwoWay}" Value="2">
<Setter Property="Background" Value="GreenYellow"/>
</DataTrigger>
<DataTrigger Binding="{Binding Order_Life_7_8,Mode=TwoWay}" Value="3">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
I am in a similar case that this question:
Displaying Content only when ListViewItem is Selected
I have a ComboBox that I only want to show when the ListViewItem that contains it is selected and when the ComboBox is not empty (both conditions must be true). It is very easy to bind visibility to a readonly property that checks if the ItemsSource property in the ViewModel has any items, and with the above link it is also solved how to show it only when its ListViewItem is selected, but I am not able to join both conditions. How can I only show the ComboBox when the item is selected and the combo is not empty?
This Style in the ComboBox does the trick for showing only when is selected:
<ComboBox ItemsSource="{Binding DataContext.ListaPedidosPendientes, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" DisplayMemberPath="numero">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
How can I add there the second condition (ListaPedidosPendientes.Count > 0)?
Thank you
You can evaluate the HasItems property of the ComboBox https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.itemscontrol.hasitems?view=net-5.0
and invert the conditions: Visible by default, collapse when not selected or when no items. Untested Aircode:
<ComboBox ItemsSource="{Binding DataContext.ListaPedidosPendientes, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" DisplayMemberPath="numero">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<Trigger Property="HasItems" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
There are two triggers to be set.
And the conditions are opposite.
Since the trigger only checks for equality, so you can compare Items.Count with zero.
But the condition >0 cannot be checked.
<ComboBox ItemsSource="{Binding DataContext.ListaPedidosPendientes, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" DisplayMemberPath="numero">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}" Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
I would like to gray out the text associated to an unchecked row in my application using xaml. I tried the following, but it is getting overwritten:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
As the Foreground color should be applied to all cells of a given row, you can remove the trigger. The trigger inside the CellTemplate will only apply to to the CheckBox that the style is applied to.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
If you want to apply the foreground color in normal state, but not in selected state, add this RowStyle.
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelectedForOrder}" Value="True">
<Setter Property="Foreground" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
If you want to apply the style in selected state, too, add this CellStyle. In this case a RelativeSource binding is used to access the data context of the row which contains IsSelectedForOrder.
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.IsSelectedForOrder, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Foreground" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
The checkbox is invisible until I mouse over which is what I want, but now I want it to stay visible once it is checked. I've tried implementing a multi trigger, but it doesn't seem to be working:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True"></Condition>
<Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True"></Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
A MultiDataTrigger will only apply the setter when all conditions are met.
Represents a trigger that applies property values or performs actions when the bound data meet a set of conditions.
Apart from that, binding to the DataGridRow does not work, as it has no IsChecked property. Instead, add a Trigger that acts on the IsChecked property of the associated CheckBox.
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</Trigger>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
i need to collapse the current DataGridRow based on a cell's DataContext value ,
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsParentExpanded}" Value="False">
<!-- Here i wan't to Collapse the DataGridRow-->
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
any ideas how this can be done ?
just to clarify i wan't there to be a Setter where the Target in the RelativeSource of type DataGridRow.
currently i apply this change threw :
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsParentExpanded}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
i was wondering if there's a different way , only using xaml of course , since i can traverse up the visual tree and do that in code.
You should do this in RowStyle like below
<DataGrid>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding IsParentExpanded}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>