WPF- trigger target not found - wpf

I have own style on listbox, I use in style data template and also control template.
In data template I create listbox item with some textboxes. In control template I want create a trigger which change foreground color of some textbox if listbox item is selected.
Here is some from style:
<Style x:Key="lbStyle" TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid Name="MainGrid">
<TextBlock Name="tbName" Text="{Binding Value.nick}"
Grid.Column="0" Grid.Row="0" Margin="2,2,2,2"
FontSize="13" FontWeight="Medium"></TextBlock>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="tbName" Property="Foreground" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Problem is, I get compile error : Cannot find the Trigger target tbName.

<Style TargetType="ListBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="2" FontSize="13" FontWeight="Medium">
<TextBlock.Style>
<Style BasedOn="{StaticResource {x:Type TextBlock}}" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}" Value="True">
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

Your code of template is incorrect. You apply ListBoxItem template to ListBox template. Also, you didn't add anything inside ControlTemplate.
I have rewrited it:
<Style x:Key="itemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter x:Name="itemContent"/>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="itemContent" Property="TextBlock.Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ListBox with applied style:
<ListBox ItemContainerStyle="{StaticResource itemStyle}" />

Related

WPF Listview Scrollbar Visibility Trigger

I'm trying to set up a trigger that removes the padding on the listview when the scrollbar is hidden.
I put the trigger on the listview style but I'm getting inconsistent results. For example the background property in the trigger is always active no matter what the scrollbar visibility is.
I've taken a look at the MSDN for the ScrollViewer.ComputedVerticalScrollBarVisibility Property but am not having much luck figuring out what's wrong.
<ListView Grid.Row="1" Grid.Column="1" BorderBrush="{x:Null}" BorderThickness="0" ItemsSource="{Binding Tasks}" Margin="5"
ScrollViewer.CanContentScroll="False" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<!-- SNIP -->
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Style>
<Style>
<Setter Property="ListView.Padding" Value="0,0,5,0"/>
<Setter Property="ListView.Background" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="ScrollViewer.ComputedVerticalScrollBarVisibility" Value="Hidden">
<Setter Property="ListView.Padding" Value="0"/>
<Setter Property="ListView.Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.Style>
</ListView>
I write an ListView style example which worked for me. I tried it.
<Style TargetType="ListView">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<ScrollViewer>
<ScrollViewer.Style>
<Style TargetType="ScrollViewer">
<Style.Triggers>
<Trigger Property="ComputedVerticalScrollBarVisibility" Value="Visible">
<Setter Property="Padding" Value="100"/>
</Trigger>
<Trigger Property="ComputedVerticalScrollBarVisibility" Value="Collapsed">
<Setter Property="Padding" Value="10"/>
</Trigger>
</Style.Triggers>
</Style>
</ScrollViewer.Style>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

ComboxBox Item mouse over color not working

I have a ComboBox with following xaml. Problem is I want the ComboxItem's background to be green when mouse over occurs but it dosen't work. I tried solution posted here ComboBox item color but it dosen't help.
I also tried editing the ComBoxItem's template like in the commented code. But none of the solutions work. Please help.
In the window resources I have the following items defined
<lib:MetroWindow.Resources>
<converter:EnumToVisibilityConverter
x:Key="EnumToVisibility"></converter:EnumToVisibilityConverter>
<x:Array
Type="{x:Type sys:String}"
x:Key="ImageFormatsArray">
<sys:String>Bmp</sys:String>
<sys:String>Png</sys:String>
<sys:String>Jpg</sys:String>
<sys:String>Tif</sys:String>
<sys:String>Gif</sys:String>
</x:Array>
</lib:MetroWindow.Resources>
<ComboBox
x:Name="CmbItems"
HorizontalAlignment="Left"
SelectedIndex="0"
ItemsSource="{StaticResource ImageFormatsArray}"
SelectedValue="{Binding SelectedImageFormat}">
<ComboBox.Resources>
<SolidColorBrush
x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Green" />
</ComboBox.Resources>
<!--<ComboBox.ItemContainerStyle>
<Style
TargetType="{x:Type ComboBoxItem}">
<Setter
Property="Background"
Value="{StaticResource ControlsDarkBackgroundBrush}"></Setter>
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ComboBoxItem}">
<ControlTemplate.Triggers>
<Trigger
Property="IsMouseOver"
Value="true">
<Setter
Property="Background"
Value="{StaticResource ControlsDarkBackgroundBrush}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>-->
<!--<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding}">
<TextBlock.Style>
<Style
TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger
Property="IsMouseOver"
Value="true">
<Setter
Property="Background"
Value="Black"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>-->
</ComboBox>
</StackPanel>
here is a working example, take what you need
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
<StackPanel Background="{TemplateBinding Background}" >
<ContentPresenter></ContentPresenter>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>

