WPF Xaml Custom Styling Selected Item Style in a ListBox - wpf

I have a ListBox that scrolls images horizontally.
I have the following XAML I used blend to create it. It originally had a x:Key on the Style TaregetType line, MSDN said to remove it, as I was getting errors on that. Now I'm getting this error:
Error 3 Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.
I don't understand how to apply all of this junk that way, I've tried several things, nothing is working.
My goal is to have the selected item's background be white, not blue. Seems like a lot of work for something so small!
Thanks.
<ListBox ItemsSource="{Binding Source={StaticResource WPFApparelCollection}}"
Grid.Row="1" Margin="2,26,2,104" ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Hidden" SelectionMode="Single"
x:Name="list1" MouseLeave="List1_MouseLeave" MouseMove="List1_MouseMove" Style="{DynamicResource ListBoxStyle1}" >
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
<Setter Property="Background" TargetName="Bd" Value="#FFFFFFFF"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
Orientation="Horizontal"
IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Image}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Wrap the Style Tag with an ItemContainerStyle as below:
<ListBox ItemsSource="{Binding Source={StaticResource WPFApparelCollection}}"
Grid.Row="1" Margin="2,26,2,104"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
SelectionMode="Single"
x:Name="list1" MouseLeave="List1_MouseLeave" MouseMove="List1_MouseMove"
Style="{DynamicResource ListBoxStyle1}" >
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
</Style>
<!-- the rest of your code, but close the ItemContainerStyle -->
</ListBox.ItemContainerStyle>
</ListBox>

I tried the above solution but it didnt worked as expected so I found another way to solve my problem which is to disable selection for listbox
this is what I did
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>

Related

WPF ListView with GridView styling ListViewItem

Ok I started to post a question but in the midst of posting I had an idea that turned out to fix it... I'm posting with an answer in case it saves someone else some frustration.
I'm trying to make a custom style for ListViewItem and within a ListView that has a GridView. Here is my style:
<Style x:Key="StListViewItemBase" 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="Cursor" Value="Hand" />
<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 Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
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 BrSelectableItemHover}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False"/>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd"
Value="{StaticResource BrSelectableItemHover}"/>
</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 I have a ListView like this:
<ListView ItemsSource="{Binding Tabs}" ItemContainerStyle="{StaticResource StListViewItemBase}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="test">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:SampleObject}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="test 2">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:SampleObject}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
however, when I run it I get the columns, but in the items list it just gives 'TestApp.SampleObject' readout for each item, and not even in each column, just once for each. If I remove the item container style it works as it should.
So I generated this style by going into Blend, creating a ListViewItem, and editing a copy of the template. However it turns out the template is different if it's inside a GridView than if it isn't... I had to create a ListView with a GridView, THEN a ListViewItem inside it and then edit that style. Here is the revised style that works:
<Style x:Key="StListViewItemBase" TargetType="{x:Type ListViewItem}">
<Setter Property="TextElement.FontFamily" Value="Resources/#Artifakt Element Light" />
<Setter Property="FontSize" Value="11pt" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="5,2,5,2"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{StaticResource BrDarkText}" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="true">
<Border x:Name="InnerBorder" BorderThickness="1" CornerRadius="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="11"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle x:Name="UpperHighlight" Fill="#75FFFFFF" Visibility="Collapsed"/>
<GridViewRowPresenter Grid.RowSpan="2"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource BrSelectableItemHover}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="{StaticResource BrSelectableItemHover}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hopefully that saves someone else some frustration...

Make listboxitem unselectable

