I've got a custom style with a template for tree view items. I want the items presenter to display content in the width and height of the grid row that it is in and leave scrolling up to the child control. This works... sort of. The child does do the scrolling, but the height is for some reason set to the parent's height (tree view) this messes up the scrolling. I've copied the code below.
<Style TargetType="TreeViewItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Name="Bd" Background="LightGray" BorderBrush="Black" Grid.Row="0"
BorderThickness="1" Padding="{TemplateBinding Padding}">
<Grid Margin="5,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1"
Fill="{StaticResource GlyphBrush}" Data="M 0 4 L 16 4 L 8 12 Z" Grid.Column="0"/>
<Label Grid.Column="1" x:Name="PART_Header" Content="{TemplateBinding Header}" FontSize="18" FontWeight="Bold"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Grid>
</Border>
<ItemsPresenter Name="ItemsHost" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
<Setter Property="Data" TargetName="ExpandPath" Value="M 8 0 L 16 8 L 8 16 Z"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="ExpandPath" Property="Visibility" Value="Collapsed"/>
</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 Property="IsExpanded" Value="True"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="IsExpanded" Value="False"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<Style TargetType="{x:Type TreeViewItem}">
</Style>
</Style.Resources>
</Style>
I figured out a way to do this in C# by setting the width and height of the child element when the selection changed.
Related
I'm at my wits end over this, I've spent the better part of the last two days playing with it and googling. When I mouseover my TreeView it works as expected, until you get over the Expander/text at this point a different background and border brush are applied. I've gone silly into trying to eliminate this and nothing at all seems to work. My last overkill attempt below still left me with no idea what is going on.
I assume it's something simple that is just flying over my head, and I know this silly amount of triggers is not required.
As requested, here's a screenshot Issue
And what is desired is the effect that you see where the text is blue and the background is transparent. The background and border brush when over the expander is not wanted
<TreeView x:Name="textureTreeView" ItemsSource="{Binding Category}" Margin="0" SelectedItemChanged="textureTreeView_SelectedItemChanged" Background="#00000000" BorderBrush="{x:Null}" Foreground="#00000000" IsTextSearchEnabled="True">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local1:CategoryViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" IsHitTestVisible="False"/> <!-- This eliminated the text from causing the issue -->
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Foreground" Value="#FFA1A1A1"/>
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#FFFFFFFF"/>
</Trigger>
<Trigger Property="Expander.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="Grid.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="StackPanel.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="TextBlock.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="ItemsPresenter.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="Path.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsMouseOver" Value="true"/>
<Condition Property="ToggleButton.IsChecked" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsMouseOver" Value="true"/>
<Condition Property="ToggleButton.IsChecked" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Update: Thanks to #Gui's suggestion I've managed to drill down farther into exactly what is happening. There is an unnamed Border that is pulling template properties that is applying the style.
I've already tried removing all my style templates, I have no idea where this is being pulled from, and while I'm now working on it, I'm having a very difficult time addressing the border itself to set a different style.
Update: For the life of me I can't get this border to take a styling, it doesn't seem to be part of any of the control templates I've downloaded.
I got it working!
I tried like a million things, and no templates or setters would stick. Finally I put the control template directly into the treeviewitem's style with an override setter, and it worked. I'm having one small issue with getting the expander fill colour to set on the treeviewitem's mouseover, but this isn't a huge issue for me.
In Resources:
<SolidColorBrush x:Key="GlyphBrush" Color="#FFA1A1A1" />
<Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
<Setter Property="Foreground" Value="#FFFFFF"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid Width="15" Height="13" Background="Transparent">
<Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" Fill="{StaticResource GlyphBrush}" Data="M 4 0 L 8 4 L 4 8 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="0,0,0,0" StrokeThickness="5" Stroke="#FF717171" StrokeDashArray="1 2" Opacity="0"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then in the page:
<TreeView x:Name="textureTreeView" ItemsSource="{Binding Category}" SelectedItemChanged="textureTreeView_SelectedItemChanged" Background="#00000000" BorderBrush="{x:Null}" Foreground="#00000000" IsTextSearchEnabled="True">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local1:CategoryViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" IsHitTestVisible="False"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style 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="#FFA1A1A1"/>
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" 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}">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#FFFFFFFF"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Border.Background" Value="#00000000"/>
<Setter Property="Background" Value="#00000000"/>
<Setter Property="BorderBrush" Value="#00000000"/>
<Setter Property="Foreground" Value="#FF58A6C3"/>
</Trigger>
<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 Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#ffffffff"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<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>
</TreeView.ItemContainerStyle>
</TreeView>
This is my Model:
ObservableCollection<Student> StudentsList;
class Student
{
static ObservableCollection<Student> Students;
string SName;
String FName;
}
And i have simple Combobox:
<ComboBox
x:Name="cbStudents"
ItemsSource="{Binding StudentsList}">
I case i want to hide from my Combobox item/items, is it possible to do that without using the function Remove from my Students ObservableCollection ?
Edit:
After try mm8 solution it seems that my combo box style i cause my error so this is my style:
<!-- region combobox style -->
<SolidColorBrush x:Key="ComboBoxNormalBorderBrush" Color="Transparent" />
<SolidColorBrush x:Key="ComboBoxNormalBackgroundBrush" Color="#FF103766" />
<SolidColorBrush x:Key="ComboBoxDisabledForegroundBrush" Color="#888" />
<SolidColorBrush x:Key="ComboBoxDisabledBackgroundBrush" Color="#FF7AA0CD" />
<SolidColorBrush x:Key="ComboBoxDisabledBorderBrush" Color="#FF7AA0CD" />
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border
Name="Border"
Padding="5"
Margin="0"
BorderThickness="0"
CornerRadius="0"
Background="Transparent"
BorderBrush="Transparent" >
<TextBlock TextAlignment="Left">
<ContentPresenter />
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true"/>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsHighlighted" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="White"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#FF103766"/>
<Setter TargetName="Border" Property="Background" Value="#FF103766"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="false"/>
<Condition Property="IsSelected" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="White"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#FF103766"/>
<Setter TargetName="Border" Property="Background" Value="#FF103766"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true"/>
<Condition Property="IsSelected" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="White"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#FF103766"/>
<Setter TargetName="Border" Property="Background" Value="#FF103766"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="false"/>
<Condition Property="IsSelected" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="#FF103766"/>
<Setter TargetName="Border" Property="BorderBrush" Value="White"/>
<Setter TargetName="Border" Property="Background" Value="White"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate TargetType="ToggleButton" x:Key="ComboBoxToggleButtonTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border
Grid.ColumnSpan="2"
Name="Border"
BorderBrush="{StaticResource ComboBoxNormalBorderBrush}"
CornerRadius="0"
BorderThickness="1, 1, 1, 1"
Background="{StaticResource ComboBoxNormalBackgroundBrush}" />
<Border
Grid.Column="1"
Margin="1, 1, 1, 1"
BorderBrush="#444"
Name="ButtonBorder"
CornerRadius="0, 0, 0, 0"
BorderThickness="0, 0, 0, 0"
Background="{StaticResource ComboBoxNormalBackgroundBrush}" />
<Path
Name="Arrow"
Grid.Column="1"
Data="M 0 0 L 8 12 L 16 0 Z"
HorizontalAlignment="Center"
Fill="#444"
VerticalAlignment="Center"
Margin="-10,0,0,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="Panel.Background" TargetName="ButtonBorder" Value="Transparent"/>
<Setter Property="Shape.Fill" TargetName="Arrow" Value="White"/>
<Setter Property="Panel.Background" TargetName="Border" Value="#FF7AA0CD"/>
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="False">
<Setter Property="Shape.Fill" TargetName="Arrow" Value="Transparent"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Panel.Background" TargetName="ButtonBorder" Value="Transparent"/>
<Setter Property="Shape.Fill" TargetName="Arrow" Value="White"/>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="Panel.Background" TargetName="Border" Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/>
<Setter Property="Panel.Background" TargetName="ButtonBorder" Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/>
<Setter Property="Border.BorderBrush" TargetName="ButtonBorder" Value="{StaticResource ComboBoxDisabledBorderBrush}"/>
<Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
<Setter Property="Shape.Fill" TargetName="Arrow" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ComboBoxFlatStyle" TargetType="{x:Type ComboBox}">
<Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
<Setter Property="FrameworkElement.OverridesDefaultStyle" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="TextElement.Foreground" Value="Gainsboro"/>
<Setter Property="FrameworkElement.FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="False"
IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Template="{StaticResource ComboBoxToggleButtonTemplate}"/>
<ContentPresenter
Name="ContentSite"
Margin="5, 4, 23, 3"
IsHitTestVisible="False"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding ComboBox.SelectionBoxItem}"
ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
<TextBox
Name="PART_EditableTextBox"
Margin="3, 3, 23, 3"
IsReadOnly="{TemplateBinding IsReadOnly}"
Visibility="Hidden"
Background="Transparent"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Focusable="True" >
<TextBox.Template>
<ControlTemplate TargetType="TextBox" >
<Border Name="PART_ContentHost" Focusable="False" />
</ControlTemplate>
</TextBox.Template>
</TextBox>
<Popup
Name="Popup"
Placement="Bottom"
Focusable="False"
AllowsTransparency="True"
IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}"
PopupAnimation="Fade">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"
MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}">
<Border
Name="DropDownBorder"
Background="Gainsboro"
Margin="0, 0, 0, 0"
CornerRadius="0"
BorderBrush="#FF103766"
BorderThickness="1" />
<ScrollViewer Margin="4" SnapsToDevicePixels="True">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
<!-- Popup showing items -->
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="TextElement.Foreground" Value="White"/>
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="False">
<Setter Property="TextElement.Foreground" Value="Gainsboro"/>
</Trigger>
<Trigger Property="ItemsControl.HasItems" Value="False">
<Setter Property="FrameworkElement.MinHeight" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" Value="Gainsboro"/>
</Trigger>
<Trigger Property="ItemsControl.IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
</Trigger>
<Trigger Property="ComboBox.IsEditable" Value="True">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
<Setter Property="UIElement.Visibility" TargetName="PART_EditableTextBox" Value="Visible"/>
<Setter Property="UIElement.Visibility" TargetName="ContentSite" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- endregion of Flat ComboBox -->
You could use an ItemContainerStyle with a DataTrigger to for example hide a Student with a particular name, e.g.:
<ComboBox
x:Name="cbStudents"
ItemsSource="{Binding StudentsList}">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding SName}" Value="SomeName">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Edit: (see the comments below) "ComboBoxFlatStyle" is a ComboBox style. The ItemContainerStyle should be based on the implicit ComboBoxItem style:
<ComboBox Style="{StaticResource ComboBoxFlatStyle}" ...>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
...
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
you need CollectionViewSource and filter delegate
#region feed items
private ObservableCollection<OpdsItemBase> _FeedItems = new ObservableCollection<OpdsItemBase>();
public ICollectionView FeedItemView
{
get
{
return CollectionViewSource.GetDefaultView(_FeedItems);
}
}
#endregion
and
public string FilterText
{
get { return _filterText; }
set
{
_filterText = value;
FeedItemView.Filter = delegate(object obj)
{
if (string.IsNullOrEmpty(_filterText))
return true;
OpdsItemBase data = obj as OpdsItemBase;
if (data == null)
return false;
return (data.Title.IndexOf(_filterText, 0, StringComparison.InvariantCultureIgnoreCase) > -1);
};
}
}
I have a ContextMenu that I want to override its style.
This is how it looks like:
All the SubMenus should look the same as the first one (with the White Highlighted Background)
Here's the XAML:
<ContextMenu>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
</MenuItem>
</MenuItem>
</MenuItem>
</MenuItem>
<MenuItem Header="Lol"/>
</ContextMenu>
Here's the Style of my ContextMenu:
<SolidColorBrush x:Key="ContextMenuMenuItemBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ContextMenuSubMenuBorderBrush" Color="#CCCEDB"/>
<SolidColorBrush x:Key="ContextMenuSubMenuBackground" Color="#F6F6F6"/>
<Color x:Key="ContextMenuSubMenuDropShadowColor">#808080</Color>
<SolidColorBrush x:Key="ContextMenuTransitionBackground" Color="#E7E8EC"/>
<SolidColorBrush x:Key="ContextMenuMenuItemHighlightedBackground" Color="#EFEFF2"/>
<SolidColorBrush x:Key="ContextMenuSubmenuItemBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ContextMenuSubmenuItemBackgroundHighlighted" Color="#FFFFFF"/>
<SolidColorBrush x:Key="ContextMenuArrowPanelBackgroundHighlighted" Color="#007ACC"/>
<SolidColorBrush x:Key="ContextMenuMenuDisabledForeground" Color="#A2A4A5"/>
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Grid Margin="0,0,5,5">
<Border x:Name="SubMenuBorder" BorderBrush="#CCCEDB" BorderThickness="1" Background="#F6F6F6" SnapsToDevicePixels="True" Padding="2">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" />
<Border.Effect>
<DropShadowEffect Color="#808080" Opacity="0.60" ShadowDepth="3"/>
</Border.Effect>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<!--Border 1-->
<Border x:Name="Border" Background="{StaticResource ContextMenuMenuItemBackground}" BorderThickness="1" SnapsToDevicePixels="True">
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
<ColumnDefinition x:Name="Col3" Width="14"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon"/>
<ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" x:Name="HeaderHost" RecognizesAccessKey="True" ContentSource="Header" VerticalAlignment="Center"/>
<ContentPresenter Grid.Column="2" Margin="8,1,8,1" x:Name="IGTHost" ContentSource="InputGestureText" VerticalAlignment="Center"/>
<Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
<Path x:Name="ArrowPanelPath" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
</Grid>
<Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" HorizontalOffset="-1" x:Name="SubMenuPopup" Focusable="False" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" AllowsTransparency="True">
<Grid Margin="0,0,5,5">
<!--Border 2-->
<Border x:Name="SubMenuBorder" BorderBrush="{StaticResource ContextMenuSubMenuBorderBrush}" BorderThickness="1" Background="{StaticResource ContextMenuSubMenuBackground}" SnapsToDevicePixels="True">
<Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True" Margin="2">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
<Border.Effect>
<DropShadowEffect Color="{StaticResource ContextMenuSubMenuDropShadowColor}" Opacity="0.60" ShadowDepth="3"/>
</Border.Effect>
</Border>
<!--Border 3-->
<Border Margin="1,0,0,0" x:Name="TransitionBorder" BorderBrush="{StaticResource ContextMenuTransitionBackground}" BorderThickness="1" Background="{StaticResource ContextMenuTransitionBackground}" SnapsToDevicePixels="True" Width="0" Height="2" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Padding" Value="6,0,6,2"/>
<Setter TargetName="SubMenuPopup" Property="Placement" Value="Bottom"/>
<Setter TargetName="Col0" Property="MinWidth" Value="0"/>
<Setter TargetName="Col3" Property="Width" Value="Auto"/>
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="IGTHost" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ArrowPanel" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="SubMenuBorder" Property="BorderThickness" Value="1,1,1,1"/>
<Setter TargetName="SubMenu" Property="Margin" Value="2,3,2,2"/>
<Setter TargetName="TransitionBorder" Property="Width" Value="{Binding ActualWidth, ElementName=Grid}"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="6,0,6,2"/>
<Setter TargetName="Col0" Property="MinWidth" Value="0"/>
<Setter TargetName="Col3" Property="Width" Value="Auto"/>
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="IGTHost" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="ArrowPanel" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="10,3,0,3"/>
<Setter TargetName="Border" Property="MinHeight" Value="22"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackground}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="10,3,0,3"/>
<Setter TargetName="Border" Property="MinHeight" Value="22"/>
<Setter TargetName="ArrowPanel" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="TopLevelHeader"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuMenuItemHighlightedBackground}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="TopLevelItem"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuMenuItemHighlightedBackground}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="SubmenuHeader"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackgroundHighlighted}"/>
<Setter TargetName="ArrowPanelPath" Property="Fill" Value="{StaticResource ContextMenuArrowPanelBackgroundHighlighted}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="SubmenuItem"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackgroundHighlighted}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSubmenuOpen" Value="True"/>
<Condition Property="Role" Value="TopLevelHeader"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackground}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource ContextMenuSubMenuBorderBrush}"/>
</MultiTrigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource ContextMenuMenuDisabledForeground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
Whats wrong here?
Why is this happening?
I got it to work but just using your MenuItem Style directly. I got rid of everything else except
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<!--Border 1-->
<Border x:Name="Border" Background="{StaticResource ContextMenuMenuItemBackground}" BorderThickness="1" SnapsToDevicePixels="True">
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
<ColumnDefinition x:Name="Col3" Width="14"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon"/>
<ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" x:Name="HeaderHost" RecognizesAccessKey="True" ContentSource="Header" VerticalAlignment="Center"/>
<ContentPresenter Grid.Column="2" Margin="8,1,8,1" x:Name="IGTHost" ContentSource="InputGestureText" VerticalAlignment="Center"/>
<Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
<Path x:Name="ArrowPanelPath" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
</Grid>
<Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" HorizontalOffset="-1" x:Name="SubMenuPopup" Focusable="False" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" AllowsTransparency="True">
<Grid Margin="0,0,5,5">
<!--Border 2-->
<Border x:Name="SubMenuBorder" BorderBrush="{StaticResource ContextMenuSubMenuBorderBrush}" BorderThickness="1" Background="{StaticResource ContextMenuSubMenuBackground}" SnapsToDevicePixels="True">
<Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True" Margin="2">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
<Border.Effect>
<DropShadowEffect Color="{StaticResource ContextMenuSubMenuDropShadowColor}" Opacity="0.60" ShadowDepth="3"/>
</Border.Effect>
</Border>
<!--Border 3-->
<Border Margin="1,0,0,0" x:Name="TransitionBorder" BorderBrush="{StaticResource ContextMenuTransitionBackground}" BorderThickness="1" Background="{StaticResource ContextMenuTransitionBackground}" SnapsToDevicePixels="True" Width="0" Height="2" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Padding" Value="6,0,6,2"/>
<Setter TargetName="SubMenuPopup" Property="Placement" Value="Bottom"/>
<Setter TargetName="Col0" Property="MinWidth" Value="0"/>
<Setter TargetName="Col3" Property="Width" Value="Auto"/>
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="IGTHost" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ArrowPanel" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="SubMenuBorder" Property="BorderThickness" Value="1,1,1,1"/>
<Setter TargetName="SubMenu" Property="Margin" Value="2,3,2,2"/>
<Setter TargetName="TransitionBorder" Property="Width" Value="{Binding ActualWidth, ElementName=Grid}"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="6,0,6,2"/>
<Setter TargetName="Col0" Property="MinWidth" Value="0"/>
<Setter TargetName="Col3" Property="Width" Value="Auto"/>
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="IGTHost" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="ArrowPanel" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="10,3,0,3"/>
<Setter TargetName="Border" Property="MinHeight" Value="22"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackground}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="10,3,0,3"/>
<Setter TargetName="Border" Property="MinHeight" Value="22"/>
<Setter TargetName="ArrowPanel" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="TopLevelHeader"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuMenuItemHighlightedBackground}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="TopLevelItem"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuMenuItemHighlightedBackground}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="SubmenuHeader"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackgroundHighlighted}"/>
<Setter TargetName="ArrowPanelPath" Property="Fill" Value="{StaticResource ContextMenuArrowPanelBackgroundHighlighted}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="Role" Value="SubmenuItem"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackgroundHighlighted}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSubmenuOpen" Value="True"/>
<Condition Property="Role" Value="TopLevelHeader"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{StaticResource ContextMenuSubmenuItemBackground}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource ContextMenuSubMenuBorderBrush}"/>
</MultiTrigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource ContextMenuMenuDisabledForeground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(I left the Brushes...)
To apply it only to the context menu in question...
<ContextMenu>
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"/>
......
</Style>
</ContextMenu.Resources>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
<MenuItem Header="blabla">
<MenuItem Header="Lol"/>
</MenuItem>
</MenuItem>
</MenuItem>
</MenuItem>
<MenuItem Header="Lol"/>
</ContextMenu>
I have the following style defined for a TreeViewItem:
<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" />
<Setter Property="AllowDrop" Value="True" />
<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 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" Height="1" Stroke="#8888" Margin="10,0,0,0" SnapsToDevicePixels="true"/>
<Rectangle x:Name="VerLn" Width="1" Stroke="#8888" Grid.RowSpan="2" SnapsToDevicePixels="true"/>
<ToggleButton x:Name="Expander"
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}">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"/>
</Grid>
<ControlTemplate.Triggers>
<!-- This trigger changes the connecting lines if the item is the last in the list -->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource LineConverter}}" Value="true">
<Setter TargetName="VerLn"
Property="Height"
Value="6"/>
<Setter TargetName="VerLn"
Property="VerticalAlignment"
Value="Top"/>
</DataTrigger>
<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="{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>
I cannot get TreeViewItem to expand, when IsExpanded property of the model is set to true in code behind. However, model IsExpanded property changes when TreeViewItem is expanded from user interface. What am I missing?
Thanks.
I have similar code working, the setting you have above looks fine.
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
Did you raise a PropertyChanged event once you updated the IsExpanded property in your model?
How to hide the expand/collpse sign for leaf nodes in a WPF TreeView?
In other words: how to make leaf nodes automatically expand?
Any way to achive this using XAML?
Thanks,
Similar to other answers, to Expand all nodes you can just use
<TreeView >
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
This will make all TreeViewItems automatically Expand. However, you'll still see the Expand/Collapse ToggleButton. To get rid of that one you'll have to re-template TreeViewItem like this
<TreeView ...
ItemContainerStyle="{StaticResource TreeViewItemExpandedStyle}">
And the Style (pretty much Xaml)
<Style x:Key="TreeViewItemExpandedStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="IsExpanded" Value="True"/>
<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="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 MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" IsEnabled="False" Visibility="Hidden" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<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="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.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
<Style x:Key="ExpandCollapseToggleStyle" 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}">
<Border Background="Transparent" Height="16" Padding="5,5,5,5" Width="16">
<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="Transparent" Stroke="#FF989898">
<Path.RenderTransform>
<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="ExpandPath" Value="#FF1BBBFA"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="Transparent"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="RenderTransform" TargetName="ExpandPath">
<Setter.Value>
<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
</Setter.Value>
</Setter>
<Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
<Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Bind the TreeViewItems to an ObservableCollection and leave the ObservableCollection empty. That way the expand/collapse sign is not shown since the UI knows there is nothing to expand. Here is the relevant part from some of my code:
XAML:
<TreeView x:Name="TreeView"
ItemsSource="{Binding TopLevelNodes}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.Resources>
<HierarchicalDataTemplate
DataType="{x:Type local:ViewModel}" ItemsSource="{Binding Children}">
ViewModel:
ObservableCollection<ObjectBaseViewModel> _children;
public ObservableCollection<ObjectBaseViewModel> Children
{
get
{
if (_children == null)
_children = new ObservableCollection<ViewModel>();
return _children;
}
}
I don't know about a pure XAML solution but you could bind the IsExpanded property of the TreeviewItem and have this property on your leaf nodes set to true by default (you don't have to have this property at all on other nodes.
<Style TargetType="controls:TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"></Setter>
</Style>
Firstly set IsExpanded to true
<Style x:Key="{x:Type TreeViewItem}"
TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded"
Value="True" />
Then hide the Expander
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<ControlTemplate.Triggers>
<Trigger Property="HasItems"
Value="false">
<Setter TargetName="Expander"
Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="HasItems"
Value="true">
<Setter TargetName="Expander"
Property="Visibility"
Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
A very good reason to use a treeview rather than a datagrid with rowdetails is that the up and down arrow keys traverse from expanded details to header details seamlessly.