WPF树视图仅展开第一个节点和选定的项

本文关键字:节点 第一个 视图 WPF | 更新日期: 2023-09-27 17:57:45

我在WPF中使用树视图,并且我不想在重新加载绑定集合时丢失状态(展开和聚焦)。

在第一次加载时,很容易只扩展第一个节点,我使用以下代码:

    private void ExpandFirstNodeTree()
    {
        foreach (var item in TreeviewModel.Items)
        {
            TreeViewItem itm = (TreeViewItem)TreeviewModel.ItemContainerGenerator.ContainerFromItem(item);
            if (itm == null) continue;
            itm.IsExpanded = true;
        }
    }

我使用DependencyPropertity来选择项目。我浏览TreeView,找到TreeViewItem并设置项";IsSelected";属性设置为true。

private static readonly DependencyProperty SelectedEntityCodeProperty =
        DependencyProperty.Register(PropertyHelper.GetName((EntitiesTreeview e) => e.SelectedEntityCode), typeof (string), typeof (EntitiesTreeview));
    public string SelectedEntityCode
    {
        get { return (string) GetValue(SelectedEntityCodeProperty); }
        set { SetValue(SelectedEntityCodeProperty, value); }
    }
    public EntitiesTreeview()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(EntitiesTreeview_Loaded);
    }
    private void LoadSelectedItem()
    {
        if ((!string.IsNullOrEmpty(SelectedEntityCode))
            && (TreeviewEntity.SelectedItem == null))
            ChangeSelectedItem<ENTITY>(SelectedEntityCode, TreeviewEntity);
    }
    private bool ChangeSelectedItem<T>(string entityCode, ItemsControl itemsControl) where T : ENTITYBASE
    {
        if (itemsControl != null)
        {
            foreach (var item in itemsControl.Items)
            {
                var currentContainer = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
                if ((currentContainer != null)
                    && (item is T)
                    && ((item as T).CCODE == entityCode))
                {
                    currentContainer.IsSelected = true;
                    var selectMethod = typeof (TreeViewItem).GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance);
                    selectMethod.Invoke(currentContainer, new object[] {true});
                    return true;
                }
                if (ChangeSelectedItem<T>(entityCode, currentContainer))
                    return true;
            }
        }
        return false;
    }

我的问题是,当我重新加载项目集合时,焦点会丢失(选定的项目),展开的项目会折叠。如何分离绑定项和ui?最后一点,我想以编程方式设置所选项目。相关性属性更改时,如何重新加载所选项目?


我已经看过josh smith的解决方案(http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx),但我不想使用ViewModel集合进行绑定。我有不同的对象类型要绑定,使用ViewModel会很痛苦。。。IMO:)

WPF树视图仅展开第一个节点和选定的项

我有不同的对象类型要绑定,使用ViewModel会很痛苦。。。IMO-

事实上,您现在遇到的问题恰恰说明了使用视图模型太痛苦的原因。

如果构造视图模型,则可以在视图模型类中实现IsSelectedIsExpanded属性。然后可以将TreeViewItem的相关属性绑定到它们。执行此操作后,对UI中状态的更改将反映在视图模型数据中,如果从数据中重新加载UI,则状态中的更改将保留。

这是实现你想要实现的目标的最简单的方法。作为一个额外的好处,您可以丢弃上面发布的令人费解的难以测试的代码的最后一部分。