WPF: Binding to selected TreeViewItem - wpf

I have a TreeView that is built on an XML file and contains a text and an image in each TreeViewItem.
Also, I have a TextBlock and an Image, that I want to bound to the selected TreeViewItem.
How can I do this?
Here is my XAML:
<Window.Resources>
<HierarchicalDataTemplate DataType="Node" ItemsSource ="{Binding XPath=ChildNode}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding XPath=#Image}"/>
<TextBlock Text="{Binding XPath=#Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="ChildNode" ItemsSource ="{Binding XPath=GrandchildNode}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding XPath=#Image}" />
<TextBlock Text="{Binding XPath=#Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="GrandchildNode">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding XPath=#Image}" />
<TextBlock Text="{Binding XPath=#Name}" />
</StackPanel>
</DataTemplate>
<XmlDataProvider x:Key="xmlNodeList" Source="XMLFile1.xml" XPath="Root"/></Window.Resources><StackPanel>
<TreeView Name="treeView1" ItemsSource="{Binding Source={StaticResource xmlNodeList}, XPath=Node}" />
<TextBlock />
<Image /></StackPanel>
And here is an XML data:
<Root>
<Node Name="AAA" Image="images/1.ico" />
<Node Name="BBB" Image="images/2.ico">
<ChildNode Name="bbb 1" Image="images/3.ico">
<GrandchildNode Name="b 1.1" Image="images/4.ico"/>
<GrandchildNode Name="b 1.2" Image="images/5.ico"/>
<GrandchildNode Name="b 1.3" Image="images/6.ico"/>
</ChildNode>
<ChildNode Name="bbb 2" Image="images/7.ico"/>
<ChildNode Name="bbb 3" Image="images/8.ico">
<GrandchildNode Name="b 3.1" Image="images/9.ico"/>
<GrandchildNode Name="b 3.2" Image="images/10.ico"/>
</ChildNode>
<ChildNode Name="bbb 4" Image="images/11.ico"/>
</Node>
<Node Name="CCC" Image="images/12.ico">
<ChildNode Name="ccc 1" Image="images/13.ico">
<GrandchildNode Name="c 1.1" Image="images/14.ico"/>
<GrandchildNode Name="c 2.2" Image="images/15.ico"/>
</ChildNode>
</Node></Root>

If you stick you TextBlock & Image inside another StackPanel to make it a bit easier you can do:
<StackPanel DataContext="{Binding ElementName=treeView1, Path=SelectedItem}">
<TextBlock Text="{Binding XPath=#Name}" />
<Image Source="{Binding XPath=#Image}" />
</StackPanel>

Related

Getting selected item from Treeview

I have a TreeView and want to get the selected item from it.
The Treeview itself is populated not manually, but from data in the code. Since it is populated this way, I'm not sure how to get information out of it.
Here is the XAML:
<TreeView Name="trvFamilies" HorizontalAlignment="Left" Margin="10,10,3,3" Width="340">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:Scene}" ItemsSource="{Binding Characters}">
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="New" Click="MenuItem_Click"></MenuItem>
<MenuItem Header="Remove" Click="MenuItem_Click_1"></MenuItem>
</ContextMenu>
</StackPanel.ContextMenu>
<Image Source="{StaticResource ImageSceneRegular}" Margin="0,0,5,0" Width="64" Height="64"/>
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" [" Foreground="Blue" />
<TextBlock Text="{Binding Characters.Count}" Foreground="Blue" />
<TextBlock Text="]" Foreground="Blue" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:Character}">
<Border BorderThickness="1" Background="AliceBlue" CornerRadius="8,8,3,3">
<StackPanel Orientation="Horizontal" Margin="4" Background="White">
<Image Source="{Binding Img}" Margin="0,0,5,0" Width="64" Height="64" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" (" Foreground="Green" />
<TextBlock Text="{Binding Age}" Foreground="Green" />
<TextBlock Text=" years)" Foreground="Green" />
</StackPanel>
</Border>
</DataTemplate>
</TreeView.Resources>
</TreeView>
It is populated by data from an ObservableCollection which is populated within the code and then assigned to the ItemSource of the treeview (and it works fine).
So let's say I had a TextBlock which sat outside the TreeView and wanted to populate it with information from the selected Character (that's the type which populates the drop down part of the TreeView), I don't know how to do that, be it using XAML only or code behind.
Any help on how to do this would be very much appreciated.

WPF - MVVM Treeview get selected item [duplicate]

