InvalidOperationException - 'Template' property cannot be set in the current element's Template - c#

I'm trying to override the default ListviewItem in ListView with my custom own, so i used GetContainerForItemOverride(). It worked as expected, but when i try to override the default template it throw the following exception:
InvalidOperationException: ''Template' property cannot be set in the current element's Template'
Am i missing anything here?
<Style TargetType="{x:Type local:StockViewItem}">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="MinHeight" Value="60px" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:StockViewItem}">
<Grid Background="Transparent">
<Border
x:Name="ContentHost"
Margin="0"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding DefaultBackground}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid>
<GridViewRowPresenter x:Name="gridrowPresenter" Content="{TemplateBinding Property=ContentControl.Content}" />
<ContentPresenter
x:Name="contentPresenter"
Content="{TemplateBinding Property=ContentControl.Content}"
Visibility="Collapsed" />
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="GridView.ColumnCollection" Value="{x:Null}">
<Setter TargetName="contentPresenter" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ContentHost" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=local:StockViewItem}, Path=ActiveBackground, Mode=TwoWay}" />
<Setter Property="Template" Value="{StaticResource SelectedTemplate}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Cursor" Value="Hand" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="False" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ContentHost" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=local:StockViewItem}, Path=HoverBackground, Mode=TwoWay}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

As noted by Clemens, i had the Template setter in a trigger inside the Template itself instead of the Style triggers.

Related

Treeview Toggle Button Style working only for Parent Node and not for Child Nodes