I'm writing an small key application and I'm using a listbox to dynamically visualise a list from code. Now the issue is it needs to be used on windows 7 and I'm having multiple issues with the visualisation on that platform.
The code I have is:
<ListBox x:Name="listBoxSecrets" Margin="0,84,10,10" Background="{x:Null}"
HorizontalContentAlignment="Stretch" BorderBrush="{x:Null}" >
<ListBox.ItemTemplate>
<DataTemplate>
<!--<Border BorderBrush="#FFF3560D" CornerRadius="3" BorderThickness="3" Margin="0,0,0,10">-->
<Border BorderBrush="White" CornerRadius="10" BorderThickness="10" Margin="0,0,0,10">
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<StackPanel Uid="{Binding Path=ID}" Grid.Row="0" Grid.Column="0">
...
</StackPanel>
<Button ... Grid.Row="0" Grid.Column="2">
...
</Button>
<Button ... Grid.Row="0" Grid.Column="3" >
...
</Button>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
I tried the following style to no effect:
<Window.Resources>
<Style x:Key="{x:Type ListBox}" TargetType="{x:Type ListBox}">
<Setter Property="Focusable" Value="False" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</Window.Resources>
This is how the selection looks - I don't want it to be selectable. (I have the same issue with the buttons btw - same solution would be applicable?)
Before:
After click:
Also: Bonus points if you can help me figure out how to remove the "aliasing" line between the grid and the border around it.. ;-; Only happens on the win 7 mahcine, not my win 8 machine.
I guess you want to remove the selection state of ListBoxItem, if thats right, Please use the below style,
in this i have commented out the triggers responsible for selection and mouse over state.
You can assign this style in ItemContainerStyle of ListBox,,
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>
<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 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 ListBoxItem}">
<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}"/>
</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>
Why don't you remove the selection upon happening? Like this:
private void listBoxSecrets_SelectionChanged(object sender, EventArgs e)
{
listBoxSecrets.SelectedIndex = -1;
}
You then setup the listener like this:
<ListBox x:Name="listBoxSecrets" Margin="0,84,10,10" Background="{x:Null}"
HorizontalContentAlignment="Stretch" BorderBrush="{x:Null}" SelectionChanged="listBoxSecrets_SelectionChanged" >

WPF Listview button set color?

I have a listview bound to a vm collection. The listview contains buttons, and what I'm trying to achieve is that when the user presses a button, it simply changes color. However, I can't figure out how to do this. Any help would be greatly appreciated.
<ListView
x:Name="GridControlOrders"
SelectionMode="Single"
ItemsSource="{Binding Orders}"
SelectedItem="{Binding Sale}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource StyleButtonOrders}">
<Grid>
<TextBlock Text="{Binding DisplayData}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap" />
</Grid>
</Button>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="PreviewMouseDown" Handler="ItemOnPreviewMouseDown" />
<EventSetter Event="PreviewMouseUp" Handler="ItemOnPreviewMouseUp" />
<Setter Property="Width" Value="{Binding Source={x:Static p:Settings.Default}, Path=CardViewCardWidthItem, Mode=TwoWay}" />
<Setter Property="Height" Value="{Binding Source={x:Static p:Settings.Default}, Path=CardViewCardHeightItem, Mode=TwoWay}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource StyleScrollBarTouchscreenNarrow}"/>
</ListView.Resources>
</ListView>
<Style TargetType="{x:Type Button}" x:Key="StyleButtonTouchscreen" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template" Value="{StaticResource ButtonTouchControlTemplate}"/>
</Style>
<ControlTemplate x:Key="ButtonTouchControlTemplate" TargetType="{x:Type ButtonBase}">
<Border x:Name="border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" TargetName="border" Value="Red"/>
<Setter Property="BorderBrush" TargetName="border" Value="Red"/>
</Trigger>
<Trigger Property="Button.IsDefaulted" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border" Value="Orange"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Did you just want to create a listview with buttons that change color when the item (or button) is clicked? You can take advantage of the IsSelected property of the ListViewItem
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="DataContext" Value="{Binding}" />
<Setter Property="Height" Value="30" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border Background="Transparent" >
<Button x:Name="button" HorizontalAlignment="Left" Width="150" Content="{Binding DisplayData}" IsHitTestVisible="False"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="button" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
Also, set SelectionMode="Single" on the ListView if you want only one button at a time to change background or SelectionMode="Multiple" if you want buttons at a time to change background when clicked.

Change Fill property of Path control inside ListBox

