【问题标题】:Get SelectedItem from TreeView?从 TreeView 获取 SelectedItem?
【发布时间】:2010-11-17 07:42:38
【问题描述】:

有谁知道我如何从 TreeView 中获取 SelectedItem(而不是标题)?
这是我的代码:

<TreeView Name="treeView1" DataContext="{Binding Path=PresentationsViewModel}" Grid.Column="1" >
    <TreeViewItem IsExpanded="True" Header="Objects-A-List" DisplayMemberPath="Name" ItemsSource="{Binding Path=MyItem.ListA}"></TreeViewItem>
    <TreeViewItem IsExpanded="True" Header="Objects-B-List" DisplayMemberPath="Name" ItemsSource="{Binding Path=MyItem.ListB}"></TreeViewItem>
    <TreeViewItem IsExpanded="True" Header="Objects-C-List" DisplayMemberPath="Name" ItemsSource="{Binding Path=MyItem.ListC}"></TreeViewItem>
</TreeView>

请注意,有 3 个不同的列表,包含 3 个不同的对象类型。 有这样的东西对我有很大帮助:

public Object SelectedObject
{
    set { _selectedObject = value; RunMyMethod(); RaisePropertyChanged("SelectedObject"); }
}  

【问题讨论】:

  • 你想做什么?为什么 TreeView.SelectedItem 不适合你?

标签: c# wpf xaml treeview selecteditem


【解决方案1】:

也许我误解了你的问题,但是,

treeView1.SelectedItem

应该可以。

【讨论】:

  • 我正在尝试在没有任何代码隐藏的情况下执行此操作,只需通过 不幸的是 TreeView 没有这个(但 ListView 例如有一个)
【解决方案2】:

好的,我知道这是一个老问题,可能已经死了,但查理说得对。这也可以在代码中使用。例如,您可以这样做:

<ContentPresenter Content="{Binding ElementName=treeView1, Path=SelectedItem}" />

这将显示所选项目。您可以向其中添加样式或 DataTemplate 或使用默认 DataTemplate 到您尝试显示的对象。

【讨论】:

  • 您的视图模型如何获取此信息?我知道 ContentPresenter 包含选定的项目,但我们如何将其传递给视图模型?
  • @ Bob 我想您可以将树视图中的 SelectedItem 绑定到 viewModel 中的属性。然后,您还可以将此属性绑定到 contentPresenter 或您想要表示它的任何其他表单。确保它有 INotify 正在处理它。因此,当您更改 SelectedItem 时,视图中的 ViewModel 和表示(如果您不想要的话)都应该更新。
  • 但首先整个问题是树视图上的 SelectedItem 是只读的,不能在 XAML 中使用。没有?
  • 如果它是只读的,则意味着您无法从 ViewModel 或其他地方设置它,除非用户在 GUI 中选择它。您仍然可以以一种方式绑定到它,绑定并在另一个控件中显示它,或者在 ViewModel 中对它做一些事情。我可能误会你了。你想完成什么?
  • 那么我很确定您可以将正确类型的 ViewModel 中的属性绑定到 TreeView 中的 SelectedItem 属性。您可能必须将模式设置为 OneWay 或 OneWayToSource(不记得是哪个)但不确定。
【解决方案3】:

第 1 步 安装 NuGet:Install-Package System.Windows.Interactivity.WPF

第 2 步 在您的窗口标签中添加:xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

第 3 步 在 TreeView 中添加:

    <TreeView Name="treeView1" ... >
         <i:Interaction.Triggers>
              <i:EventTrigger EventName="SelectedItemChanged">
                   <i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}" CommandParameter="{Binding ElementName=treeView1, Path=SelectedItem}"/>
              </i:EventTrigger>
          </i:Interaction.Triggers>
   ...
   </TreeView>

第 4 步 在您的 ViewModel 中添加:

        private ICommand _selectedItemChangedCommand;
        public ICommand SelectedItemChangedCommand
        {
            get
            {
                if (_selectedItemChangedCommand == null)
                    _selectedItemChangedCommand = new RelayCommand(args => SelectedItemChanged(args));
                return _selectedItemChangedCommand;
            }
        }

        private void SelectedItemChanged(object args)
        {
            //Cast your object
        }

【讨论】:

  • 感谢您的解决方案:)
【解决方案4】:

Diego Torres's answer 简洁明了!但是对于那些不想为此目的安装 NuGet 包的人,您可以创建自己的依赖属性,在触发事件时执行命令。

namespace View.Helper
{
    public class EventToCommandAdaptor
    {
        public static readonly DependencyProperty TreeViewSelectedItemChangedCommand_DpProp =
            DependencyProperty.RegisterAttached(
              "TreeViewSelectedItemChangedCommand",
              typeof(ICommand),
              typeof(EventToCommandAdaptor), // owner type
              new PropertyMetadata(new PropertyChangedCallback(AttachOrRemoveTreeViewSelectedItemChangedEvent))
              );

        public static ICommand GetTreeViewSelectedItemChangedCommand(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(TreeViewSelectedItemChangedCommand_DpProp);
        }

        public static void SetTreeViewSelectedItemChangedCommand(DependencyObject obj, ICommand value)
        {
            obj.SetValue(TreeViewSelectedItemChangedCommand_DpProp, value);
        }

        public static void AttachOrRemoveTreeViewSelectedItemChangedEvent(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            TreeView treeview = obj as TreeView;
            if (treeview != null)
            {
                ICommand cmd = (ICommand)args.NewValue;

                if (args.OldValue == null && args.NewValue != null)
                {
                    treeview.SelectedItemChanged += ExecuteTreeViewSelectedItemChanged;
                }
                else if (args.OldValue != null && args.NewValue == null)
                {
                    treeview.SelectedItemChanged -= ExecuteTreeViewSelectedItemChanged;
                }
            }
        }

        private static void ExecuteTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> args)
        {
            DependencyObject obj = sender as DependencyObject;
            ICommand cmd = (ICommand)obj.GetValue(TreeViewSelectedItemChangedCommand_DpProp);

            if (cmd != null)
            {
                if (cmd.CanExecute(args.NewValue))
                {
                    cmd.Execute(args.NewValue);
                }
            }
        }
    }
}

&lt;Windows&gt;&lt;/Windows&gt; 中包含xmlns:vh="clr-namespace:View.Helper"

TreeView 看起来像:

<TreeView ItemsSource="{Binding MyItemSource}"
    vh:EventToCommandAdaptor.TreeViewSelectedItemChangedCommand="{Binding MyCommand}">
</TreeView>

我在遇到类似情况时学会了这个技巧:我想在触发 DataGrid.MouseDoubleClick 事件时执行命令。不过很抱歉忘记标出出处。

【讨论】:

    猜你喜欢
    • 2015-05-15
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 2011-11-01
    • 2013-04-25
    • 2012-03-17
    • 2016-02-21
    • 2013-10-08
    相关资源
    最近更新 更多