wpf TreeViewItem is not selectable - wpf

I've made a TreeView UserControl using this code:
<UserControl x:Class="Company.ObjectInTreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Company"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
x:Name="ObjectInTreeViewControl">
<TreeView ItemsSource="{Binding TreeNodes, ElementName=ObjectInTreeViewControl}" SelectedItemChanged="TreeView_SelectedItemChanged">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="ToolTip" Value="{Binding ToolTipText}"/>
<Setter Property="Background" Value="Transparent"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeNode}" ItemsSource="{Binding Path=Children}">
<TreeViewItem IsSelected="{Binding IsSelected, Mode=TwoWay}" IsExpanded="{Binding IsExpanded, Mode=TwoWay}" Selected="TreeViewItem_Selected" Expanded="TreeViewItem_Expanded" MouseLeftButtonUp="TreeViewItem_MouseLeftButtonUp">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Value}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
only empty space of TreeViewItem is selectable, and the user can't select an item by click on the text of the item
Only the yellow parts are clickable and selectable:
is there anyone to help me find and correct my mistake?

I've found the problem!
I only changed TreeView.Resources like this:
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeNode}" ItemsSource="{Binding Path=Children}">
<Grid>
<TextBlock Text="{Binding Path=Value}"/>
<TreeViewItem Selected="TreeViewItem_Selected" Expanded="TreeViewItem_Expanded" MouseLeftButtonUp="TreeViewItem_MouseLeftButtonUp"></TreeViewItem>
</Grid>
</HierarchicalDataTemplate>
</TreeView.Resources>
Good luck

Related

How to make leftdouble click work on entire treeviewitem area not just on text?

I have a TreeView and i use an ItemTemplate for the Item Bindings similar to this:
<TreeView ItemsSource="{Binding TreeViewItemCollection}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding Command}" CommandParameter="{Binding CommandParameter}"></MouseBinding>
</StackPanel.InputBindings>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
In the Ui it looks something like this :
Now if i doubleclick on the text the command triggers. When i doubleclick on the grey area nothing happens. How can i achieve this behaviour?
Define an ItemContainerStyle that stretches the content and removes the default padding, and then put the StackPanel in an element that adds the padding back:
<TreeView ItemsSource="{Binding TreeViewItemCollection}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem" BasedOn="{StaticResource MaterialDesignTreeViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<Border Background="Transparent" Padding="8">
<Border.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" />
</Border.InputBindings>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding Name}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></TextBlock>
</StackPanel>
</Border>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

How to setup a template for a ListBox with a DataTemplate

So I have the following ListBox defined:
<ListBox Grid.Row="1" Grid.Column="0" x:Name="RawLBControl"
ItemsSource="{Binding ProductionLists.Raw}"
Background="LightGray" BorderThickness="2" BorderBrush="Black">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
There are going to be a number of these, where the only things that changes is the placement (Grid location) and the ItemsSource bindings. Everything else is going to be the same. Question is how do I setup a template so all the ListBoxes use it.
You can define style in application resources and applied it to ListBox later in your code.
<Application x:Class="Q52018469.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyListBoxStyle" TargetType="ListBox">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
Using of this style:
...
<Grid>
...
<ListBox Grid.Row="1" Grid.Column="0" x:Name="RawLBControl"
ItemsSource="{Binding ProductionLists.Raw}"
Style="{StaticResource MyListBoxStyle}" />
</Grid>
...

Avoiding spaces while grouping with listbox

I am using listbox grouping, I want to avoid vertical spaces left between header and subelements, as shown below:
Here is the xaml for the same
<Grid>
<Grid.Resources>
<XmlDataProvider x:Key="Company" XPath="/Company">
<x:XData>
<Company xmlns="">
<Person Name="Jack" Role="CEO"/>
<Person Name="Tim" Role="PL" />
<Person Name="Jil" Role="PL" />
<Person Name="Jimmy" Role="PM" />
<Person Name="Joy" Role="PM" />
<Person Name="Jim" Role="PL" />
<Person Name="Jack" Role="PM" />
</Company>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="categoryTemplate">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Background="ForestGreen" Margin="0,5,0,0"/>
</DataTemplate>
<DataTemplate x:Key="template">
<TextBlock Text="{Binding XPath=#Name}"/>
</DataTemplate>
<CollectionViewSource x:Key="cvs" Source="{Binding Source={StaticResource Company},XPath=Person}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="#Role"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Grid.Resources>
<ListBox Name="lst" ItemTemplate="{StaticResource template}" ItemsSource="{Binding Source={StaticResource cvs}}">
<ListBox.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource categoryTemplate}" />
</ListBox.GroupStyle>
</ListBox>
</Grid>
The ListBox will use GroupItems when you group and they have a default Margin set to 5,0,0,0. Also, ListBoxItem comes with a default Padding of 2,0,0,0. You can change either one, or both, of them like this
<ListBox ...>
<ListBox.Resources>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<ContentPresenter/>
<ItemsPresenter Margin="0,0,0,0"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
<!--...-->
</ListBox>
Check if this is fine for you. Just modified your template bit.
<DataTemplate x:Key="template">
<TextBlock Text="{Binding XPath=#Name}" Margin="-5,0,0,0"/>
</DataTemplate>

