How to specify Binding XPath using property element syntax? - wpf

I need to apply an XPath Binding for ItemsSource of an HierarchicalDataTemplate. The XPath binding is working correct when applied using property attribute syntax, but in a case, I have very long XPath expression to use and so I thought to apply it using property element syntax.
This is what is working using the Property Attribute Syntax:
<HierarchicalDataTemplate
x:Key="rootTemplate"
ItemsSource="{Binding XPath=./*}">
<StackPanel
Orientation="Horizontal"
VerticalAlignment="Center">
<TextBlock
Margin="5,0,0,0"
Text="{Binding Name}" />
<Image
Source="repeat.ico"
Margin="5 0 0 0"
Width="20"
Height="20"
Visibility="{Binding Converter={StaticResource RepeatToVisiblityConverter}}"></Image>
</StackPanel>
</HierarchicalDataTemplate>
And this is what I am trying to achieve for the same template above, using the Property Element syntax when using the long XPath: [Although I have used the same XPath here in question, but in real it is long]
<HierarchicalDataTemplate
x:Key="rootTemplate">
<HierarchicalDataTemplate.ItemsSource>
<Binding>
<Binding.XPath>
<![CDATA[./*]]>
</Binding.XPath>
</Binding>
</HierarchicalDataTemplate.ItemsSource>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
VerticalAlignment="Center">
<CheckBox
Margin="5,0,0,0" />
<TextBlock
Margin="5,0,0,0"
Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
The ItemsSource becomes empty and nothing is shown when using this syntax for specifying the Binding.
Does anyone know, how to fix this?

The following code works:
It just removes these two lines from above:
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
I will find out later, why removing this works.
<HierarchicalDataTemplate
x:Key="rootTemplate">
<HierarchicalDataTemplate.ItemsSource>
<Binding>
<Binding.XPath>
./*[#Repeat="true" or .//*[#Repeat="true"]]
</Binding.XPath>
</Binding>
</HierarchicalDataTemplate.ItemsSource>
<StackPanel
Orientation="Horizontal"
VerticalAlignment="Center">
<CheckBox
Margin="5,0,0,0" />
<TextBlock
Margin="5,0,0,0"
Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>

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.

Orientating elements in a TreeView

I have a TreeView in my XAML, each element of which is a StackPanel which allows each element to have an image and some text. They are orientated one atop the other as you can see here.
What I would like, and this may not be possible with a TreeView, is for the items (in this case 'FamilyMember') to appear horizontally rather than vertically. So, for example, you click the drop down for the family - you don't see them in a vertical list but in a horizontal one.
The XAML is as follows:
<TreeView Name="trvFamilies">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:Family}" ItemsSource="{Binding Members}">
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource ImageGroup}" Margin="0,0,5,0" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" [" Foreground="Blue" />
<TextBlock Text="{Binding Members.Count}" Foreground="Blue" />
<TextBlock Text="]" Foreground="Blue" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:FamilyMember}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" (" Foreground="Green" />
<TextBlock Text="{Binding Age}" Foreground="Green" />
<TextBlock Text=" years)" Foreground="Green" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
Any attempts made within the DataTemplate element only apply to each of the vertically aligned elements.
Maybe my efforts are on the wrong track if this is my goal. If so, if an alternative panel or control is better than I will gladly use it.
Thanks!

WPF TreeView multiple itemsSource

I want to display the following using a wpf TreeView:
My objects are different, there is no Base class or Interface, I must define a HierarchicalDataTemplate for each item, STOP for example I can add just one ItemSource "Deliveries" but I want to add the pickups also for this stop.
<!-- DELIVERY-->
<DataTemplate x:Key="DeliveryDataTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="DeliveryId" Margin="3,3" />
<TextBlock Text="{Binding DeliveryStatus}" VerticalAlignment="Center" Margin="5" />
<TextBlock Background="{Binding StopStatus, Converter={StaticResource StatusConverter}}" Width="16" Height="16" />
</StackPanel>
</DataTemplate>
<!-- STOP -->
<HierarchicalDataTemplate x:Key="StopTemplate"
ItemsSource="{Binding Deliveries}"
ItemTemplate="{StaticResource DeliveryTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Stop" Margin="3,3" />
<TextBlock Text="{Binding StopId}" Margin="3,3" />
<TextBlock Background="{Binding StopStatus, Converter={StaticResource StatusConverter}}" Width="16" Height="16" Margin="3,3" />
</StackPanel>
</HierarchicalDataTemplate>
<!-- ROUTE -->
<HierarchicalDataTemplate x:Key="RouteTemplate"
ItemsSource="{Binding Stops}"
ItemTemplate="{StaticResource StopTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Route" Margin="5,5" />
<TextBlock Text="{Binding RouteId}" Margin="5,5" />
<TextBlock Background="{Binding RouteStatus, Converter={StaticResource StatusConverter}}" Width="16" Height="16" Margin="5,5" />
</StackPanel>
</HierarchicalDataTemplate>
I have a collection of Routes, each Route has Stops, each Stop has Deliveries and Pickups, each Delivery has its items each item has its own items and so on... How to solve this?
This sounds like a heterogenous datasource problem. I think this solution might be what you are looking for.
I like this answer because it need some very short codes.
WPF Treeview Databinding Hierarchal Data with mixed types
And you might need reading this question to import the System.Windows.Data.ObservableCollection Class. To be short, it can only be imported in a Wpf Library or so, not in a normal .net Class Library.
Cannot Import System.Windows.Data

How to use converters without binding paths?

I have a Combobox whose ItemsSource is an ObservableCollection of int values.
My combobox itemtemplate consists on an image and a textblock which content is given by 2 converters.
How can I set this 2 bindings? The following code does not compile:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding, Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding, Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
You need to remove the , so:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>

How to reuse contents in wpf/mvvm

I have a UI that displays a pattern of "first name/last name". So I thought I would reuse the same template. But I am facing some issues getting the binding right.
Note:-
PrimaryContactDataContext is nothing but a class, with a property named "value" which implements the *INotifyPropertyChanged" interface.
<StackPanel>
<ContentControl DataContext="{Binding Path=PrimaryContactDataContext.Value,Mode=TwoWay}" ContentTemplate="{StaticResource PersonalDetailsTemplate}" />
</StackPanel>
// See the Reusable template below
<UserControl.Resources>
<DataTemplate x:Key="PersonalDetailsTemplate" >
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Width="30" Text="Name"></TextBlock>
<TextBox Width="110" Text="{Binding LastName}" IsReadOnly="True"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Width="30" Text="Title"></TextBlock>
<TextBox Width="110" Text="{Binding firstName}" IsReadOnly="True"></TextBox>
</StackPanel>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
Set the Content of the ContentControl, not its DataContext:
<ContentControl Content="{Binding Path=PrimaryContactDataContext.Value,Mode=TwoWay}" ContentTemplate="{StaticResource PersonalDetailsTemplate}" />

Resources