新添加的项目将添加到集合中,但不会添加到treeViewItems中

时间:2014-10-04 09:00:31

标签: c# wpf treeview

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

当我右键单击任何TreeViewItem时,我得到一个ContextMenu,它有一个选项可以在用户右键单击的Item下添加一个新的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的子项。

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

最后当计算机完成任务时,我可以在TreeView中看到newAddedCity。

更新:

这是我的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, "");
}

2 个答案:

答案 0 :(得分:1)

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;
    }
}

答案 1 :(得分:0)

mvvm方式是将新项目添加到基础集合而不是树视图。

   public OberservableCollection<City> MyCollection {get;set;}

   this.MyCollection.Add(getNewlyAddedCity(ServiceLocator.Instance.Cities));

xaml

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