Binding WPF DatagridCell to the source

My original datagrid does have a few columns wherein the bound value is bool.[By default this would show up as check boxes]
I have defined a cell template and could create
I would like to use a common datagrid controltemplate for this, like the one defined below.
However it doews not bring in the binding value - it shows up blank.
Could someone help spot me on what I am doing wrong?
<Style x:Key="dgCellBool" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Ellipse>
<Ellipse.Height>10</Ellipse.Height>
<Ellipse.Width>10</Ellipse.Width>
<Ellipse.Style>
<Style TargetType="Ellipse">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Binding}" Value="True">
<Setter Property="Fill" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Binding}" Value="False">
<Setter Property="Fill" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks
Rajesh
You are trying to bind Binding property of DataGridCell but DataGridCell dont have any Binding property. Yoy should set Path=Column.Binding. DataGridCell has Column property which further has Binding Property.
Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Column.Binding}"
I hope this will help.
You need to provide a ContentPresenter to present the content and make sure you add the Border that you will lose from the original Template:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
UPDATE >>>
If you want your Ellipse instead of a Border, just add it back in with a Grid... Ellipse objects cannot have any content:
<Style x:Key="dgCellBool" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Ellipse Height="10" Width="10">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={
RelativeSource TemplatedParent}, Path=Binding}" Value="False">
<Setter Property="Fill" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How do I add different icons to treeview items in a wpf application using xaml?

I have a treeview which has been populated using a dataset. Now I need to add different icons to the treeview nodes. How do I add them using xaml?
You need to add a custom template for the TreeViewItem like this:
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Tag="{Binding}" />
<Image Source="{Binding Converter={StaticResource CustomImagePathConvertor}}" />
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
You can change Image Path and use Template to implement it:
<ToggleButton x:Name="Expander" ClickMode="Press">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid Height="16" Width="16">
<Image x:Name="imgBkg" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Source" TargetName="imgBkg" Value="/XXXX;component/YourImage.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>

Styling TabItem when populated with ItemsSource

I'm using a WPF Tabcontrol populated with a collection using Itemssource.
<TabControl x:Name="_tabControl" ItemsSource="{Binding TabViewModelList}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding TabCaption}"/>
<Setter Property="Content" Value="{Binding TabContent}"/>
<Setter Property="IsSelected" Value="{Binding IsDefault}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
Now I want to set my TabItem-style in my App.xaml(or other resourcefile) like this:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Background="LightBlue"
BorderBrush="Black"
BorderThickness="1,1,1,1"
CornerRadius="6,6,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="LightBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="LightGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
..but the ItemContainerStyle, of course overrides the controltemplate.
How do I combine these two so I can load my tabcontrol dynamically and still be able to style my TabItems the way I want to?
Ok... Solved my own problem. Pretty obvious..
Named my template
<Style TargetType="{x:Type TabItem}" x:Key="TabItemTemplate">
Added a BasedOn property like this:
<Style TargetType="TabItem" BasedOn="{StaticResource TabItemTemplate}">
But if I could combine them into one template please let me know...

Resources