Treeview
There are two template data HierarchicalDataTemplate
(hierarchical data templates) and DataTemplate
(template data), sub-data items are generated and applied to the common data items.
During use, if two templates are DataType
set to the same type, run-time error directly.
The reason probably is the addition of two identical Key resources (since HierarchicalDataTemplate
and DataTemplate
are defined in the <TreeView.Resources>
tag).
Code:
public class TypeTreeModel :TypeModel
{
public ObservableCollection<TypeTreeModel> ChildList { get; set; }
= new ObservableCollection<TypeTreeModel>();
}
public class TypeModel
{
public int Id { get; set; }
public string Name { get; set; }
}
<TreeView x:Name="treeView" ItemsSource="{Binding TypeList}" MinWidth="200" MaxHeight="200" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:TypeTreeModel}" ItemsSource="{Binding ChildList}">
<TextBlock Text="{Binding Name}" Margin="3 2"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type vm:TypeModel}">
<TextBlock Text="{Binding Name}" ToolTip="{Binding Id}" Margin="3 2"></TextBlock>
</DataTemplate>
</TreeView.Resources>
</TreeView>
Renderings:
TypeList
Results are generally taken out of the database data processing nested. Sometimes encounter needs, there are different types for different categories. According to the rules of two-way binding, we only need to modify ViewModel
the TypeList
content of it.
Note: ObservableCollection
Only when the list of items changes will trigger a page refresh, will react to the page when that is added or deleted. If using direct writing assignment, will not trigger a page refresh.
Recommended time of writing update data:
//清空原先的列表
TypeList.Clear();
list.ForEach(d =>
{
TypeList.Add(d);
});
TreeView.SelectedItem way binding
TreeView.SelectedItem
IsReadOnly
, it is not bound by a simple way to get the selected items
Eventually by binding to Treeview
the SelectedItemChanged
event, to modify the ViewModel
data
1. Direct binding events
<TreeView ItemsSource="{Binding TypeList}" SelectedItemChanged="TreeView_OnSelectedItemChanged" />
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
vm.SelectItem = (Cluster)e.NewValue;
}
2. Command
binding events
- Referenced in the project
System.Windows.Interactivity.WPF
(for the plug-in can be simple page controlsEvent
into the ViewModelCommand
) - Add a reference to the form
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
- Binding
Command
to theSelectedItemChanged
event
<TreeView x:Name="treeView" ItemsSource="{Binding TypeList}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding SelectItemChangeCommand}"
CommandParameter="{Binding ElementName=treeView,Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
ViewModel:
public class TreeViewModel : ViewModelBase
{
public ObservableCollection<TypeTreeModel> TypeList;
private TypeModel selectItem;
public TypeModel SelectItem
{
get { return selectItem; }
set { this.MutateVerbose(ref selectItem, value, RaisePropertyChanged()); }
}
public TreeViewModel()
{
TypeList = GetData();
}
public ICommand SelectItemChangeCommand
{
get
{
return new CommandBase((param) =>
{
if(param != null)
SelectItem = (TypeModel)param;
});
}
}
}
Renderings:
ViewModelBase
And CommandBase
is the base class own package, two-way binding is to write a simple point of WPF, are interested can comment to me.