I am trying to make a WPF Application containing a treeview, whose data will be populated from the database. Since I am new to all this, I tried using the simple tutorial that can be found at http://dev102.blogspot.com/2007/12/how-to-use-hierarchical-datatemplate-in.html
I tried following the steps exactly, but all I am getting is just the root node. My xaml looks like this:
<Window x:Class="Hierarchical_attempt.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:Hierarchical_attempt"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type data:Root}"
ItemsSource="{Binding Path=WebPages}">
<TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type data:WebPage}"
ItemsSource="{Binding Path=LinksInPage}">
<TextBlock Text="{Binding PageTitle}" />
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView Name="tree1">
<TreeViewItem ItemsSource="{Binding Path=Webpages}"
Header="{Binding Title}">
</TreeViewItem>
</TreeView>
</Grid>
</Window>
Can you plese tell me where am I going wrong? I am just tring this since this will give me a heads up as to how to go about the treeview. However, what I actually have to do is to populate the data fom the database in the treeview. If you know of any step by step tutorial available, then that will also be really helpful. Thanks. Please reply soon.
It looks as though you have a typo on your binding path. It should be:
<TreeView>
<TreeViewItem ItemsSource="{Binding Path=WebPages}"
Header="{Binding Title}">
</TreeViewItem>
</TreeView>
Note that the P in WebPages is in upper case.
If you are using Visual Studio to develop this, then you should examine the Output pane when running the application. Any binding errors such as this won't raise exceptions, but they will create helpful messages there.
I also simplified the XAML slightly in the original question.
Related
None of my datatemplates are showing up based on DataType of the DataContext. The actual object being passed to the DataContext of UserControl is an Entity (EntityFrameWork 6.0).
I am specifying DataType="{x:Type pf:Promotion}" which is the name of a POCO class that the entity is based on.
(xmlns:pf="clr-namespace:PFModel;assembly=PFModel")
I am lost here, don't know where the problem lies. Thankful for any help or hints.
<UserControl x:Class="PFPromoEditor.UserControls.CenterEditor"
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:PFPromoEditor.UserControls"
xmlns:wpfTool="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
xmlns:pf="clr-namespace:PFModel;assembly=PFModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Border BorderBrush="#FF000000" Margin="2" Padding="5" BorderThickness="1,1,1,1" CornerRadius="8,8,8,8">
<ContentControl>
<ContentControl.Resources>
<DataTemplate DataType="{x:Type pf:Promotion}">
<TextBox Text="Promotion DATA type" />
</DataTemplate>
<DataTemplate DataType="{x:Type pf:Casino}">
<TextBox Text="Casino DATA type" />
</DataTemplate>
<DataTemplate DataType="{x:Type pf:Progressive}">
<TextBlock Text="Progressive DATA type" />
</DataTemplate>
<DataTemplate DataType="{x:Type pf:Detail}">
<TextBox Text="Detail DATA type" />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Border>
</Grid>
<local:CenterEditor x:Name="CenterContent" DataContext="{Binding ElementName=promoMenu,Path=MySelectedItem }"/>
Answer to first question, the control has datacontext properly set with an entity, of either Promotion, Casino, Promotion or Detail.
I have also tried it with a bound property like:
<DataTemplate DataType="{x:Type pf:Progressive}">
<Grid>
<TextBlock Text="Progressive DATA type" />
<TextBox Text="{Binding Path=Detail.Title, FallbackValue= 'Select any Item in list to edit'}"/>
</Grid>
</DataTemplate>
Still nothing, blank.
I have also just placed something like:
<TextBox Text="{Binding Path=Detail.Title, FallbackValue= 'Select any Item in list to edit'}"/>
In the code above like thus:
</DataTemplate>
</ContentControl.Resources>
<TextBox Text="{Binding Path=Detail.Title, FallbackValue= 'Select any Item in list to edit'}"/>
</ContentControl>
And the textbox binding is fine, the entity is there and I get the expected data.
Its not a data binding problem. I have context and I have a proper object.
I thought of a couple other things I need to try. Let me get back to you.
It turns out the thing I was doing wrong (besides being stubborn about what I thought was wrong, and trying to solve my problem at 3 am, and over thinking the problem in general) was leaving out:
Content="{Binding}"
which BTW way I missed in the comments, I recall reading datacontext, that happened because I was tired and frustrated.
The thing that solved the problem was this modification to the content control
<ContentControl Content="{Binding}" >
In MSDN examples sometimes I see it is pointing to an SDK or library but there is no any link or pointer to the SDK to download. Is this a general style or I'm missing something ...
Just an example in following:
<Window x:Class="SDKSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="HierarchicalDataTemplate Sample"
xmlns:src="clr-namespace:SDKSample">
<DockPanel>
<DockPanel.Resources>
<src:ListLeagueList x:Key="MyList" />
<HierarchicalDataTemplate DataType="{x:Type src:League}"
ItemsSource="{Binding Path=Divisions}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type src:Division}"
ItemsSource="{Binding Path=Teams}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type src:Team}">
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</DockPanel.Resources>
<Menu Name="menu1"
DockPanel.Dock="Top"
Margin="10,10,10,10">
<MenuItem Header="My Soccer Leagues"
ItemsSource="{Binding Source={StaticResource MyList}}" />
</Menu>
<TreeView>
<TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}"
Header="My Soccer Leagues" />
</TreeView>
</DockPanel>
</Window>
I'm looking at this xaml code on MSDN http://msdn.microsoft.com/en-us/library/system.windows.hierarchicaldatatemplate.aspx
It is all good but question I'm having is where can I find SDKSample class?
This data can be found at the following path where all the samples and their backup files are hosted on GitHub.
WPF-Samples->Data Binding->HierarchicalDataTemplate
One can search for a particular filename within the repository to find its exact location and the same can either be downloaded or reproduced. The namespace given in the MSDN documentation may not be matching with the namespace used in the Samples repository but that can always be changed and the references need to be updated accordingly.
xmlns:src="clr-namespace:SDKSample" is a reference to the main project used for the documentation. You can see this because Window1 uses the same namespace: <Window x:Class="SDKSample.Window1"
However, I don't see a way to download the whole documentation project. You will have to create the class ListLeagueList yourself. Fortunately there is an explanation of it:
In the following example, ListLeagueList is a list of League objects.
Each League object has a Name and a collection of Division objects.
Each Division has a Name and a collection of Team objects, and each
Team object has a Name.
I have two simple ViewModels, NodeViewModel and LeafViewModel that can be items in a TreeView. Just like below. Templates are applied implictly because I don't want a custom template selector.
<UserControl x:Class="MyProject.UserControl1"
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:ViewModels="clr-namespace:MyProject.ViewModels" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignData /SampleData/NodeViewModelSampleData.xaml}">
<UserControl.Resources>
<HierarchicalDataTemplate DataType="{x:Type ViewModels:NodeViewModel}" ItemsSource={Binding Children}>
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding Name}" IsChecked="{Binding Result}"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type ViewModels:LeafViewModel}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</UserControl.Resources>
<TreeView ItemsSource="{Binding Children}" />
</UserControl>
How can I generate sample data in blend that contains a tree with both NodeViewModels and LeafViewModels and then display it as the data in the treeview while still using implict template selection?
In the absence of using some kind of mocking framework, I've found that the easiest way to do this is to just hack together a class that generates instances of my view models and use it as a data source in Blend.
It occurs to me that it might be even easier to just define the test data in XAML, though this is contingent on the view model classes being designed to allow that (e.g. with parameterless constructors and a ContentProperty attribute, among other things).
I think the answer is simple: You can't.
Blend doesn't really work well with implicit datatemplates and template selectors. This is not only true for sample data but also inplace wysiwyg template editing. So for blendability you should try to avoid implict templates and template selectors whenever you can.
Is it possible to bind something to a property of a control in a data template entirely in XAML? The following code is a simplified version of the problem I'm running into. I'd like the text of the TextBlock (displayName) to be updated as the user types in the TextBox located in the DataTemplate.
<Window x:Class="WpfApplication4.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfApplication4="clr-namespace:WpfApplication4"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate DataType="{x:Type WpfApplication4:Foo}">
<TextBox Text="{Binding Path=Name}" />
</DataTemplate>
<WpfApplication4:Foo x:Key="testObject" Name="This is a test" />
</Window.Resources>
<StackPanel>
<TextBlock x:Name="displayName" Margin="5" />
<ContentControl x:Name="contentControl" Margin="5" Content="{StaticResource testObject}" />
</StackPanel>
No, at least, not from XAML. You could write code to traverse the visual tree and find the element you want to bind to, but that would be nasty.
But in your particular example, would it not make sense to just bind the TextBlock to the same data object (Foo instance)?
I have a simple WPF TreeView with icons
<TreeView Name="TreeViewThings" ItemsSource="{Binding}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Thing}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Margin="2">
<Image Source="Thing.png" Width="16"
Height="16"
SnapsToDevicePixels="True"/>
<TextBlock Text="{Binding Path=Name}" Margin="5,0"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
When a node is selected, the whole StackPanel is selected (both the image and the text).
How can I restrict the selection to the Text Only?
Here is a little sth I found a while ago, when I googled for sth different:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/208805b2-225f-4da3-abd7-0d3dfa92fede/
In that thread they also talk about rewriting the TreeView. You can do so like stated in this link:http://marlongrech.wordpress.com/2008/03/15/wpf-treeview-root-node/
you don't have to rewrite the TreeView class though, simply use the xaml from the latter link. you can see how to add the controltemplate if you download the source code.