找不到绑定源

当我添加新选项卡然后将其删除时,我的应用程序将抛出此错误消息:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.TabControl', AncestorLevel='1''. BindingExpression:Path=TabStripPlacement; DataItem=null; target element is 'TabItem' (Name=''); target property is 'NoTarget' (type 'Object') 

如果我添加了一个新选项卡,切换到另一个选项卡,切换回来然后删除它,它没有抱怨。 看起来像是在切换过程中“更新”的东西,但我无法弄清楚是什么以及如何修复它们。

这是我的xaml文件:

                     

这是我添加/删除标签的代码:

 public void AddNewTab() { NewCourseName ncn = new NewCourseName(); ncn.Owner = mainWindow; ncn.ShowDialog(); if (ncn.courseName != null) { MyHomeworkModel newTab = new MyHomeworkModel(); newTab.Header = ncn.courseName; newTab.Text = ""; AllTabs.Add(newTab); SelectedTab = newTab; } } public void RemoveTab() { DropCourseConfirmation dcc = new DropCourseConfirmation(); dcc.Owner = mainWindow; dcc.ShowDialog(); if (dcc.drop == true) { int index = AllTabs.IndexOf(SelectedTab); AllTabs.Remove(SelectedTab); if (AllTabs.Count > 0) { if (index == 0) { SelectedTab = AllTabs[0]; } else { SelectedTab = AllTabs[--index]; } } else { SelectedTab = null; } } } 

如果您需要查看更多代码,请与我们联系。 提前致谢。

正如Zarat所提到的,Windows 8中TabItem的默认样式具有在删除后触发的触发器,然后查找现在缺少的TabControl。 我认为这是一个bug,因为添加和删除TabItems是一个非常常见的场景不是吗?

我发现作为一种解决方法,可以删除TabItem的模板:

 foreach (var item in TabControl.Items) { var tabitem = item as TabItem; // if this is the item to remove tabitem.Template = null; TabControl.Items.Remove(item); } 

在我的场景中看起来没问题,因为我不会再使用TabItem了。

我还尝试清除模板的触发器集合或清除其触发器的conditons集合,但不允许这样做(错误)。
似乎也没有办法禁用触发器。

这不是一个bug,只是来自WPF绑定引擎的一些噪音,当它更新绑定并注意到某些内容丢失时。 不幸的是,它无法沉默。 也许它值得报道Connect或MSDN论坛,但不要指望任何快速反应。

您注意到的消息来自aero2.normalcolor.xaml – Windows 8的默认样式。如果您在默认位置安装了VS 2012 SP 2,可以在此处找到它们:C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \混合\ SystemThemes \ WPF

在这个文件中有一些MultiDataTriggers,其条件是通过RelativeSource检查TabStripPlacement,查找父TabControl。 因此,当您从TabControl中删除TabItem时,绑定引擎可能会尝试更新绑定并找到父项缺失,并记录警告。 这完全没问题,因为TabItem被移除了,你不再关心样式(如果你再次添加它,绑定将被重新评估,一切都会很好)。

现在我不知道为什么他们为Windows 8的RelativeSource检索TabStripPlacement,因为TabItem本身似乎带有其父项TabStripPlacement的副本。 所有其他默认样式都使用TabStripPlacement的本地副本进行绑定。 因此,如果您喜欢冒险,您可能希望将样式复制到您自己的资源字典中,并在调试期间使用“固定”版本以减少噪音……