I want to bind data to radtreeview through Hireachical Data Template. With Wpf treeview Its working. We wanted to change that to Radtreeview. When i am trying to achieve the same i am not getting that.
<TreeView Name="treeview2"
Grid.RowSpan="2" Tag=""
Grid.ColumnSpan="2"
ItemContainerStyle="{StaticResource StretchTreeViewItemStyle}" ItemsSource="{Binding Path=Cluster}" Width="250" Height="251" Margin="0,0,0,0" DockPanel.Dock="Bottom">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Nodes}">
<DockPanel LastChildFill="True">
<TextBlock Padding="15,0,30,0" Text="{Binding Path=numitems}" TextAlignment="Right" DockPanel.Dock="Right"/>
<TextBlock Text="{Binding Path=Text}" DockPanel.Dock="Left" TextAlignment="Left">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Rename" />
<MenuItem Header="Exlcude"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DockPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
I am looking for a sample which shows that bind a property. Cluster is a observablecollection property of type a class. Nodes is a child collection with in that. I am looking for transforming the same code to radtreeview-- Thanks
Related
I have a task to use a contextmenu in treeview and pass selected treeview's item to ViewModel by clicking on contextmenu element.
Here is my xaml:
<Window.Resources>
<HierarchicalDataTemplate x:Key="Ufps"
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" />
<TextBlock Margin="5 0 0 0" Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
........
........
<TreeView x:Name="TrvUfpsDictionary" Height="222" Canvas.Left="25"
Canvas.Top="280" Width="545"
Background="AliceBlue"
ItemsSource="{Binding Path=Ufps, Mode=OneWay}"
ItemTemplate="{StaticResource Ufps}">
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Element"
cal:Message.Attach="[Event Click] = [Action AddElement(TrvUfpsDictionary.SelectedItem)]"
/>
................
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
........
<Button Content="Test" Canvas.Left="475" Canvas.Top="568" Width="75"
cal:Message.Attach="[Event Click] = [Action AddElement(TrvUfpsDictionary.SelectedItem)]"/>
And here is simple ViewModel's code:
public class UserSettingsViewModel : PropertyChangedBase
{
..........
public void AddElement(object selectedItem)
{
MessageBox.Show("Element added! "+selectedItem.?GetHashCode());
}
..........
}
Now I've stuck with it. When I've selected treeview's item and then I've pressed the "Test" button - it works fine, it pass the selected item to "AddElement" in my VM. BUT when I do the same with contextmenu - it always pass null. Did I miss something?
EDIT
I've made a simple app with the problem described. https://github.com/whizzzkey/WpfApp1
You might have to move the Context Menu further into the TreeView, into the Item Template and add Context Menu to the Label/TextBlock you have in nodes.
For example, consider the following Employee tree (emulating since I do not know your data structure),
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Positions}" >
<Label Content="{Binding DepartmentName}"/>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Employees}" >
<Label Content="{Binding PositionName}"
Tag="{Binding DataContext, ElementName=TestControl}" >
<Label.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element"
cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"/>
</ContextMenu>
</Label.ContextMenu>
</Label>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<Label Content="{Binding EmployeeName}"
Tag="{Binding DataContext, ElementName=TestControl}">
<Label.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element"
cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
</ContextMenu>
</Label.ContextMenu>
</Label>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
There are couple of important points to note here. Since your method exists in ViewModel and you have to ensure that the DataContext is pointing to your ViewModel instead of the Item Type that is bound to node.
For this, you need can make use of cal:Action.TargetWithoutContext. The following line the Label definition ensure we have access to the View's DataContext.
Tag="{Binding DataContext, ElementName=TestControl}"
While the following line ensures the we get our bindings right (to ViewModel). TestControl is the x:Name for your UserControl
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
Finally the Click Action would be modified as following.
cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"
This would ensure your ViewModel's Action is called with the right parameter passed.
Update
Based on your comment and code,following are the changes required.
Window Definition : Add x:Name
<Window
x:Class="WpfApp1.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
Title="XmlData Tree Test"
x:Name="TestControl"
Width="250"
Height="350">
Root Hierarchical Template
Associating Item source with Tag is placed on the TextBlock, also the Relative Source has Self.
<HierarchicalDataTemplate DataType="root" ItemsSource="{Binding XPath=./*}" >
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0" Text="ROOT"
Tag="{Binding DataContext, ElementName=TestControl}">
<TextBlock.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element"
cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
Hierarchical Template for Node
<HierarchicalDataTemplate
DataType="Node"
ItemsSource="{Binding XPath=./*}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0" Text="Node:" />
<TextBlock Margin="5,0,0,0"
Tag="{Binding DataContext, ElementName=TestControl}"
Text="{Binding XPath=#name}" >
<TextBlock.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element"
cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
Output Example,
For Root
For Node,
I want a DataTemplate for ListBox having the ItemsSource as Collection of Borders. Inside each Border i want to display another ListBox containg set of some items having its own ItemsSource.
But, when i try to acheive this structure i am not able to populate any data.
My XAML code -
<Grid x:Name="RightPanel" Grid.Column="2" Background="Beige">
<Border BorderBrush="Black" Margin="4" BorderThickness="1.5">
<ScrollViewer Margin="2" Focusable="False">
<ListBox x:Name="MainRightListBox" ItemsSource="{Binding ListBoxCollection,Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<ListBox x:Name="ChildListBox" ItemsSource="{Binding CurrentPage.ClonedVectorImages,Mode=TwoWay}" SelectedItem="{Binding ImageVectorSelected}" BorderBrush="Transparent" Background="Transparent">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="canvas" Background="Transparent" Orientation="Horizontal" Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete" CommandParameter="{Binding}"
Command="{Binding PlacementTarget.Tag.DataContext.DeleteCloneCommand, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}, Mode=FindAncestor}}"/>
</ContextMenu>
</StackPanel.ContextMenu>
<Viewbox Width="35" Height="35" >
<Canvas Width="35" Height="35">
<Canvas>
<Path Fill="#ffda2526" Data="F1 M 0.000,112.500 C 0.000,50.369 50.368,0.000 112.500,0.000 C 174.632,0.000 225.000,50.369 225.000,112.500 C 225.000,174.633 174.632,225.000 112.500,225.000 C 50.368,225.000 0.000,174.633 0.000,112.500 Z" Height="30.667" Stretch="Fill" Width="31"/>
<TextBlock x:Name="tb1" Text="{Binding CountId}" Foreground="WhiteSmoke" FontSize="20" FontFamily="Arial Bold" Height="20" RenderTransformOrigin="1.588,1.224" Canvas.Left="9.322" Canvas.Top="3.335"></TextBlock>
</Canvas>
</Canvas>
</Viewbox>
<TextBox Text="Enter Text Here" Height="20" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Border>
</Grid>
"Can a DataTemplate be placed inside another DataTemplate of different Template Structure?"
The answer is yes, it can. Your XAML structure is fine.
But what possibly wrong is binding path/expression used. You need to be aware that DataContext of the inner ListBox (the one inside DataTemplate) is corresponding item in ListBoxCollection. So if that item mentioned before has property CurrentPage.ClonedVectorImages, this way of binding should work fine to populate the inner ListBox :
<ListBox x:Name="ChildListBox"
ItemsSource="{Binding CurrentPage.ClonedVectorImages,Mode=TwoWay}"
........>
You need to put DataTemplates in resources with the corresponding keys, because otherwise an exception may occur:
Markup.IStyle.Connector.Connect error
This is bug of studio, which is described as follows link:
A good way to look at this problem “Templating is like parentheses, quoting parentheses” the Template XAML is not created but saved and run later. The bug is therefore: We have a problem with nested parentheses.
In any case as I think, should be avoided nesting templates and use him via resources, it will be easier and clearer.
Trying to add a context menu to a TreeView with just xaml code.
Tv Show
Season 1
Season n
The context menu should only show when I right click a Season node.
Is that possible? I know how to solve it with code behind, but I'd like to learn to use WPF as it is intended. I have trouble finding out if I should be able to solve this with using only xaml.
Current xaml:
<TreeView
Grid.Row="1"
Grid.Column="0"
ItemsSource="{Binding TvShows}" x:Name="TvShowsTreeView"
SelectedItemChanged="TvShowsTreeViewOnSelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="tvShows:TvShow" ItemsSource="{Binding Seasons}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Try using the ItemTemplate property of HierarchicalDataTemplate. It should look like this:
<HierarchicalDataTemplate DataType="tvShows:TvShow" ItemsSource="{Binding Seasons}">
<TextBlock Text="{Binding Name}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate DataType="TypeOfSeasonInYourApplication">
<TextBlock Text="{Binding Name}">
<TextBlock.ContextMenu>
<ContextMenu>
<!-- Place MenuItems here -->
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
I actually didn't test that myself so please let me know if that works or not.
I have my xaml code as :
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<toolkit:ToggleSwitch Name="toggle3" Header="{Binding name}" Height="120" HorizontalAlignment="Left" Margin="35,20,0,0" VerticalAlignment="Center" Width="440" Content="{Binding descrip}" Checked="toggleSwitch1_Checked" Unchecked="toggleSwitch1_Unchecked" Tap="toggleSwitch1_Tap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
Now i want to retrieve toggleswitch(toggle 3)'s header text in c# code. How can that be done?
When you create a data binding like you did, it should automatically update the variable you bound it to, name
Assuming you have a proper collection to serve as the ItemsSource Binding
the xaml would write as follows:
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0" ItemsSource="{Binding Path=ItemsCollection}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<toolkit:ToggleSwitch Name="toggle3" Header="{Binding Name,Mode=TwoWay}" Height="120" HorizontalAlignment="Left" Margin="35,20,0,0" VerticalAlignment="Center" Width="440" Content="{Binding descrip}" Checked="toggleSwitch1_Checked" Unchecked="toggleSwitch1_Unchecked" Tap="toggleSwitch1_Tap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You'll have to provide a property named ItemsCollection of type IEnumerable<TModel> in your DataContext
where TModel class shouldcontain Name property
This should put you on the right path to access elements inside of ItemTemplate.Probably that's what your looking for.
http://dotbay.blogspot.in/2009/09/accessing-controls-in-wpf-itemtemplate.html
I am working with binding an xml structure to a listbox. I am quite confused hoe to do this.How to put a datatemplate inside a datatemplate or i need to use a hirarchialdatatemplate...for example from the xml, I want to display the Make Name of the cars in a list box and i want to show the corresponding Suvs's as a tooltip or contextmenu.How to do this..please help..any input will be highly helpfull..my xml file structure is as given below
<XmlDataProvider x:Key="src">
<x:XData>
<Automobiles>
<Id>24</Id>
<Category>Cars</Category>
<MakeName>Audi</MakeName>
<Suvs>
<SuvId>Item1</SuvId>
<SuvId>Item1</SuvId>
<SuvId>Item1</SuvId>
<SuvId>Item1</SuvId>
</Suvs>
<IsPanel>1</IsPanel>
<IsFav>1</IsFav>
</Automobiles>
</x:XData>
</XmlDataProvider>
I modified your XML format to support multiple Automobile groups:
<XmlDataProvider x:Key="src">
<x:XData>
<Automobiles xmlns="">
<Automobile>
<Id>24</Id>
<Category>Cars</Category>
<MakeName>Audi</MakeName>
<Suvs>
<SuvId>audiItem1</SuvId>
<SuvId>audiItem2</SuvId>
<SuvId>audiItem3</SuvId>
<SuvId>audiItem4</SuvId>
</Suvs>
<IsPanel>1</IsPanel>
<IsFav>1</IsFav>
</Automobile>
<Automobile>
<Id>24</Id>
<Category>Cars</Category>
<MakeName>BMW</MakeName>
<Suvs>
<SuvId>bmwItem1</SuvId>
<SuvId>bmwItem2</SuvId>
<SuvId>bmwItem3</SuvId>
<SuvId>bmwItem4</SuvId>
</Suvs>
<IsPanel>1</IsPanel>
<IsFav>1</IsFav>
</Automobile>
</Automobiles>
</x:XData>
</XmlDataProvider>
I hooked up both a context menu and a tooltip.
Below is how I wired up the bindings:
<ItemsControl ItemsSource="{Binding Source={StaticResource src}, XPath=/Automobiles/Automobile}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu ItemsSource="{Binding XPath=Suvs}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SUV ID: " />
<TextBlock Text="{Binding XPath=SuvId}" />
</StackPanel>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</StackPanel.ContextMenu>
<StackPanel.ToolTip>
<ListBox ItemsSource="{Binding XPath=Suvs/SuvId}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SUV ID: " />
<TextBlock Text="{Binding InnerText, StringFormat={}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel.ToolTip>
<TextBlock Text="Make: " />
<TextBlock Text="{Binding XPath=MakeName}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>