I have a treeview, for which I wrote the style template of treeview in App.xaml, as I need to apply the style in two or three treeviews in my application. Now my problem is that the togglebutton style works for parent and not for child nodes.
Here for the togglebutton collapse and expand, i added two images(
Resources/Images/arrowexpand.png
and
Resources/Images/arrowcollapse.png
It is working perfectly with parent nodes, but not with child and subchild nodes.
For the child and subchild nodes, the default triangle button comes.
I didn't use MVVM. I don't know where I am going wrong
In the treeview
<TreeView x:Name="myTreeview" ItemContainerStyle="{StaticResource ms}"/>
Here is my code in App.xaml
<Style TargetType="TreeView">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<Border Name="Border" CornerRadius="5" BorderThickness="2">
<Border.BorderBrush>
<SolidColorBrush Color="DarkGreen"/>
</Border.BorderBrush>
<ItemsPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Image x:Name="image" Source="Resources/Images/arrowcollapse.png" />
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="image" Property="Source" Value="Resources/Images/arrowexpand.png" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ms" TargetType="TreeViewItem" >
<Setter Property="IsExpanded" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Connecting Lines -->
<Rectangle x:Name="HorLn" Margin="9,1,0,0" Height="1" Stroke="#DCDCDC" SnapsToDevicePixels="True"/>
<Rectangle x:Name="VerLn" Width="1" Stroke="#DCDCDC" Margin="0,0,1,0" Grid.RowSpan="2" SnapsToDevicePixels="true" Fill="White"/>
<ToggleButton Margin="-1,0,0,0" x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
<ToggleButton Margin="-1,0,0,0" x:Name="Collapsed" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
<Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" MinWidth="20"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="False">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false"/>
<Condition Property="Width" Value="Auto"/>
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false"/>
<Condition Property="Height" Value="Auto"/>
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinHeight" Value="19"/>
</MultiTrigger>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="White"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I want the arrow button to be for the child items and subchild items. Please tell me where I am wrong
I found out the Solution. Actually I am trying to apply the styles for the derived classes of the treeview item. So only my style was not working.
What I did was I just added this style statement in my Constructor of the derived Class
Style = (Style)FindResource(typeof(TreeViewItem));
Then the style was applied to all the items in the treeview.

How to change DataGrid selected row color WPF

I have created a data grid in my WPF application. I want to change the selected row color. I have following code
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:navigationApp.Resources">
<Style x:Key="DataGridColumnHeaderGripper" TargetType="Thumb">
<Setter Property="Width" Value="18"/>
<Setter Property="Background" Value="#252526"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent" BorderBrush="#3e3e45">
<Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="8,5" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="Transparent">
<ContentPresenter
Margin="{TemplateBinding Padding}"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Grid>
<Border x:Name="BorderOutline" BorderThickness="2,1,1,1" />
<Border x:Name="BorderInline" BorderThickness="0" />
<Grid Background="Black" Opacity="0" />
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter
ItemsPanel="{TemplateBinding ItemsControl.ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Grid.Column="1" />
<DataGridDetailsPresenter
Visibility="{TemplateBinding DataGridRow.DetailsVisibility}"
Grid.Column="1"
Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Both" />
<DataGridRowHeader
Visibility="Visible"
Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" />
</SelectiveScrollingGrid>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource ApplicationAccentBrush}" TargetName="BorderOutline" />
<Setter Property="Opacity" Value="0.8" TargetName="BorderOutline" />
<Setter Property="Background" Value="{DynamicResource ApplicationAccentBrushSecondary}" TargetName="BorderInline" />
<Setter Property="Opacity" Value="0.2" TargetName="BorderInline" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource ApplicationAccentBrush}" TargetName="BorderOutline" />
<Setter Property="Background" Value="{DynamicResource ApplicationAccentBrushSecondary}" TargetName="BorderInline" />
<Setter Property="Opacity" Value="0.3" TargetName="BorderInline" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="8,2,8,2"/>
<Setter Property="Background" Value="#252526"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border Name="HeaderBorder" Padding="{TemplateBinding Padding}" BorderThickness="1,1,1,1" BorderBrush="#3e3e45" Background="#252526">
<ContentPresenter
Name="HeaderContent"
Margin="0,0,0,1"
RecognizesAccessKey="True"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<!--<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0" Style="{StaticResource DataGridColumnHeaderGripper}"/>-->
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="HeaderBorder" Property="Background" Value="{DynamicResource ApplicationAccentBrushSecondary}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="HeaderBorder" Property="Background" Value="{DynamicResource ApplicationAccentBrush}"/>
<Setter TargetName="HeaderContent" Property="Margin" Value="1,1,0,0"/>
</Trigger>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter Property="TextElement.Foreground" Value="White"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Currently, the selected row color is white or transperent. So i cant see the selected row details.
You can change the color of the selected row by using triggers.As shown in the datagridrow style. Set the color to the background property of parent control (i.e Grid as TargetName) when row is selected .
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Grid x:Name="selectedRow">
<DataGridCellsPresenter
ItemsPanel="{TemplateBinding ItemsControl.ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Grid.Column="1" />
<DataGridDetailsPresenter
Visibility="{TemplateBinding DataGridRow.DetailsVisibility}"
Grid.Column="1"
Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Both" />
<DataGridRowHeader
Visibility="Visible"
Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" />
</SelectiveScrollingGrid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource ApplicationAccentBrushSecondary}" TargetName="selectedRow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In my project, I did as followed:
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource DataGridCell}">
<Setter Property="Background" Value="{StaticResource DataGridCellBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource DataGridBorderBrush}" />
<Setter Property="BorderThickness" Value="0"/>
<Style.Triggers>
<!-- IsSelected -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="{StaticResource BlackBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Controls:DataGridCellHelper.IsCellOrRowHeader" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="{StaticResource DataGridCellBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource DataGridCellBackgroundBrush}" />
</MultiTrigger>
//others properties
DataGridCellBackgroundBrush and DataGridBorderBrush is my color predefined

WPF Listbox. Style does not work correcty