CollectionViewSource+PropertyGroupDescription - count of items in a group

In my WPF application I have a CollectionViewSource which is providing a view to a private ObservableCollection. The CollectionViewSource has a PropertyGroupDescription which is utilised in a ListBox to present data to the User's preference.
Using a ControlTemplate containing a Expander Control within the ListBox GroupStyle, the result is quite nice. However, I would like to show the number of items in each group in the Expander Header in addition to the Group Name. Any ideas on the binding path?
Regards,
Liam
<Style x:Key="basicGroupStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Header="{Binding Name}" IsExpanded="True">
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox ItemsSource="{Binding Source={StaticResource myViewSource}}">
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource basicGroupStyle}"/>
</ListBox.GroupStyle>
</ListBox>
you have to use property ItemCount
<Window x:Class="WpfApplication11.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<XmlDataProvider x:Key="data">
<x:XData>
<Animals xmlns="">
<Animal name="Dory" Species="Fish" />
<Animal name="Felix" Species="Cat" />
<Animal name="Fluffy" Species="Dog" />
<Animal name="Jake" Species="Snake" />
<Animal name="Mittens" Species="Cat" />
<Animal name="Murtle" Species="Turtle" />
<Animal name="Nemo" Species="Fish" />
<Animal name="Rex" Species="Dog" />
<Animal name="Rover" Species="Dog" />
<Animal name="Toonces" Species="Cat" />
</Animals>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key="animalsBySpecies" Source="{Binding Source={StaticResource data}, XPath=Animals/Animal}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="#Species" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<DockPanel>
<ScrollViewer DockPanel.Dock="Bottom" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Source={StaticResource animalsBySpecies}}">
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox >
<GroupBox.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text ="{Binding Name}" ></TextBlock>
<TextBlock Text="(" Grid.Column="1" Margin="15,0,0,0"></TextBlock>
<TextBlock Text="{Binding ItemCount}" Grid.Column="1" Margin="20,0,0,0"
HorizontalAlignment="Right" ></TextBlock>
<TextBlock Text=")" Margin="0,0,-5,0" Grid.Column="1
HorizontalAlignment="Right" ></TextBlock>
</Grid>
</GroupBox.Header>
<ItemsPresenter />
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=#name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Window>
I updated the Group Style as follows. I found that I could not use a MultiBinding in the Expander.Header property, nothing was displayed on screen, I needed to include an intermediate TextBlock instead.
<Style x:Key="basicGroupStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name"/>
<Binding Path="ItemCount"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to implement a XAML Radio Button control with an ObservableCollection source?

I have the following ComboBox element in XAML:
<ComboBox ItemsSource="{Binding CollectionControlValues}"
SelectedItem="{Binding CollectionControlSelectedValue, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I would like to implement RadioButtons in the same way, like this:
PSEUDO-CODE:
<RadioButtons ItemsSource="{Binding CollectionControlValues}"
SelectedItem="{Binding CollectionControlSelectedValue, UpdateSourceTrigger=PropertyChanged}">
<RadioButtons .ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</RadioButtons .ItemTemplate>
</RadioButtons >
However, the only WPF RadioButton implementations I can find are static like this.
<StackPanel x:Name="rbHolder1" Style="{StaticResource rbStackPanelStyle}">
<RadioButton Style="{StaticResource rbStyle}">RadioButton 1</RadioButton>
<RadioButton Style="{StaticResource rbStyle}">RadioButton 2</RadioButton>
<RadioButton Style="{StaticResource rbStyle}">RadioButton 3</RadioButton>
<RadioButton Style="{StaticResource rbStyle}">...</RadioButton>
</StackPanel>
How can I create a RadioButton control which is not static like the above but instead gets its data from its ItemsSource property as in the above ComboBox example?
Use ItemsControl and DataTemplate:
<ItemsControl ItemsSource="{Binding CollectionControlValues}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Value}" IsChecked="{Binding SomeProperty}" GroupName="name"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
code in window1.xaml file
<Window x="RadioButton.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local ="clr-namespace:RadioButton"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<StackPanel>
<StackPanel.Resources>
<ObjectDataProvider x:Key="RadioOptions" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:RadioOption" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Style x:Key="RadioButtonList" TargetType="{x:Type ListBox}">
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Background="Transparent">
<RadioButton Focusable="False"
IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}">
<ContentPresenter />
</RadioButton>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ListBox Margin="37,20,28,58" Name="listBox1" Style="{StaticResource RadioButtonList}" ItemsSource="{Binding Source={StaticResource RadioOptions}}" />
</StackPanel>
this line
<ListBox` Margin="37,20,28,58" Name="listBox1" Style="{StaticResource RadioButtonList}"
ItemsSource="{Binding Source={StaticResource RadioOptions}}"
is using itemsource property
C# code
namespace RadioButton
{
public enum RadioOption
{
option1,
option2,
option3,
option4
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
i think this will help you out..

Resources