【问题标题】:How to programmatically select an item in a WPF TreeView?如何以编程方式选择 WPF TreeView 中的项目?
【发布时间】:2010-09-29 15:47:27
【问题描述】:

如何以编程方式选择 WPF TreeView 中的项目? ItemsControl 模型似乎可以阻止它。

【问题讨论】:

    标签: c# .net wpf treeview itemscontrol


    【解决方案1】:

    对于那些仍在寻找此问题的正确解决方案的人,请参阅以下内容。我在 DaWanderer 的代码项目文章“WPF TreeView Selection”http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx 的 cmets 中找到了这个。 它由 Kenrae 于 2008 年 11 月 25 日发布。这对我来说非常有用。谢谢肯雷!

    这是他的帖子:

    让您自己的数据对象拥有 IsSelected 属性(我也推荐 IsExpanded 属性),而不是遍历树。使用 TreeView 上的 ItemContainerStyle 属性定义树的 TreeViewItems 的样式,该属性将 TreeViewItem 中的这些属性绑定到您的数据对象。像这样的:

    <Style x:Key="LibraryTreeViewItemStyle"
                   TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded"
                            Value="{Binding IsExpanded, Mode=TwoWay}" />
                <Setter Property="IsSelected"
                            Value="{Binding IsSelected, Mode=TwoWay}" />
                <Setter Property="FontWeight"
                            Value="Normal" />
                <Style.Triggers>
                      <Trigger Property="IsSelected"
                                  Value="True">
                            <Setter Property="FontWeight"
                                        Value="Bold" />
                      </Trigger>
                </Style.Triggers>
          </Style>
    
    <TreeView ItemsSource="{Binding Path=YourCollection}"
                   ItemContainerStyle="{StaticResource LibraryTreeViewItemStyle}"
                   ItemTemplate={StaticResource YourHierarchicalDataTemplate}/>
    

    【讨论】:

    • 有效! ItemContainerStyle="{StaticResource LibraryTreeViewItemStyle}"
    • 对我不起作用;程序选择总是自动重置为之前选择的内容,除非之前没有选择任何内容。我用示例代码创建了一个related question
    • 没关系。我为我的收藏使用了 IEnumerable,我将其更改为 ObservableCollection,现在它可以工作了。
    • 这并不总是有效。 TreeView.SelectedItem 保留旧值,这在某些情况下会导致奇怪的错误(多选场景)。
    • 效果很好,有一些额外说明:模型需要实现 INotifyPropertyChanged 并为 IsSelected 和 IsExpanded 属性触发 PropertyChangedEvent。此外,如果你想扩展一个项目,你也需要扩展它的所有祖先,这意味着模型也有一个 Parent 关系是有意义的。
    【解决方案2】:

    出于某种奇怪的原因,这真的很痛苦,您必须使用 ContainerFromItem 来获取容器,然后调用 select 方法。

    //  selectedItemObject is not a TreeViewItem, but an item from the collection that 
    //  populated the TreeView.
    
    var tvi = treeView.ItemContainerGenerator.ContainerFromItem(selectedItemObject) 
              as TreeViewItem;
    
    if (tvi != null)
    {
        tvi.IsSelected = true;
    }
    

    曾经有一篇关于如何做到这一点的博客文章here,但现在链接已失效。

    【讨论】:

    • 它对我不起作用。尽管 TreeView.HasItems 为真,但 ContainerFromItem 返回 null。就此而言,我还尝试了 ContainerFromIndex(0),它也返回了 null。
    • 很遗憾,链接不见了
    • 不,不是!查看 Kent Boogaart 的解决方案
    • 这仅适用于一个级别并且令人困惑。看我的回答。这是真正的交易。
    【解决方案3】:

    您需要获取TreeViewItem,然后将IsSelected 设置为true

    【讨论】:

    • 那么如何获取 TreeViewItem?
    • 您可以使用 treeview.ItemContainerGenerator.ContainerFromItem(item) 获取 treeviewitem,其中 item 是 treeview.items 集合中的单个数据绑定对象。
    • 是的,这对我有用 ((TreeViewItem){treeview_name}.Items[0]).IsSelected = true;
    • 如果您使用不使用 TreeViewItem 的自定义数据绑定上下文,这将不起作用
    【解决方案4】:

    我已成功使用此代码:

    public static TreeViewItem FindTviFromObjectRecursive(ItemsControl ic, object o) {
      //Search for the object model in first level children (recursively)
      TreeViewItem tvi = ic.ItemContainerGenerator.ContainerFromItem(o) as TreeViewItem;
      if (tvi != null) return tvi;
      //Loop through user object models
      foreach (object i in ic.Items) {
        //Get the TreeViewItem associated with the iterated object model
        TreeViewItem tvi2 = ic.ItemContainerGenerator.ContainerFromItem(i) as TreeViewItem;
        tvi = FindTviFromObjectRecursive(tvi2, o);
        if (tvi != null) return tvi;
      }
      return null;
    }
    

    用法:

    var tvi = FindTviFromObjectRecursive(TheTreeView, TheModel);
    if (tvi != null) tvi.IsSelected = true;
    

    【讨论】:

    • 这应该是公认的答案。此代码还查找和选择子元素。
    • 在我添加了一个空检查后,这对我有用:if (tvi2 != null) 围绕对 FindTviFromObjectRecursive 的递归调用和返回 tvi 的以下行。如果没有该检查,我不确定这是如何工作的,因为否则它会尝试在叶子上继续......
    【解决方案5】:

    这并不像看起来那么简单,Steven 提供的链接在 2008 年发布了一个解决方案,该解决方案可能仍然有效,但无法处理虚拟化 TreeViews。此外,该文章的 cmets 中还提到了许多其他问题。没有冒犯,但我也遇到了同样的问题,找不到完美的解决方案。以下是一些对我有很大帮助的文章/帖子的链接-

    如何在 TreeView 中展开项目? – 第三部分: http://bea.stollnitz.com/blog/?p=59

    以编程方式在 TreeView 中选择项目: http://blog.quantumbitdesigns.com/2008/07/22/programmatically-selecting-an-item-in-a-treeview/#respond

    TreeView、TreeViewItem 和 IsSelected: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7e368b93-f509-4cd6-88e7-561e8d3246ae/

    【讨论】:

    【解决方案6】:

    我写了一个扩展方法:

    using System.Windows.Controls;
    
    namespace Extensions
    {
        public static class TreeViewEx
        {
            /// <summary>
            /// Select specified item in a TreeView
            /// </summary>
            public static void SelectItem(this TreeView treeView, object item)
            {
                var tvItem = treeView.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
                if (tvItem != null)
                {
                    tvItem.IsSelected = true;
                }
            }
        }
    }
    

    我可以这样使用:

    if (_items.Count > 0)
        _treeView.SelectItem(_items[0]);
    

    【讨论】:

      【解决方案7】:

      如果您想选择位于孩子的孩子的项目,您可以使用递归来做到这一点。

      public bool Select(TreeViewItem item, object select) // recursive function to set item selection in treeview
      {
          if (item == null)
              return false;
          TreeViewItem child = item.ItemContainerGenerator.ContainerFromItem(select) as TreeViewItem;
          if (child != null)
          {
              child.IsSelected = true;
              return true;
          }
          foreach (object c in item.Items)
          {
              bool result = Select(item.ItemContainerGenerator.ContainerFromItem(c) as TreeViewItem, select);
              if (result == true)
                  return true;
          }
          return false;
      }
      

      【讨论】:

        【解决方案8】:

        你可以通过后面的代码来做到这一点

        if (TreeView1.Items.Count > 0)
                (TreeView1.Items[0] as TreeViewItem).IsSelected = true;
        

        【讨论】:

          【解决方案9】:

          试试这个

              /// <summary>
              /// Selects the tree view item.
              /// </summary>
              /// <param name="Collection">The collection.</param>
              /// <param name="Value">The value.</param>
              /// <returns></returns>
              private TreeViewItem SelectTreeViewItem(ItemCollection Collection, String Value)
              {
                  if (Collection == null) return null;
                  foreach(TreeViewItem Item in Collection)
                  {
                      /// Find in current
                      if (Item.Header.Equals(Value))
                      {
                          Item.IsSelected = true;
                          return Item;
                      }
                      /// Find in Childs
                      if (Item.Items != null)
                      {
                          TreeViewItem childItem = this.SelectTreeViewItem(Item.Items, Value);
                          if (childItem != null)
                          {
                              Item.IsExpanded = true;
                              return childItem;
                          }
                      }
                  }
                  return null;
              }
          

          参考:http://amastaneh.blogspot.com/2011/06/wpf-selectedvalue-for-treeview.html

          【讨论】:

          • 这仅在 itemcollections 条目是“TreeViewItem”时才有效 - 如果使用数据绑定,“Items”的内容是数据绑定条目的类型。
          【解决方案10】:

          只是想我会加入我所采用的解决方案,以防万一这可以帮助任何人。请注意,执行此操作的最佳方法是根据 kuninl 的回答使用像“IsSelected”这样的绑定属性,但在我的情况下,它是一个不遵循 MVVM 的遗留应用程序,所以我最终得到了以下结果。

          private void ChangeSessionSelection()
          {
              foreach (SessionContainer item in this.treeActiveSessions.Items)
              {
                  var treeviewItem = this.treeActiveSessions.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
          
                  if (item.Session == this.selectedSession.Session)
                  {
                      treeviewItem.IsSelected = true;
                      treeviewItem.IsExpanded = true;
                  }
                  else
                  {
                      treeviewItem.IsSelected = false;
                      treeviewItem.IsExpanded = false;
                  }
              }            
          }
          

          它的作用是在 UI 中选择并展开树视图项,它代表后面代码中选定的数据项。这样做的目的是当用户在同一窗口中的项目控件中更改选择时,在树视图中更改选择。

          【讨论】:

            【解决方案11】:

            我创建了一个方法VisualTreeExt.GetDescendants&lt;T&gt;,它返回与指定类型匹配的可枚举元素集合:

            public static class VisualTreeExt
            {
              public static IEnumerable<T> GetDescendants<T>(DependencyObject parent) where T : DependencyObject
              {
                var count = VisualTreeHelper.GetChildrenCount(parent);
                for (var i = 0; i < count; ++i)
                {
                   // Obtain the child
                   var child = VisualTreeHelper.GetChild(parent, i);
                   if (child is T)
                     yield return (T)child;
            
                   // Return all the descendant children
                   foreach (var subItem in GetDescendants<T>(child))
                     yield return subItem;
                }
              }
            }
            

            当您请求 VisualTreeHelperExt.GetDescendants&lt;TreeViewItem&gt;(MyAmazingTreeView) 时,您将获得所有 TreeViewItem 子代。您可以使用以下代码选择特定值:

            var treeViewItem = VisualTreeExt.GetDescendants<TreeViewItem>(MyTreeView).FirstOrDefault(tvi => tvi.DataContext == newValue);
            if (treeViewItem != null)
              treeViewItem.IsSelected = true;
            

            这是一个有点肮脏的解决方案(可能不是最有效的),如果您使用虚拟化 TreeView,它将无法工作,因为它取决于实际视觉元素的存在。但它适用于我的情况......

            【讨论】:

              【解决方案12】:

              建议的答案不起作用。 @fandisusanto 的答案可能确实有效,但它可以变得更简单。这是我能想到的最简单的答案:

                  private static void DeselectTreeViewItem(IEnumerable<TreeViewItem> treeViewItems)
                  {
                      foreach (var treeViewItem in treeViewItems)
                      {
                          if (treeViewItem.IsSelected)
                          {
                              treeViewItem.IsSelected = false;
                              return;
                          }
              
                          DeselectTreeViewItem(treeViewItem.Items.Cast<TreeViewItem>());
                      }
                  }
              

              用法:

                  private void ClearSelectedItem()
                  {
                      if (AssetTreeView.SelectedItem != null)
                      {
                          DeselectTreeViewItem(AssetTreeView.Items.Cast<TreeViewItem>());
                      }
                  }
              

              【讨论】:

              • 这仅适用于您的 ItemsSource 是 TreeViewItem 列表的情况。
              【解决方案13】:

              这是我的解决方案。其他人以各种方式对我来说失败了。您需要从上到下遍历树,在每个级别查找树项,沿途扩展和更新布局。

              此函数获取一个节点堆栈,其中第一个出堆栈的节点是最顶部的节点,堆栈上的每个后续节点都是前一个父节点的子节点。第二个参数是 TreeView。

              找到每个项目后,展开该项目,并返回最后一个项目,调用者可以在其中选择它。

                  TreeViewItem FindTreeViewItem( Stack<object> nodeStack, TreeView treeView )
                  {
                      ItemsControl itemsControl = treeView;
              
                      while (nodeStack.Count > 0) {
                          object node = nodeStack.Pop();
                          bool found = false;
              
                          foreach (object item in itemsControl.Items) {
                              if (item == node) {
                                  found = true;
              
                                  if (itemsControl.ItemContainerGenerator.ContainerFromItem( item ) is TreeViewItem treeViewItem) {
                                      if (nodeStack.Count == 0) {
                                          return treeViewItem;
                                      }
              
                                      itemsControl = treeViewItem;
                                      treeViewItem.IsExpanded = true;
                                      treeViewItem.UpdateLayout();
                                      break;
                                  }
                              }
                          }
              
                          if (!found) {
                              return null;
                          }
                      }
              
                      return null;
                  }
              

              如何调用它的示例:

                  // Build nodeStack here from your data
              
                  TreeViewItem treeViewItem = FindTreeViewItem( nodeStack, treeView );
              
                  if (treeViewItem != null) {
                      treeViewItem.IsSelected = true;
                      treeViewItem.BringIntoView();
                  }
              

              【讨论】:

                【解决方案14】:

                我为此编写了一个 Helper 类,它支持 MVVM 和延迟加载项。

                public class TreeViewHelper<TModel>
                {
                    public TreeViewHelper(TreeView treeView, Func<TModel, TModel> getParent, Func<TModel, IList<TModel>> getSubItems)
                    {
                        TreeView = treeView;
                        GetParent = getParent;
                        GetSubItems = getSubItems;
                    }
                
                    public TreeView TreeView { get; }
                    public Func<TModel, TModel> GetParent { get; }
                    public Func<TModel, IList<TModel>> GetSubItems { get; }
                
                    public void SelectItemWhileLoaded(TModel node, IList<TModel> rootNodes)
                    {
                        if (TreeView.IsLoaded)
                        {
                            SelectItem(node, rootNodes);
                        }
                        else
                        {
                            TreeView.Loaded += TreeView_Loaded;
                            void TreeView_Loaded(object sender, System.Windows.RoutedEventArgs e)
                            {
                                TreeView.Loaded -= TreeView_Loaded;
                                SelectItem(node, rootNodes);
                            }
                        }
                    }
                
                
                    public void SelectItem(TModel node, IList<TModel> rootNodes)
                    {
                        Stack<TModel> nodes = new Stack<TModel>();
                        //push into stack
                        while (!rootNodes.Contains(node))
                        {
                            nodes.Push(node);
                            node = GetParent(node);
                        }
                        TreeViewItem treeViewItem = TreeView.ItemContainerGenerator
                            .ContainerFromItem(node) as TreeViewItem;
                        if (nodes.Count == 0)
                        {
                            //Top level
                            treeViewItem.IsSelected = true;
                            treeViewItem.BringIntoView();
                            return;
                        }
                        Expanded(true);
                        void Expanded(bool top)
                        {
                            if (!top)
                            {
                                treeViewItem = treeViewItem.ItemContainerGenerator
                                    .ContainerFromItem(node) as TreeViewItem;
                                if (nodes.Count == 0)
                                {
                                    treeViewItem.IsSelected = true;
                                    treeViewItem.BringIntoView();
                                    return;
                                }
                            }
                            node = nodes.Pop();
                            treeViewItem.IsExpanded = true;
                            if (treeViewItem.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
                            {
                                Expanded(true);
                            }
                            else
                            {
                                //Lazy
                                treeViewItem.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
                            }
                        }
                        void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
                        {
                            if (treeViewItem.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
                            {
                                treeViewItem.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;
                                Expanded(false);
                            }
                        }
                    }
                }
                

                【讨论】:

                  【解决方案15】:

                  是的..我知道这个问题已经过去很多年了,但是..仍然没有快速解决这个问题..所以:

                  以下将执行 OP 要求的操作。

                  我所做的基本上是阅读此页面中的所有答案并点击所有相关链接以创建一个一劳永逸的解决方案来解决这个恼人的问题。

                  好处:

                  • 它也支持虚拟化 TreeView。
                  • 它使用行为技术,因此 XAML 非常简单。
                  • 添加依赖属性以允许绑定到选定的 TreeView 项。

                  这部分是你唯一需要复制的代码,其他部分只是为了帮助完成一个例子。

                  public static class TreeViewSelectedItemExBehavior
                  {
                      private static List<TreeView> isRegisteredToSelectionChanged = new List<TreeView>();
                  
                      public static readonly DependencyProperty SelectedItemExProperty =
                          DependencyProperty.RegisterAttached("SelectedItemEx",
                              typeof(object),
                              typeof(TreeViewSelectedItemExBehavior),
                              new FrameworkPropertyMetadata(new object(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemExChanged, null));
                  
                      #region SelectedItemEx
                  
                      public static object GetSelectedItemEx(TreeView target)
                      {
                          return target.GetValue(SelectedItemExProperty);
                      }
                  
                      public static void SetSelectedItemEx(TreeView target, object value)
                      {
                          target.SetValue(SelectedItemExProperty, value);
                          var treeViewItemToSelect = GetTreeViewItem(target, value);
                          if (treeViewItemToSelect == null)
                          {
                              if (target.SelectedItem == null)
                                  return;
                              var treeViewItemToUnSelect = GetTreeViewItem(target, target.SelectedItem);
                              treeViewItemToUnSelect.IsSelected = false;
                          }
                          else
                              treeViewItemToSelect.IsSelected = true;
                      }
                  
                      public static void OnSelectedItemExChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
                      {
                          var treeView = depObj as TreeView;
                          if (treeView == null)
                              return;
                          if (!isRegisteredToSelectionChanged.Contains(treeView))
                          {
                              treeView.SelectedItemChanged += TreeView_SelectedItemChanged;
                              isRegisteredToSelectionChanged.Add(treeView);
                          }
                      }
                      
                      #endregion
                  
                      private static void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
                      {
                          var treeView = (TreeView)sender;
                          SetSelectedItemEx(treeView, e.NewValue);
                      }
                  
                      #region Helper Structures & Methods
                  
                      public class MyVirtualizingStackPanel : VirtualizingStackPanel
                      {
                          /// <summary>
                          /// Publically expose BringIndexIntoView.
                          /// </summary>
                          public void BringIntoView(int index)
                          {
                              BringIndexIntoView(index);
                          }
                      }
                  
                      /// <summary>Recursively search for an item in this subtree.</summary>
                      /// <param name="container">The parent ItemsControl. This can be a TreeView or a TreeViewItem.</param>
                      /// <param name="item">The item to search for.</param>
                      /// <returns>The TreeViewItem that contains the specified item.</returns>
                      private static TreeViewItem GetTreeViewItem(ItemsControl container, object item)
                      {
                          if (container != null)
                          {
                              if (container.DataContext == item)
                              {
                                  return container as TreeViewItem;
                              }
                  
                              // Expand the current container
                              if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded)
                              {
                                  container.SetValue(TreeViewItem.IsExpandedProperty, true);
                              }
                  
                              // Try to generate the ItemsPresenter and the ItemsPanel.
                              // by calling ApplyTemplate.  Note that in the 
                              // virtualizing case even if the item is marked 
                              // expanded we still need to do this step in order to 
                              // regenerate the visuals because they may have been virtualized away.
                  
                              container.ApplyTemplate();
                              ItemsPresenter itemsPresenter =
                                  (ItemsPresenter)container.Template.FindName("ItemsHost", container);
                              if (itemsPresenter != null)
                              {
                                  itemsPresenter.ApplyTemplate();
                              }
                              else
                              {
                                  // The Tree template has not named the ItemsPresenter, 
                                  // so walk the descendents and find the child.
                                  itemsPresenter = FindVisualChild<ItemsPresenter>(container);
                                  if (itemsPresenter == null)
                                  {
                                      container.UpdateLayout();
                  
                                      itemsPresenter = FindVisualChild<ItemsPresenter>(container);
                                  }
                              }
                  
                              Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0);
                  
                  
                              // Ensure that the generator for this panel has been created.
                              UIElementCollection children = itemsHostPanel.Children;
                  
                              MyVirtualizingStackPanel virtualizingPanel =
                                  itemsHostPanel as MyVirtualizingStackPanel;
                  
                              for (int i = 0, count = container.Items.Count; i < count; i++)
                              {
                                  TreeViewItem subContainer;
                                  if (virtualizingPanel != null)
                                  {
                                      // Bring the item into view so 
                                      // that the container will be generated.
                                      virtualizingPanel.BringIntoView(i);
                  
                                      subContainer =
                                          (TreeViewItem)container.ItemContainerGenerator.
                                          ContainerFromIndex(i);
                                  }
                                  else
                                  {
                                      subContainer =
                                          (TreeViewItem)container.ItemContainerGenerator.
                                          ContainerFromIndex(i);
                  
                                      // Bring the item into view to maintain the 
                                      // same behavior as with a virtualizing panel.
                                      subContainer.BringIntoView();
                                  }
                  
                                  if (subContainer != null)
                                  {
                                      // Search the next level for the object.
                                      TreeViewItem resultContainer = GetTreeViewItem(subContainer, item);
                                      if (resultContainer != null)
                                      {
                                          return resultContainer;
                                      }
                                      else
                                      {
                                          // The object is not under this TreeViewItem
                                          // so collapse it.
                                          subContainer.IsExpanded = false;
                                      }
                                  }
                              }
                          }
                  
                          return null;
                      }
                  
                      /// <summary>Search for an element of a certain type in the visual tree.</summary>
                      /// <typeparam name="T">The type of element to find.</typeparam>
                      /// <param name="visual">The parent element.</param>
                      /// <returns></returns>
                      private static T FindVisualChild<T>(Visual visual) where T : Visual
                      {
                          for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
                          {
                              Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
                              if (child != null)
                              {
                                  T correctlyTyped = child as T;
                                  if (correctlyTyped != null)
                                  {
                                      return correctlyTyped;
                                  }
                  
                                  T descendent = FindVisualChild<T>(child);
                                  if (descendent != null)
                                  {
                                      return descendent;
                                  }
                              }
                          }
                          return null;
                      }
                      
                      #endregion
                  }
                  

                  这是 TreeView 行在 XAML 中的外观示例:

                  <TreeView x:Name="trvwSs"
                      Grid.Column="2" Grid.Row="1" Margin="4" ItemsSource="{Binding ItemsTreeViewSs}"
                      behaviors:TreeViewSelectedItemExBehavior.SelectedItemEx="{Binding SelectedItemTreeViewSs}" />
                  

                  唯一需要担心的是确保要绑定到 SelectedItemEx 的视图模型属性不为空。但这不是特例。只是提到它以防人们感到困惑。

                  public class VmMainContainer : INotifyPropertyChanged
                  {
                      private object selectedItemTreeViewSs = new object();
                      private ObservableCollection<object> selectedItemsTreeViewSs = new ObservableCollection<object>();
                      private ObservableCollection<VmItem> itemsTreeViewSs = new ObservableCollection<VmItem>();
                  
                      public object SelectedItemTreeViewSs
                      {
                          get
                          {
                              return selectedItemTreeViewSs;
                          }
                          set
                          {
                              selectedItemTreeViewSs = value;
                              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemTreeViewSs)));
                          }
                      }
                  
                      public ObservableCollection<object> SelectedItemsTreeViewSs
                      {
                          get
                          {
                              return selectedItemsTreeViewSs;
                          }
                          set
                          {
                              selectedItemsTreeViewSs = value;
                              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemsTreeViewSs)));
                          }
                      }
                  
                      public ObservableCollection<VmItem> ItemsTreeViewSs
                      {
                          get { return itemsTreeViewSs; }
                          set
                          {
                              itemsTreeViewSs = value;
                              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ItemsTreeViewSs)));
                          }
                      }
                  }
                  

                  最后一件事.. 以编程方式选择的示例: 我在 MainWindow.xaml 及其处理程序中创建了一个按钮..

                  private void Button_Click(object sender, RoutedEventArgs e)
                  {
                      TreeViewSelectedItemExBehavior.SetSelectedItemEx(trvwSs, trvwSs.Items[3]);
                      //TreeViewSelectedItemExBehavior.SetSelectedItemEx(trvwSs, null);
                  }
                  

                  希望这可以帮助某人:)

                  【讨论】:

                  • 它看起来像是一个可行的解决方案。我不喜欢它的是它是全球性的。这将导致内存泄漏,因为它存储了所有TreeViews。此外,您永远不会从您订阅的事件中取消注册。如果元素被删除,您的行为中仍然会保留对它们的引用。一些不错的工作可以从中取出东西,但整体上是泄漏的。
                  【解决方案16】:

                  我认为这是最简单的解决方案:

                  private void MouseDownEventProcessing(TreeNodeMouseClickEventArgs e)
                  {
                      tvEmployeeDirectory.SelectedNode = e.Node;
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-05-30
                    • 2010-11-07
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-12-25
                    相关资源
                    最近更新 更多