I've a problem with a WPF ListBox ( See code bellow ). I'm trying to change the background and foreground for the listBox items when the mouse is over or when the item is selected but it doesn't work and I don't know why.
<ListBox x:Name="ListBoxSnapshots" ItemsSource="{Binding DevicesImageList}" SelectedIndex="{Binding WebcamSelected}" BorderThickness="0" SelectionMode="Single" HorizontalContentAlignment="Left" VerticalContentAlignment="Stretch" SelectionChanged="ListBoxSnapshots_SelectionChanged" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFBCBCBC"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="#FFD3D3D3"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFD3D3D3"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsSelected" Value="false">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="2" BorderBrush="DarkGray">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=theImage}" Stretch="Fill" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="142" Height="80"/>
<Canvas Width="142" Height="80" Margin="-142,0,0,0">
<Image Source="/MyApp;component/Images/snapshot-whitetriangle.png" Stretch="Fill" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
<Label FontSize="8" Content="{Binding Path=theImageIndex}" Foreground="DarkGray" FontWeight="DemiBold" Canvas.Top="61" Canvas.Left="110" HorizontalAlignment="Center" VerticalAlignment="Top" Width="34" Height="24" VerticalContentAlignment="Top" HorizontalContentAlignment="Right" />
</Canvas>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
My listBox looks like the following picture.
The border of the Item selected has not the color that I have applied using Style.
Thanks,
Well, unfortunately it's not so easy... You need to change default ControlTemplate of ListBoxItem. Basing on this answer I've tried to make it look as i thought you wanted it to look. The most important elements are in <Setter Property="Template"> setter.
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Padding" Value="4,1" />
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment,
RelativeSource={RelativeSource FindAncestor,
AncestorLevel=1,
AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment,
RelativeSource={RelativeSource FindAncestor,
AncestorLevel=1,
AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
SnapsToDevicePixels="True"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeDashArray="1 2"
StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd"
Background="White"
BorderBrush="DarkGray"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#FFBCBCBC" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="False" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#FFD3D3D3" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="True" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#FFD3D3D3" />
</MultiTrigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter TargetName="Bd"
Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

GridViewColumn.CellTemplate with TextBox not working with ListView.ItemContainerStyle

I have a ListView like this:
<ListView ItemsSource="{Binding Components}"
BorderThickness="0"
Margin="0,2,0,0"
HorizontalAlignment="Stretch"
MinHeight="150"
SelectionMode="Single"
<ListView.View>
<GridView>
<GridViewColumn Header="Component Name">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type viewModels:ComponentViewModel}">
<TextBox Text="{Binding Name}"
Style="{StaticResource TextBoxInListViewStyle}">
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
This renders like shown here:
As you can see, TextBox is used (I can select text), but the ListViewItemContainer gives me the glassy selection look which I don't want.
Then I have defined a ItemContainerStyle (ListViewItemStyle) for my ListView which is used like that (7th row):
<ListView ItemsSource="{Binding Components}"
BorderThickness="0"
Margin="0,2,0,0"
HorizontalAlignment="Stretch"
MinHeight="150"
SelectionMode="Single"
ItemContainerStyle="{StaticResource ListViewItemStyle}"
<ListView.View>
<GridView>
<GridViewColumn Header="Component Name">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type viewModels:ComponentViewModel}">
<TextBox Text="{Binding Name}"
Style="{StaticResource TextBoxInListViewStyle}">
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Here is my ListViewItemStyle:
<Style x:Key="ListViewItemStyle"
TargetType="{x:Type ListViewItem}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="Padding"
Value="4,1" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource FocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{StaticResource Item.MouseOver.Background}" />
<Setter Property="BorderBrush"
TargetName="Bd"
Value="{StaticResource Item.MouseOver.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="False" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{StaticResource Item.SelectedInactive.Background}" />
<Setter Property="BorderBrush"
TargetName="Bd"
Value="{StaticResource Item.SelectedInactive.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="True" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{StaticResource Item.SelectedActive.Background}" />
<Setter Property="BorderBrush"
TargetName="Bd"
Value="{StaticResource Item.SelectedActive.Border}" />
</MultiTrigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="TextElement.Foreground"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This gives me the selection look I want. But unfortunately now my TextBox template from the CellTemplate is not working anymore and the data binding isn't working either:
Happy new year!
I solved it!
Instead of using a ContentPresenter in my Style I had to use a GridRowPresenter!
<Style x:Key="ListViewItemStyle"
TargetType="{x:Type ListViewItem}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="Padding"
Value="4,1" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource FocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<GridViewRowPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
/>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{StaticResource Item.MouseOver.Background}" />
<Setter Property="BorderBrush"
TargetName="Bd"
Value="{StaticResource Item.MouseOver.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="False" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{StaticResource Item.SelectedInactive.Background}" />
<Setter Property="BorderBrush"
TargetName="Bd"
Value="{StaticResource Item.SelectedInactive.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="True" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{StaticResource Item.SelectedActive.Background}" />
<Setter Property="BorderBrush"
TargetName="Bd"
Value="{StaticResource Item.SelectedActive.Border}" />
</MultiTrigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="TextElement.Foreground"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then it looks like this:

