我有一个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, "");
}
答案 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}"/>