Replacing Treeview +- with Expander - wpf

I am trying to remove the node signs +- from tree view and replace them with Expander. Following is my Xaml:
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Disks}" DataType="{x:Type local1:GenSet}">
<Expander Header="{Binding Genre}" x:Name="exp" IsExpanded="False" >
</Expander>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsExpanded}" Value="True">
<Setter TargetName="exp" Property="IsExpanded" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsExpanded}" Value="False">
<Setter TargetName="exp" Property="IsExpanded" Value="False"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
<!--<TextBlock Text="{Binding Genre}"/>-->
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local1:DiskPrime}">
<TextBlock Text="{Binding Namee}"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
I need to remove the +- icons and get the expander to work. Could you please advice how to get this done. Thank you.

Play with this and modify it to satisfy your needs.
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=Header}">
<ContentPresenter Content="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=Items[0]}"/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
<TreeViewItem Header="Test 1">
<TreeViewItem Header="Child 1"><TextBox Text="Hello"></TextBox></TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Test 2"/>
<TreeViewItem Header="Test 3"/>
</TreeView>

In the ItemContainerStyle set a new Template for the TreeViewItems.

Related

How can I add a Click Event Handler to a DataGrid Context Menu?

How can I add a Click Event Handler to a DataGrid's dynamically-generated ContextMenu?
I see people say use the 'Tag' attribute, but I'm not sure how to add the code in XAML, or whether that needs to be done in the code-behind.
Thanks.
<DataGrid ItemsSource="{Binding MyModules}" AutoGenerateColumns="False" x:Name="dataGrid">
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu ItemsSource="{Binding Configuration.Commands}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Caption}" />
<!-- Instead of the following two lines where I set the CommandAction and CommandParameter, I need to have a Click Event Handler. How can I achieve that? -->
<!-- <Setter Property="Command" Value="{Binding CommandAction}" />
<Setter Property="CommandParameter" Value="{Binding CommandId}" /> -->
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ItemContainerStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Module Name" Width="*" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Configuration.Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Module Caption" Width="3*" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Configuration.Description}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
You could use an EventSetter:
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu ItemsSource="{Binding Configuration.Commands}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Caption}" />
<EventSetter Event="Click" Handler="MenuItem_Click" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Setter.Value>
</Setter>

WPF: Single TreeViewItem bold

I am new to Xaml and somehow i got stuck here. I googled a lot of different approaches but neither did work :-( I hope someone has here has an idea and can help me :-)
With the help of a few tutorials in the internet I got this TreeView. It works like a charme :-)
<TreeView>
<TreeViewItem ItemsSource="{Binding Data.Number}">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Width="15" Margin="5 0 5 0" Source="image.ico"/>
<TextBlock Text="{Binding Data.ID}"/>
<TextBlock Text=" [" Foreground="Blue"/>
<TextBlock Text="{Binding Data.Number.Count}" Foreground="Blue"/>
<TextBlock Text="]" Foreground="Blue"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<TreeViewItem Header="{Binding ItemID}">
<TreeViewItem ItemsSource="{Binding ItemInfo}">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Width="15" Margin="5 0 5 0" Source="image.ico"/>
<TextBlock Text="Items"/>
<TextBlock Text=" [" Foreground="Blue"/>
<TextBlock Text="{Binding ItemInfo.Count}" Foreground="Blue"/>
<TextBlock Text="]" Foreground="Blue"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value.Number}"/>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
<TreeViewItem ItemsSource="{Binding SetInfo}">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Width="15" Margin="5 0 5 0" Source="image.ico"/>
<TextBlock Text="Sets"/>
<TextBlock Text=" [" Foreground="Blue"/>
<TextBlock Text="{Binding SetInfo.Count}" Foreground="Blue"/>
<TextBlock Text="]" Foreground="Blue"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value.ID}"/>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
<TreeViewItem ItemsSource="{Binding GroupInfo}">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Width="15" Margin="5 0 5 0" Source="image.ico"/>
<TextBlock Text="Groups"/>
<TextBlock Text=" [" Foreground="Blue"/>
<TextBlock Text="{Binding GroupInfo.Count}" Foreground="Blue"/>
<TextBlock Text="]" Foreground="Blue"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value.Number}"/>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</TreeViewItem>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</TreeView>
The problem is now that I want the selected item (with mouse click) gets bold. But only the selected item (not items below or above). It doesnt matter on which level the item is.
I tried this a lot of variations but none did work. This two were the best ones but they always select a hole node or just the top node and I couldnt break it down for one single node.
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<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="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TextBlock.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}, FallbackValue=False}" Value="True">
<Setter Property="TextBlock.FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
Can you try this Style?
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="FontWeight" Value="Normal"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.Resources>

Two bindings; One Works, Other Doesn't. Why?