This question already has answers here:
Data binding to SelectedItem in a WPF Treeview
(21 answers)
Closed 6 years ago.
‘SelectedItem’ property is read-only and cannot be set from markup. How i can get selected item?
<TreeView x:Name="TreeView1"
ItemsSource="{Binding Path=Champ}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:SimpleChampionship}" ItemsSource="{Binding Path=Tours}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:SimpleTourClient}" ItemsSource="{Binding Path=Matches}">
<StackPanel Orientation="Horizontal" >
<TextBlock Text="Tour:" />
<TextBlock Text="{Binding Path=NameTour}" />
<TextBlock Text=" Matches [" />
<TextBlock Text="{Binding Path=Matches.Count}" />
<TextBlock Text="]" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:SimpleMatchClient}">
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=Home}" />
<TextBlock Text="{Binding Path=HomeTeamGoals}" />
<TextBlock Text=" - " />
<TextBlock Text="{Binding Path=GuestTeamGoals}" />
<TextBlock Text="{Binding Path=Guest}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
example treeview
Need return selected SimpleMatchClient
Try this. It should work.
var treeViewItem = TreeView1.ItemContainerGenerator.ContainerFromItem(SelectedItem) as TreeViewItem;

WPF Databinding ListView with ComboBox Selected Item Issue

I have a databound ComboBox where I cannot seem to set the SelectedItem. I have tried SelectedValue/SelectedValuePath, but have having difficulties.
To explain the scenario, I have a parent ListView which contains ComboBoxes w/in the ListViewItems. The parent ListView and the child ComboBox have the same datasource, but display different data. For example, Extension 2 references Extension 1. In this case I am trying to illustrate that 2 mirrors one. The user needs to be able to change which Extension it points to, itself or any of the others. Other than that it is very simple, but almost have it.
Here the example which you can run from your favorite xaml editor.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<XmlDataProvider x:Key="xmlDataProvider">
<x:XData>
<Extensions xmlns="">
<Extension>
<ExtId>1</ExtId>
<ExtName>Extension 1</ExtName>
<ExtValue>1</ExtValue>
</Extension>
<Extension>
<ExtId>2</ExtId>
<ExtName>Extension 2</ExtName>
<ExtValue>1</ExtValue>
</Extension>
<Extension>
<ExtId>3</ExtId>
<ExtName>Extension 3</ExtName>
<ExtValue>3</ExtValue>
</Extension>
<Extension>
<ExtId>4</ExtId>
<ExtName>Extension 4</ExtName>
<ExtValue>4</ExtValue>
</Extension>
</Extensions>
</x:XData>
</XmlDataProvider>
<!-- Extensions -->
<CollectionViewSource
x:Key="CollectionViewSourceExtensions"
Source="{Binding Source={StaticResource xmlDataProvider}, XPath=Extensions/Extension}" />
</Page.Resources>
<Grid>
<ListView
ItemsSource="{Binding
Source={StaticResource CollectionViewSourceExtensions},
Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding XPath=ExtName}" />
<TextBlock Text=" - " />
<TextBlock Text="{Binding XPath=ExtValue}" />
</StackPanel>
<ComboBox
SelectedItem="{Binding XPath=ExtId}"
ItemsSource="{Binding
Source={StaticResource CollectionViewSourceExtensions},
Mode=OneTime}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=ExtId}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
Was a simple resolution that took a good deal of time to finally figure out...
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<XmlDataProvider x:Key="SamplePeople">
<x:XData>
<Extensions xmlns="">
<Exension>
<Id>1</Id>
<Name>Line Key 1</Name>
<Value>1</Value>
</Exension>
<Exension>
<Id>2</Id>
<Name>Line Key 2</Name>
<Value>1</Value>
</Exension>
<Exension>
<Id>3</Id>
<Name>Line Key 3</Name>
<Value>3</Value>
</Exension>
<Exension>
<Id>4</Id>
<Name>Line Key 4</Name>
<Value>4</Value>
</Exension>
</Extensions>
</x:XData>
</XmlDataProvider>
</Page.Resources>
<Grid>
<ListBox x:Name="PeopleListBox"
DataContext="{Binding Source={StaticResource SamplePeople}}"
ItemsSource="{Binding Mode=Default, XPath=/Extensions/node()}"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding XPath=Name}" />
<TextBlock Text=" is " />
<ComboBox
SelectedValue="{Binding XPath=Value}"
ItemsSource="{Binding Mode=Default, XPath=/Extensions/Exension/Id}" >
</ComboBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Page>

How to select UI Elements within a custom data template for a listbox item in Silverlight

