WPF MVVM way binding realization of Treeview

TreeviewThere 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 DataTypeset to the same type, run-time error directly.

The reason probably is the addition of two identical Key resources (since HierarchicalDataTemplateand DataTemplateare 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:

TypeListResults 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 ViewModelthe TypeListcontent 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.SelectedItemIs ReadOnly, it is not bound by a simple way to get the selected items

Eventually by binding to Treeviewthe SelectedItemChangedevent, to modify the ViewModeldata
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. Commandbinding events

  • Referenced in the project System.Windows.Interactivity.WPF(for the plug-in can be simple page controls Eventinto the ViewModel Command)
  • Add a reference to the form
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  • Binding Commandto the SelectedItemChangedevent
<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:

ViewModelBaseAnd CommandBaseis the base class own package, two-way binding is to write a simple point of WPF, are interested can comment to me.

Guess you like

Origin www.cnblogs.com/cplemom/p/12078859.html