HierarchicalDataTemplate TreeviewItem - c#

I have the following xaml:
<TreeView x:Name="tvCategoryList" Grid.Column="0" Padding="0" ItemsSource="{Binding CategoriesList}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding ItemName}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
In the above code i'm binding ObservableCollection CategoriesList where the class CustomTreeItem has a Visibility property. How could i change the above code to bind the Visibility property so that it gets updated everytime (set to either visibile or collapsed) an item gets selected / de-selected?

You would use a style setter to manipulate the visibility of the item.
You use a binding that digs up to the TreeViewItem's selected property:
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding ItemName}">
<TextBlock.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
Value="True">
<Setter Property="TextBlock.Visibility" Value="false" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</HierarchicalDataTemplate>
But this doesn't make it any less counter-intuitive.

Related

Create a ComboBox containing the values of a checked CheckBoxs

I am creating a list of CheckBoxs and a ComboBox that contains the list of checked checkboxes in WPF MVVM application. I don't know how to bind in text of combobox checked values from checkboxes.
Here is what I have tried:
<ComboBox ItemsSource="{Binding Systems}" Grid.Row="4" Grid.Column="1"
IsEditable="True" IsReadOnly="True" Text="{}">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding TemplateName}" IsChecked="{Binding
IsSystemChecked, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This should do the trick:
<StackPanel>
<ListView ItemsSource="{Binding Systems}" >
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding TemplateName}" IsChecked="{Binding
IsSystemChecked, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ComboBox ItemsSource="{Binding Systems}" DisplayMemberPath="TemplateName" >
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSystemChecked}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
</ComboBox.Style>
</ComboBox>
</StackPanel>
Here there is:
ListView containing a checkbox for each item in Systems which is bound to to the IsSystemChecked property
ComboBox containing all of the items in Systems however if the IsSystemChecked property is false the Visibility is set to Collapsed so it is not displayed
Let me know if you have any issues! Hope this helps.

how to show only selected item from treeview in wpf

I am working with a Wpf/XAML based application which has DataGrid with one of the DataGridColumn containing the TreeView control to let user select the item required.
<DataGrid.Columns>
<DataGridTextColumn Header="SerialNumber" Width="*" Binding="{Binding SerialNumber}" />
<DataGridTemplateColumn Header="Field" Width="*">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<uControls:FieldTreeViewControl />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CurrentField.FieldName,Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Field column in above code is the one which displays treeviewcontrol in the DataGrid cell by referencing the FieldTreeViewControl and it works perfectly. The xaml code of FieldTreeViewControl is :
<UserControl>
.......
<Grid>
<TreeView x:Name="MyUITreeView" ItemsSource="{Binding Fields}">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsNodeExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsNodeSelected, Mode=TwoWay}" />
</Style>
<DataTemplate x:Key="NormalTemplate">
<StackPanel Orientation="Horizontal">
<!--<TextBlock Text="-" Margin="3"/>-->
<TextBlock Text="{Binding FieldName}" Margin="3"/>
<StackPanel.ContextMenu>
<ContextMenu Name="myChildMenu" DataContext="{Binding PlacementTarget,RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Field" Command="{Binding DataContext.AddFieldCommand}" CommandParameter="{Binding}">
</MenuItem>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
<!--<DataTemplate x:Key="EditTemplate">
<TextBox Text="{Binding FieldName}"/>
</DataTemplate>-->
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<ContentPresenter Content="{Binding}">
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="ContentTemplate" Value="{StaticResource NormalTemplate}"/>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsNodeSelected,
RelativeSource={RelativeSource
FindAncestor,
AncestorType={x:Type TreeViewItem}}}"
Value="True">
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
Now when user completes selecting an item from treeview I want to collapse treeview to show only that selected item. Later when user wants to change his selection , then the treeview should be available again by clicking on that column/cell. Is that possible to do this in wpf/XAML ? I tried to follow the link but not able to implement it for my scenario.

How can I know if item is selected inside the ItemTemplate?

I have a ListBox that use my custom ItemTemplate. I want to set Visibility property in my TextBlock (inside my template) depending on selected item. I think of doing it using triggers. But how can I know inside my template if current item is selected or not?
<DataTemplate x:Key="myTemplate">
<StackPanel Orientation="Horizontal">
<Image Tag="{Binding priority}" Loaded="SetIconPriority"/>
<Image Tag="{Binding alarm}" Loaded="SetIconAlarm"/>
<!-- I want this TextBlock to be visible only when item is selected -->
<TextBlock Text="{Binding description}"/>
</StackPanel>
</DataTemplate>
edit:
It works, thanks! Code:
<TextBlock Grid.Column="2" Grid.Row="1" Text="{Binding opis}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Using a RelativeSource binding with AncestorType being ListBoxItem.
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True">
(May want to reverse the logic and Collapse on False instead, avoids the default value Setter)

Binding IsEnabled property to items.count

I have the following tree view template :
<TreeView x:Name="counterTree" ItemsSource="{Binding CounterCheckBoxList}" x:FieldModifier="private">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Name="counterTreePanel">
<CheckBox Background="LightBlue"
IsChecked="{Binding IsChecked}" Checked="CounterTreeCheckBoxChecked" Unchecked="CounterTreeCheckBoxUnchecked"
VerticalAlignment="Center" Tag="{Binding Id}" />
<Label Content="{Binding Name }"
Tag="{Binding ParentId}"
Name="counterLabel"
Padding="1,1,1,1" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="False" />
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
The ItemsSource of the TreeView is List<CounterCheckBox>.
CounterCheckBox class has a property as : public List Children.
My requirement was that if this list is empty the 'CheckBox' should not be visible and it there are Children the Checkbox should be visible.How do I bind the count of the list to the Visiblity property of the Checkbox.
Thanks in advance.
You have to use a IValueConverter.

How do I change an image of a node in a WPF treeview when the node is expanded or collapsed?

My Xaml looks like this:
<TreeView Name="mainTree" ItemsSource="{Binding Folders}">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Style.Triggers>
<!-- ??? -->
</Style.Triggers>
</Style>
<HierarchicalDataTemplate DataType="{x:Type local:FolderNode}" ItemsSource="{Binding Children}" >
<StackPanel Orientation="Horizontal" Name="myPanel">
<Image x:Name="treeImg" Width="16" Height="16" Source="Images/vsfolder_closed.png"/>
<TextBlock Text="{Binding Name}" />
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<!-- ??? -->
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Now what I would like is if a treenode is expanded, the image source changes to Images/vsfolder_open.png...
What would be the easiest way to do that?
Thanks in advance!
Add a DataTrigger to the HierarchicalDataTemplate. Since you have two-way binding to the Property IsExpanded in the ViewModel you can bind to it and use TargetName because of the namescope in a DataTemplate.
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding IsExpanded}" Value="True">
<Setter TargetName="treeImg"
Property="Source"
Value="Images/vsfolder_open.png"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>

Categories