Setting Background Color or WPF (4.0) ListBox - Windows 8

I am attempting to set the background color of a selected ListBoxItem to be white rather than the system color. I have read what I could find here on SO and have followed, or believed to have followed the recommendations there (Change background color for selected ListBox item, WPF How to change the listbox selected item text color when the list box loses focus, Change selected and unfocused Listbox style to not be grayed out, and others).
All seem to solve the problem by setting the HighlightBrush and ControlBrush to Transparent for the selected item. I have the following XAML and it sets the font color properly, but the backgroound is the default transparent blue regardless of the brush settings. I am still a bit of a WPF noob, so I must be missing something simple here.
<ListBox Width="Auto" Height="Auto" Grid.Column="0" BorderThickness="0" Background="#FFF3F3F3" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ListBox.ItemsSource>
<x:Array Type="{x:Type sys:String}">
<sys:String>String 1</sys:String>
<sys:String>String 2</sys:String>
<sys:String>String 3</sys:String>
<sys:String>String 4</sys:String>
</x:Array>
</ListBox.ItemsSource>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</Style.Resources>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="Foreground" Value="#999999"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" HorizontalAlignment="Right" Margin="0,0,8,0" Background="Transparent"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I would appreciate any nudges in the right direction.
EDIT:
After reading the first answer that it worked for them with a slight change, I took the application that I have been developing on my Windows 8 machine and executed it in a Windows 7 VM and it worked as expected. Any ideas on what needs to change to get this to work on a Windows 8 machine as well as a Windows 7?
Those posts are getting outdated for Windows-8.
In Windows-8 for some reason Microsoft don't want people editing their Default Style's so easily or something with a Brush over-ride.
ListBoxItem default Style from VS has this for selection triggers:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="False" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#3DDADADA" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="#FFDADADA" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="True" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#3D26A0DA" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="#FF26A0DA" />
</MultiTrigger>
Triggers for Selection state no longer are applying brushes we can over-ride easily but are static colors. Hence to modify it you are going to need to derive the template and modify the trigger there. to White
This is the full Style given by VS2012 Windows-8 for ListBoxItem
<Style x:Key="ListBoxItemStyle1"
TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="Padding"
Value="4,1" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment,
RelativeSource={RelativeSource FindAncestor,
AncestorLevel=1,
AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment,
RelativeSource={RelativeSource FindAncestor,
AncestorLevel=1,
AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
SnapsToDevicePixels="True"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeDashArray="1 2"
StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#1F26A0DA" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="#A826A0DA" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="False" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#3DDADADA" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="#FFDADADA" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="True" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="#3D26A0DA" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="#FF26A0DA" />
</MultiTrigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter TargetName="Bd"
Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
if you modify those triggers to:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="False" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="White" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="White" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive"
Value="True" />
<Condition Property="IsSelected"
Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="White" />
<Setter TargetName="Bd"
Property="BorderBrush"
Value="White" />
</MultiTrigger>
you should have your issue sorted.
Adding the following trigger to my Item DataTemplate, worked for Windows 10:
<DataTemplate x:Key="MyItemTemplate">
<Border Name="Border" Background="Transparent" BorderBrush="LightGray" BorderThickness="0,1,0,0" Padding="0">
<TextBlock Text="{Binding Text}" HorizontalAlignment="Left" FontWeight="Medium" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
<Setter TargetName="Border" Property="Background" Value="SkyBlue"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
So you simply want to make the background of the selected item white?
Your code minus the ControlBrushKey setting works for me:
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White" />
</Style.Resources>

Categories