Binding IsEnabled property to items.count - c#

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.

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.

wpf TreeView HierarchicalDataTemplate related

I have a question related to HierarchicalDataTemplate. Is it possible to keep adding HierarchicalDataTemplate via code or there is no way to do that. I'm asking this because in my case later i don't know if i will need more child nodes than these i have now.
below you can see my treeview:
<TreeView Background="#FFF0F0F0" BorderBrush="#FFE5E2DB" IsEnabled="{Binding isAllesEnabled}" ItemsSource="{Binding LijstRechten, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Margin="0,0,0,0" Name="dgStamOverzichtGebruikerRechten" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemTemplate>
<!-- Top Level -->
<HierarchicalDataTemplate ItemsSource="{Binding Childs}">
<CheckBox IsChecked="{Binding isChecked}" Content="{Binding naam}" />
<!-- 1st Child Level -->
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Childs}">
<CheckBox IsChecked="{Binding isChecked}" Content="{Binding naam}" />
<!-- 2nd Child Level -->
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Childs}">
<CheckBox IsChecked="{Binding isChecked}" Content="{Binding naam}" />
<!-- 3rd Child Level -->
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding isChecked}" Content="{Binding naam}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="Margin" Value="2"/>
<!--<Setter Property="IsSelected" Value="{Binding isSelected, Mode=TwoWay}"/>
<EventSetter Event="Selected" Handler="TreeViewSelectedItemChanged" />-->
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Thanks in advance!
For your problem, assuming all the childs are of same type.. just define one HierarchicalDataTemplate in your window's resources without any x:key and put the DataType which is type of your Child object...Your whole tree will populate..
<HierarchicalDataTemplate DataType="{local:YourParentType}"
ItemsSource="{Binding Childs}">
<CheckBox IsChecked="{Binding isChecked}" Content="{Binding naam}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{local:YourChildType}"
ItemsSource="{Binding Childs}">
<CheckBox IsChecked="{Binding isChecked}" Content="{Binding naam}" />
</HierarchicalDataTemplate>
here assuming local is the namespace (xmlns) in which your Child class is defined

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>

HierarchicalDataTemplate TreeviewItem

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.

Categories