Hello all I have a usercontrol that I have defined as a data template. What I trying to do is have the results returned in a wrap panel and have each result returned in a tile format. I have this all working and the resutls are returned properly. However I have within the data template items that I would like the user to click upon. (scrollviewer to scroll data, buttons to click and text to select)/ Currently when you click on the selected item the item is selected but it is as if everything inside the listbox item is locked ( not selectable).
I'd appreciate any suggestions as to what I am missing here. Listed below is my code for the user controls and how I reference the wrap panel from app.xaml
SearchResultTileControl.xaml
<UserControl x:Class="UI.Search.Controls.SearchResultTileControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dts="clr-namespace:UI.Search.Commands"
xmlns:formatter="clr-namespace:UI.Search.Commands"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:qr="clr-namespace:UI.Search.Controls.tiles"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot" >
<ListBox x:Name="ResultListBox"
HorizontalAlignment="Stretch"
Background="{x:Null}"
BorderThickness="0"
HorizontalContentAlignment="Stretch"
ItemsPanel="{StaticResource ResultsItemsControlPanelTemplate}"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
ItemsSource="{Binding SearchResults[0].Results}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<formatter:TypeTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch">
<!-- Person Template -->
<formatter:TypeTemplateSelector.PersonTemplate>
<DataTemplate>
<qr:ucTilePerson />
</DataTemplate>
</formatter:TypeTemplateSelector.PersonTemplate>
<!-- Incident Template -->
<formatter:TypeTemplateSelector.IncidentTemplate>
<DataTemplate>
<qr:ucTileIncident />
</DataTemplate>
</formatter:TypeTemplateSelector.IncidentTemplate>
</formatter:TypeTemplateSelector>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Within the Usercontrol ucTilePerson.xaml I have the template setup as:
<UserControl x:Class="UI.Search.Controls.tiles.ucTilePerson"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:formatter="clr-namespace:UI.Search.Commands"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
Width="300"
Height="250"
d:DesignHeight="250"
d:DesignWidth="300"
IsHitTestVisible="False"
mc:Ignorable="d">
<UserControl.Resources>
<formatter:TileHighlightConverter x:Key="FormatConverter" />
</UserControl.Resources>
<Grid x:Name="PersonLayoutRoot">
<Rectangle Style="{StaticResource TileBackground}" />
<ScrollViewer Margin="5" BorderBrush="{x:Null}">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Margin="0,0,0,2" Orientation="Horizontal">
<StackPanel>
<Image Width="48"
Height="48"
Source="/Images/search/person.png" />
<TextBlock Style="{StaticResource TileRelevance}" Text="{Binding Relevance}" />
</StackPanel>
<StackPanel>
<HyperlinkButton Content="{Binding Type}" Style="{StaticResource TypeHyperlinkButton}" />
<TextBox Margin="0,0,0,2"
Style="{StaticResource TileTextBox}"
Text="{Binding Content[AgencyName]}"
TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
<toolkit:WrapPanel Margin="0,0,0,2">
<TextBlock Style="{StaticResource TileLabel}" Text="Name" />
<TextBox Margin="0,0,3,0"
Style="{StaticResource TileTextBox}"
Text="{Binding Content[lastname]}" />
<TextBox Margin="0,0,3,0"
Style="{StaticResource TileTextBox}"
Text="{Binding Content[firstname]}" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[middlename]}" />
</toolkit:WrapPanel>
<Border Style="{StaticResource TileBorder}">
<toolkit:WrapPanel Orientation="Horizontal">
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Race" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[race]}" />
</StackPanel>
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Sex" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[sex]}" />
</StackPanel>
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="DOB" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[dob]}" />
</StackPanel>
</toolkit:WrapPanel>
</Border>
<Border Style="{StaticResource TileBorder}">
<toolkit:WrapPanel Orientation="Horizontal">
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Involvement" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[involvementtype]}" />
</StackPanel>
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Associated Event" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[0].EventAssociation}" />
<HyperlinkButton Content="{Binding Content[0].EventID}" Style="{StaticResource TileResultLink}" />
</StackPanel>
</toolkit:WrapPanel>
</Border>
<Border Style="{StaticResource TileBorder}">
<ContentControl Width="256"
Margin="0,0,6,0"
BorderThickness="0"
Content="{Binding HitContext,
Converter={StaticResource FormatConverter}}"
FontSize="11" />
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
And then I set reference to the wrap panel used in the listboxt ItemsPanel in my app.xaml
<ItemsPanelTemplate x:Key="ResultsItemsControlPanelTemplate">
<toolkit:WrapPanel/>
</ItemsPanelTemplate>
I suspect this is something in the Listbox styles that may be preventing this but I am not positive.
Thanks again for any suggestions,
Cheers
Discovered the issue. Within the usercontrol (ucTilePerson) I had IsHitTestVisible set to false. Since it was set at the user control level all elements inherited this property which is why I was getting the effect of not being able to raise any mouse events on anything.
No idea why I set that there other than it was late in the day.
Cheers

WPF : InputBindings on a StackPanel

I want to put a command on a ListBoxItem. The ListBoxItem use a DataTemplate composed of a StackPanel (containing an Image and a TextBlock, both using Binding). I want that the doubleclick on that ListBoxItem fire the command.
I have tried this :
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False">
</StackPanel>
</DataTemplate>
I have also tried to put the Command Resources on a StackPanel containing this StackPanel, without any change.
I am certain of my binding because when I put the InputBindings part on the TextBlock, it works.
Thanks
Try handling the event in the ListBox instead of the StackPanel:
<ListBox>
<ListBox.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</ListBox.Resources>
<ListBox.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</ListBox.InputBindings>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox>
My code finally looks like this :
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
Thanks anyway, Mr Poulin.

Resources