New Added Item会添加到集合中,但不会添加到treeViewItems中

本文关键字:添加 treeViewItems Added New 集合 Item | 更新日期: 2023-09-27 18:25:35

我有一个TreeView。我为TreeViewItems定义了一个contextMenu。

当我右键单击任何TreeViewItem时,我会得到一个ContextMenu,它可以选择在用户右键单击的项目下添加新的TreeViewItem。

这是我的代码:

private void AddContextMenu_Click(object sender, RoutedEventArgs e)
{
    TreeViewItem treeViewItem = null;
    foreach (TreeViewItem tvItem in StaticHelpers.FindVisualChildren<TreeViewItem>(cityTreeView))
    {
        if (tvItem.Header == ServiceLocator.Instance.SelectedCity)
        {
            treeViewItem = tvItem;
            break;
        }
    }
    AddNewCity(ServiceLocator.Instance.SelectedCity);
    treeViewItem.IsExpanded = true;
    City newlyAddedCity = getNewlyAddedCity(ServiceLocator.Instance.Cities);
    foreach (TreeViewItem tvItem in StaticHelpers.FindVisualChildren<TreeViewItem>(cityTreeView))
    {
        if (tvItem.Header == newlyAddedCity)
        {
            treeViewItem = tvItem;
            break;
        }
    }
    this.RenameContextMenu_Click(treeViewItem, e);
}

现在,在上面的代码中,如果我在最后一个foreach循环上保留一个断点,我可以看到它循环通过所有父项和那些父项的IsExpanded设置为true的子项。

但我也注意到,当它循环遍历所有项目时,它不会在集合中获得newreAddedCity,因此在第二个循环tvItem.Header==newreAdded City永远不会变为true。

最后,当计算机完成任务时,我可以在TreeView中看到新添加的城市。

更新:

这是我的AddNewCity方法:

public static void AddNewCity(City parentCity)
{
    City lastAddedCity = ServiceLocator.Instance.Cities.Where(x => x.IsLastAdded == true).Select(x => x).FirstOrDefault();
    lastAddedCity.IsLastAdded = false;
    City newCity = new City()
                    {
                        Id = lastAddedCity.Id + 1,
                        IsLastAdded = true,
                        Name = "New City"
                    };
    ServiceLocator.Instance.Cities.Where(x => x.Id == parentCity.Id).FirstOrDefault().Children.Add(newCity);
    CityMethods.SaveNew(parentCity.Id, "");
}

New Added Item会添加到集合中,但不会添加到treeViewItems中

TreeViewItem是一个UI容器,当它出现在View中时生成。在代码中,您将IsExpanded设置为True,但UI调度器没有时间进行生成容器的处理,因为它忙于执行单击处理程序


若您有兴趣查看生成的项目,则需要在运行最后一个foreach循环之前给UI线程一些时间来处理它。

在优先级为Render的UI调度器上调用空委托 ,以便在优先级高于或等于Render的UI调度程序上排队的所有委托都有时间执行(UI刷新优先级渲染)

Dispatcher.Invoke((Action)(() => { }), DispatcherPriority.Render);

只需将此代码放在最后一个foreach循环之前,您就会看到断点被击中

Dispatcher.Invoke((Action)(() => { }), DispatcherPriority.Render);
foreach (TreeViewItem tvItem in StaticHelpers.FindVisualChildren<TreeViewItem>(cityTreeView))
{
    if (tvItem.Header == newlyAddedCity)
    {
        treeViewItem = tvItem;
        break;
    }
}

mvvm的方法是将一个新项添加到底层集合中,而不是添加到树视图中。

   public OberservableCollection<City> MyCollection {get;set;}
   this.MyCollection.Add(getNewlyAddedCity(ServiceLocator.Instance.Cities));

xaml

   <TreeView ItemsSource="{Binding MyCollection}"/>