I have a small question, I've created a ListBox that only contains 2 items. Each item is a Path control that has a Fill attribute set to Black.
Now, what I'm trying to do is, change the colour of this Fill attribute when you select one of the items in the listbox... I would think this should be done with a Style. But when doing so, the style contains a ContentPresenter that maps to the Path and this ContentPresenter has no Fill attribute to change through the IsSelected trigger!
So in other words, how can I still use a Style that maps the Fill attribute?
My current XAML code of the Window in the WPF project:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="XAMLPathStyleProblem.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<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="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" 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="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ListBox x:Name="ImageBar" ItemContainerStyle="{DynamicResource ListBoxItemStyle}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>
<Path Data="M15.992466,14.680105C20.892824,14.680104 23.97299,17.360288 28.013305,17.360288 31.943504,17.360288 34.333683,14.680104 39.994102,14.680105 44.274425,14.680104 48.804641,17.000391 52.034961,21.0308 41.454162,26.831151 43.174373,41.942682 53.865043,45.983101 52.394974,49.24342 51.694851,50.703518 49.794819,53.583672 47.154625,57.614079 43.424389,62.624561 38.803959,62.664604 34.703705,62.704647 33.643696,59.994431 28.073246,60.024464 22.50292,60.054249 21.342806,62.714657 17.23254,62.674614 12.622241,62.634571 9.0819604,58.104115 6.441766,54.083717 -0.95864094,42.822647 -1.7287129,29.611443 2.8315349,22.590761 6.0717456,17.600301 11.19209,14.680104 15.992466,14.680105z M38.751411,0C39.321331,3.8093758 37.761547,7.538764 35.701835,10.178331 33.502144,12.997869 29.702673,15.197509 26.033186,15.077528 25.373277,11.438125 27.093038,7.6887398 29.172746,5.1591539 31.462427,2.3696117 35.39188,0.23996067 38.751411,0z"
Fill="Black" />
</ListBoxItem>
<ListBoxItem>
<Path Data="M32.127438,4.0459317E-05C34.679321,-0.0059787218,51.370113,0.63573532,60.553993,18.050023L60.522991,18.050023 60.543671,18.086075C61.200066,19.24132 68.004066,31.93957 59.575981,47.967091 59.575981,47.967091 51.176838,64.148377 30.558096,63.870453L29.65756,63.847004 29.649204,63.861397C29.644096,63.870198,29.641504,63.874661,29.641504,63.874661L29.638971,63.874695 29.681444,63.800747C30.804413,61.84562,39.865662,46.068413,42.345753,41.710415L42.378082,41.653572 42.392643,41.638874 42.472183,41.501145 42.692501,41.246766C44.087284,39.55642,45.09919,37.538369,45.595421,35.325478L45.613995,35.233231 45.681602,34.931549C45.857914,34.084336,45.977459,33.046578,45.939392,31.839535L45.927822,31.607016 45.927765,31.604247 45.927345,31.597495 45.913135,31.311926 45.901112,31.172703 45.89138,31.015126 45.867527,30.783802 45.865814,30.76396 45.8638,30.747662 45.831325,30.432713C45.783504,30.046782,45.720222,29.665644,45.64212,29.289938L45.605244,29.129017 45.579826,29.001641C45.3101,27.769034 44.871658,26.423209 44.200989,24.977549 43.870582,24.491171 43.539108,24.000555 43.182049,23.514327L42.899601,23.140976 60.287002,18.042616C60.287002,18.042616,39.292564,18.022913,34.351002,18.039915L34.393581,18.050023 34.172077,18.050023C33.849613,18.050023,33.54248,18.050023,33.252323,18.050023L33.158501,18.050023 32.880497,18.023783C32.497307,17.992794 32.109821,17.977 31.718649,17.977 31.350422,17.977 30.985464,17.990992 30.624279,18.018473L30.292705,18.050023 30.278829,18.050023C30.225145,18.050023 30.197481,18.050023 30.197481,18.050023 30.197481,18.050023 30.175093,18.049284 30.131918,18.049599 29.747402,18.052403 27.714258,18.138693 25.166611,19.573328L25.156681,19.579142 25.090729,19.612418C22.198151,21.138638,19.8955,23.632718,18.613605,26.663617L18.496868,26.959704 5.5749997,14.177C5.5749997,14.177,15.021078,30.765849,17.85829,35.692574L17.988001,35.917668 18.035503,36.093228C19.728666,42.05547 25.213291,46.422997 31.718649,46.422997 32.332252,46.422997 32.936783,46.384125 33.529907,46.308712L33.816097,46.268658 29.596954,63.874993 29.542429,63.874833C28.213777,63.865578 13.814976,63.407895 4.1510181,48.093563 4.1510176,48.093563 -5.6624084,32.728032 4.8882693,15.012328L5.3907794,14.192161 5.3934535,14.187385C5.6228327,13.780242 13.109029,0.74591898 31.796461,0.0057129142 31.796461,0.0057133239 31.911178,0.00055203911 32.127438,4.0459317E-05z"
Fill="Black" />
</ListBoxItem>
</ListBox>
</Grid>
</Window>
I recommend you using MVVM pattern with MVVM Light Toolkit. Then you should create Collection of data that you want to dispaly on the list. In your case it can be Data and Fill (Color). Then you need to handled Click event and that's all. I have code that provides such feature, so If you want it, please ask.
But in your case (without MVVM Light toolkit) I would rather do sth like this:
<Style x:Key="Path" TargetType="{x:Type Path}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource, AncestorType={x:Type ListBoxItem}}, Path=IsSelected" Value="True">
<Setter Property="Fill" Value="YouColor"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource, AncestorType={x:Type ListBoxItem}}, Path=IsSelected" Value="False">
<Setter Property="Fill" Value="YouAnotherColor"/>
</DataTrigger>
</Style.Triggers>
</Style>
Best regards.
Mateusz
Ok... found the answer myself!
When changing the Fill value inside the Path control to a binding one, all works as expected!
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"

