Use*_*979 0 c# wpf tabcontrol tabitem
我的TabControl中有多个TabItems; tabItem1,tabItem2,tabItem3 ......这些都是
CloseableTabItem.
如果我在tabItem1中添加一个节点并按一个按钮为该节点创建一个subGraph模型,那么
同一节点应该在tabItem2中出现一个按钮; 以便
tabItem2-Header = nodeName和nodeName = tabItem1-Header.
如果我按下tabitem2中节点的按钮,则应该关注tabitem1.如果我关闭
tabItem1并按下相同的Button tabItem1应该再次加载(这发生在
SubGraphButton_Click).
你看到这段代码有问题吗?
private void ChildNode_Click(object sender, RoutedEventArgs args)
{
System.Windows.Controls.Button button = (System.Windows.Controls.Button)sender;
Node node = Part.FindAncestor<Node>(button);
MyNodeData nodeData = node.Data as MyNodeData;
foreach (TabItem item in tabControl.Items)
{
if (nodeData.Text == item.Header.ToString())
{
item.Focus();
}
else if (nodeData.Text != item.Header.ToString())
{
SubGraphButton_Click(sender, args);
}
}
}
private void SubGraphButton_Click(object sender, RoutedEventArgs args)
{
string activeDirectory = @"X:\SubGraph\";
string[] files = Directory.GetFiles(activeDirectory);
foreach (string fileName in files)
{
FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
System.Windows.Controls.Button button = (System.Windows.Controls.Button)sender;
Node node = Part.FindAncestor<Node>(button);
MyNodeData nodeData = node.Data as MyNodeData;
if (node != null)
{
if (nodeData.Text + ".epk" == fileName.Substring(12, fileName.Length - 12) && !tabControl.Items.Contains(tabItem1))
{
tabControl.Items.Add(tabItem1);
tabItem1.Focus();
var model = new MyGraphLinksModel();
model.Modifiable = true;
model.HasUndoManager = true;
activateDiagram(myDiagram1);
activeDiagram.Model = model;
model.Name = fileName.Substring(12, fileName.Length - 12);
model.Name = model.Name.Substring(0, model.Name.Length - 4);
tabItem1.Header = model.Name;
activeDiagram.PartManager.UpdatesRouteDataPoints = false;
StreamReader reader = new StreamReader(file);
string contents = reader.ReadToEnd();
XElement root = XElement.Parse(contents);
activeDiagram.LayoutCompleted += LoadLinkRoutes;
model.Load<MyNodeData, MyLinkData>(root, "MyNodeData", "MyLinkData");
}
}
}
Run Code Online (Sandbox Code Playgroud)
当修改集合处于修改过程中时,很可能会导致错误.错误的类型及其可能性往往根据底层集合的实际情况而有所不同.修改一个List迭代它很可能会给你很多错误(如果你经常修改它会多关闭一个错误)并且可能会超出边界错误.修改a LinkedList可能会导致空指针异常,无限循环,访问不存在的项等,但可能性要小得多.
因为在一般情况下,问题的可能性相当高,这些问题的影响也相当高,并且难以诊断实际出错的地方(以及在哪里)C#选择在您尝试迭代时抛出异常在迭代期间修改的集合.这样你就不会遇到奇怪的,意想不到的问题,这些问题直到他们根本原因的某个时候才会显现出来.
有几种不同的策略可用于避免此问题:
迭代与您真正想要修改的集合不同的集合.在某些情况下,这可以简单地通过ToList在序列上添加调用来完成,以便将其移动到新集合中; 在执行此操作时,正在迭代的集合与正在修改的集合是分开的,因此没有错误.
您可以避免修改foreach循环内部的实际集合.常见的例子是创建一个List或其他集合"修改,使"无论是itemsToAdd,itemsToRemove等等,那么你可以添加/删除/无论对所有的循环后这些项目.(如果您只修改集合大小的一小部分,则此方法很有效.)
某些类型的集合可以"迭代"而不实际使用传统的迭代器(意味着foreach循环).例如,您可以List使用常规for循环迭代,只需在添加或删除项时修改(递增/递减)循环变量.这一点,如果正确完成,往往是一个有效的选择,但是很容易出错并出错,所以当其他选项(略微)效率较低时,它们是非性能密集型代码的非常好的选择,因为他们的简单.