Rất muộn đối với câu trả lời của tôi nhưng đối với những người muốn có giải pháp MVVM thuần túy, có thể thực hiện với Trình kích hoạt sự kiện (để cập nhật liên kết khi người dùng chọn mục mới) và Trình kích hoạt dữ liệu (để cập nhật) mục đã chọn khi giá trị của các ràng buộc thay đổi).
Đối với điều này để làm việc ViewModel chính cần các mặt hàng, một tài sản cho mục đang được chọn và sở hữu một lệnh đó sẽ được gọi khi thay đổi mục đang được chọn:
public class MainViewModel : ViewModelBase
{
// the currently selected node, can be changed programmatically
private Node _CurrentNode;
public Node CurrentNode
{
get { return this._CurrentNode; }
set { this._CurrentNode = value; RaisePropertyChanged(() => this.CurrentNode); }
}
// called when the user selects a new node in the tree view
public ICommand SelectedNodeChangedCommand { get { return new RelayCommand<Node>(OnSelectedNodeChanged); } }
private void OnSelectedNodeChanged(Node node)
{
this.CurrentNode = node;
}
// list of items to display in the tree view
private ObservableCollection<Node> _Items;
public ObservableCollection<Node> Items
{
get { return this._Items; }
set { this._Items = value; RaisePropertyChanged(() => this.Items); }
}
}
Các TreeView cần một kích hoạt sự kiện để gọi SelectedNodeChangedCommand khi những thay đổi lựa chọn, và một DataTrigger theo phong cách TreeViewItem để các hạng mục kiểm soát được chọn khi giá trị của CurrentNode được thay đổi programatically trong các mã:
<TreeView x:Name="treeView" ItemsSource="{Binding Items}"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd ="http://www.galasoft.ch/mvvmlight">
<TreeView.Resources>
<conv:EqualityConverter x:Key="EqualityConverter" />
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
<Setter Property="IsSelected" Value="False" />
<Style.Triggers>
<!-- DataTrigger updates TreeViewItem selection when vm code changes CurrentNode -->
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource EqualityConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type TreeView}}" Path="DataContext.CurrentNode" />
<Binding />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="IsSelected" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- *** HierarchicalDataTemplates go here *** -->
</TreeView.Resources>
<!-- EventTrigger invokes SelectedNodeChangedCommand when selection is changed by user interaction -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<cmd:EventToCommand Command="{Binding SelectedNodeChangedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
các DataTrig ger hoạt động bằng cách phát hiện khi giá trị của CurrentNode khớp với nút cho mục danh sách hiện tại. Thật không may DataTriggers không thể ràng buộc giá trị của họ, do đó, nó phải kiểm tra với một EqualityConverter thay vì mà chỉ cần làm một so sánh đơn giản:
public class EqualityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0] == values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Nguồn
2015-08-06 23:16:02
WPF's TreeView hy sinh * mỗi bit cuối cùng của khả năng sử dụng để đạt được các tính năng mà hầu hết mọi người không dường như cần hầu hết thời gian ... –