Can I have a Treeview without the tree structure?

Can someone tell me how I can template a treeview control so that it doesn't look like a tree? Basically, I want to remove the indents at various levels as well as the +/- that allow for expansion and collapse.
The actual requirement is that I have a hierarchical data template that is bound to an object collection that is recursive in nature. And I want to display these objects on screen in a flat manner. The best solution would be to get the hierarchical data template to work with an itemscontrol. But sadly, i believe that the itemscontrol does not understand hierarchical templates. So I am forced to use a treeview control and strip all the "tree" features.
Any suggestions will be mighty helpful..
You need to modify the TreeViewItem's template. I already did it for you, just copy/paste code below in your Window. Although I extremely recommend you study ControlTemplates and how to modify them since if you're gonna be using WPF. It's EXTREMELY useful.
Here you go:
<Window.Resources>
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
<SolidColorBrush x:Key="GlyphBrush" Color="#444" />
<!-- TreeView -->
<Style x:Key="{x:Type TreeView}" TargetType="TreeView">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<Border
Name="Border"
CornerRadius="1"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1">
<ScrollViewer
Focusable="False"
CanContentScroll="False"
Padding="4">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- TreeViewItem -->
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="0,0,0,0"
StrokeThickness="5"
Stroke="Black"
StrokeDashArray="1 2"
Opacity="0"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Name="Bd"
Grid.Column="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Visibility="Visible"
Grid.Row="1"
Grid.Column="0"/>
</Grid>
<ControlTemplate.Triggers>
<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="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TreeView>
<TreeViewItem Header="Node 1">
<TreeViewItem Header="Node 1.1">
<TreeViewItem Header="Node 1.1.1" />
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Node 2">
<TreeViewItem Header="Node 2.1">
<TreeViewItem Header="Node 2.1.1" />
</TreeViewItem>
<TreeViewItem Header="Node 2.2">
<TreeViewItem Header="Node 2.2.1" />
</TreeViewItem>
</TreeViewItem>
</TreeView>
</Grid>
</Window>
You can check out this and this article that show how to completely change the rendering of a treeview:
You could probably do this with a template, but if the data doesn't need to be in a hierarchy then it makes more sense to flatten it in the ViewModel - possibly using AutoMapper.

Resources