Why does one label update but not the other? Both bound to the same property. I assume there's a problem with the binding being in a dataTemplate? Using Resharper I'm told that my lblOverallInt cannot resolve the symbol. How could I fix this?
<Label Name="lbl1" Content="{Binding Path=lblOverallInt, UpdateSourceTrigger=PropertyChanged}"/>
<Expander>
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Name="lbl2" Content="{Binding Path=lblOverallInt, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
</Expander>
UPDATE
Related follow on question; I have the following style binding also which works when applied to the label but not to the Expander. Is there a similar process for wiring this up as mm8 solution to the top part of this question?
Added separate solution for this part
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=lblOverallInt}" Value="0">
<Setter Property="Foreground" Value="Yellow"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=lblOverallInt, Converter={StaticResource isZeroConverter}}" Value="False">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
The DataContext of the HeaderTemplate is the header itself. Try this:
<Expander>
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Name="lbl2" Content="{Binding Path=DataContext.lblOverallInt, RelativeSource={RelativeSource AncestorType=Expander}}"/>
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
</Expander>
Or this:
<Expander Header="{Binding Path=lblOverallInt}">
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Name="lbl2" Content="{Binding}"/>
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
</Expander>
For part 2 of my question I had the style binding part still attached to the Expander when it actually needed to be included in the DataTemplate;
<Expander.HeaderTemplate>
<DataTemplate>
<Border Height="24">
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Resources>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="0">
<Setter Property="Foreground" Value="Yellow"/>
</DataTrigger>
<DataTrigger Binding="{Binding Converter={StaticResource isZeroConverter}}" Value="False">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
</StackPanel.Style>
<Label>Errors/Warnings:</Label>
<Label Name="lbl2" Content="{Binding}"/>
</StackPanel>
</Border>
</DataTemplate>
</Expander.HeaderTemplate>

How to find out if ComboBox item is in dropdown list or inside it

I want selected item in ComboBox look differently from it's instance in drop down list.
<ComboBox ItemsSource="{Binding ViewList}" SelectedItem="{Binding SelectedView}">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type vm:View}">
<StackPanel Orientation="Horizontal">
<c:Icon x:Name="Icon" IconShape="{DynamicResource z.Users}" Margin="5,0" Background="{Binding Foreground, RelativeSource={RelativeSource Self}}"/>
<StackPanel>
<StackPanel>
<TextBlock x:Name="CurrentView" Text="Current View"
Foreground="{DynamicResource Pallete.Primary.Brighter}"
Visibility="{Binding IsSelected, Converter={StaticResource bool2VisibilityConverter}}"/>
<TextBlock x:Name="Title" Text="{Binding Title}"/>
</StackPanel>
</StackPanel>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="SeparatorView">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="Title" Property="FontWeight" Value="Bold"/>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="YearView">
<Setter TargetName="Icon" Property="IconShape" Value="{DynamicResource z.Bookmark}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
Is there something I could use in CurrentView's Visibility Property or in triggers?
Here is an example of your you could modify the Foreground of a TextBlock when it it is selected in the ComboBox using a DataTrigger:
<ComboBox ItemsSource="{Binding ListOfStrings}">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type sys:String}">
<TextBlock x:Name="txt" Text="{Binding}" Foreground="Red" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" Value="{x:Null}">
<Setter TargetName="txt" Property="Foreground" Value="Green"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
I believe that the following is what you are looking for:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" Value="{x:Null}">

How to apply style trigger to datatemplate in WPF

I've got the following..
<ComboBox Grid.Row="2" Grid.Column="2" Grid.RowSpan="2" ItemsSource="{Binding ShipperAddresses}" Text="{Binding ShipperAddress}" Margin="85,2,0,2">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox AcceptsReturn="True" Width="200" Height="100"/>
<DataTemplate.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="IsReadOnly" Value="True">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=Tag}" Value="False"/>
</Style.Triggers>
</Setter>
</Style>
</DataTemplate.Resources>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The problem is that you can't apply a Style.Trigger like I'm trying to do inside a DataTemplate. So my question is how would you apply create a trigger so that a property on the DataTemplate changes based on the parent?
FINAL SOLUTION:
I took what Souvik gave me and fixed it up since there were a few problems. Here is the end result.
<ComboBox Grid.Row="2" Grid.Column="2" Grid.RowSpan="2" ItemsSource="{Binding ShipperAddresses}" Text="{Binding ShipperAddress}" DisplayMemberPath="Value" Margin="85,2,0,2">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox AcceptsReturn="True" Width="200" Height="100" Text="{Binding Path=Value}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=IsEditable}" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Resources>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="IsEditable" Value="True"/>
<Style.Triggers>
<Trigger Property="IsDropDownOpen" Value="True" >
<Setter Property="IsEditable" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Resources>
Have DataTemplate trigger instead of Style trigger:
<ComboBox Grid.Row="2" Grid.Column="2" Grid.RowSpan="2" ItemsSource="{Binding ShipperAddresses}" Text="{Binding ShipperAddress}" Margin="85,2,0,2">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox AcceptsReturn="True" Width="200" Height="100"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=Tag}" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Resources