如何检索在WPF-treeview中选择的项?我想在XAML中这样做,因为我想绑定它。

您可能认为它是SelectedItem,但显然它不存在是只读的,因此不可用。

这就是我想做的:

<TreeView ItemsSource="{Binding Path=Model.Clusters}" 
            ItemTemplate="{StaticResource ClusterTemplate}"
            SelectedItem="{Binding Path=Model.SelectedCluster}" />

我想将SelectedItem绑定到我的Model上的一个属性。

但这给了我一个错误:

“SelectedItem”属性是只读的,不能从标记中设置。

编辑: 这就是我解决这个问题的方法:

<TreeView
          ItemsSource="{Binding Path=Model.Clusters}" 
          ItemTemplate="{StaticResource HoofdCLusterTemplate}"
          SelectedItemChanged="TreeView_OnSelectedItemChanged" />

在我的xaml的代码背后文件:

private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    Model.SelectedCluster = (Cluster)e.NewValue;
}

当前回答

你也可以使用TreeViewItem。IsSelected财产

其他回答

这个属性存在:TreeView。设置SelectedItem

但是它是只读的,所以你不能通过绑定来赋值它,只能检索它

我知道这个帖子已经10年了,但问题仍然存在....

最初的问题是“检索”所选项目。我还需要在我的视图模型中“获取”选定的项目(而不是设置它)。在这个线程中的所有答案中,“Wes”的答案是唯一一个以不同的方式解决问题的答案:如果你可以使用“Selected Item”作为数据绑定的目标,那么就使用它作为数据绑定的源。Wes对另一个视图属性做过,我将对viewmodel属性做

我们需要两样东西:

在视图模型中创建一个依赖属性(在我的情况下,类型为'MyObject',因为我的树视图绑定到'MyObject'类型的对象) 从Treeview绑定。SelectedItem属性在视图的构造函数中(是的,这是后面的代码,但很可能你也会init你的datacontext)

Viewmodel:

public static readonly DependencyProperty SelectedTreeViewItemProperty = DependencyProperty.Register("SelectedTreeViewItem", typeof(MyObject), typeof(MyViewModel), new PropertyMetadata(OnSelectedTreeViewItemChanged));

    private static void OnSelectedTreeViewItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as MyViewModel).OnSelectedTreeViewItemChanged(e);
    }

    private void OnSelectedTreeViewItemChanged(DependencyPropertyChangedEventArgs e)
    {
        //do your stuff here
    }

    public MyObject SelectedWorkOrderTreeViewItem
    {
        get { return (MyObject)GetValue(SelectedTreeViewItemProperty); }
        set { SetValue(SelectedTreeViewItemProperty, value); }
    }

构造函数:

Binding binding = new Binding("SelectedItem")
        {
            Source = treeView, //name of tree view in xaml
            Mode = BindingMode.OneWay
        };

        BindingOperations.SetBinding(DataContext, MyViewModel.SelectedTreeViewItemProperty, binding);

一切都很复杂……使用Caliburn Micro (http://caliburnmicro.codeplex.com/)

观点:

<TreeView Micro:Message.Attach="[Event SelectedItemChanged] = [Action SetSelectedItem($this.SelectedItem)]" />

ViewModel:

public void SetSelectedItem(YourNodeViewModel item) {}; 

它的答案比OP期待的要多一点…但我希望它至少能帮助到一些人。

如果你想在SelectedItem改变时执行ICommand,你可以在事件上绑定一个命令,不再需要在ViewModel中使用属性SelectedItem。

这样做:

1-添加System.Windows.Interactivity引用

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

2-将命令绑定到事件SelectedItemChanged

<TreeView x:Name="myTreeView" Margin="1"
            ItemsSource="{Binding Directories}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectedItemChanged">
            <i:InvokeCommandAction Command="{Binding SomeCommand}"
                                   CommandParameter="
                                            {Binding ElementName=myTreeView
                                             ,Path=SelectedItem}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <TreeView.ItemTemplate>
           <!-- ... -->
    </TreeView.ItemTemplate>
</TreeView>

当点击某些项目列表时,你会在“选定”属性中获得数据。 视图模型:

public class ShellViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    private ObservableCollection<Books> _books;

    private List<Books> bookList = new List<Books>();

    public ObservableCollection<Books> Books
    {
        get { return _books; }
        set { _books = value; NotifyPropertyChanged("Books"); }
    }

    private Books books;

    public Books Selected
    {
        get { return books; }
        set { books = value; }
    }


    public ShellViewModel()
    {
        bookList = new List<Books>()
        {
            new Books{BookName = "Harry Poter",Price ="15$"},
            new Books{BookName = "Harry Poter 2 ",Price ="14.95$"},
            new Books{BookName = "Harry Poter 3",Price ="18.50$"},
            new Books{BookName = "Harry Poter 4",Price ="32.90$"},
        };

        Books = new ObservableCollection<Books>(bookList);
    }
}

public class Books
{
    public string BookName { get; set; }
    public string Price { get; set; }
}

XAML:

 <ListView x:Name="lst" Grid.Row="2" ItemsSource="{Binding Books}" SelectedItem="{Binding Selected}">
        <ListView.View>
            <GridView >
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding BookName}"  />
                <GridViewColumn Header="Price" Width="100" DisplayMemberBinding="{Binding Price}"/>
            </GridView>
        </ListView.View>
    </ListView>