所以此刻我很难过,并希望另一双眼睛能够捕捉到我所缺少的东西,或者至少指出我要进一步挖掘的方向。提前抱歉,我不经常提出快速简单的问题。
场景:巨大的Silverlight解决方案带有一些不稳定的部分,它们需要使用新功能构建,但没有大量的重写或任何东西。其中一个是虚拟化ListBox。这个ListBox是许多不同事物的父级,我通常不希望看到它们按照它们的方式完成。所以在伪;
中给出层次结构的一点可视化ListBox(父级)
-ListBoxItemTemplate - 托管ContentControl的用户控件,其中其他UserControl在其中交换出来。
---多个其他UserControls在前一个被换出 ContentControl在运行时基于众多条件。
----在每个嵌套的UserControl中,通常有其他嵌套的ItemsControls和它们的项目模板的集合。
希望我对这个怪物仍然有所了解,但如果没有,这里有一些更直观的东西来帮助传达我所遇到的问题;
所以这是我目前的问题。基于他们想要的东西,没有做一些重大的重构,我正在尝试制作柠檬水并使用父列表框中的SelectedItem bool来执行某些子视图UserControls中的一些操作。
我使用快速祖先抓取父ListBoxItem的IsSelected来执行此操作。我通过子UserControls中的快速{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}
执行此操作(xaml wise)。
在大多数情况下,它会按预期工作,并返回True / False就可以完成它需要做的事情了。但是,在某些情况下,当其他各种UserControl充当项目时,它可能会将IsSelected返回到第一级嵌套UserControl,但对其中一个子嵌套UserControl返回False。或相反亦然。有趣的是,它根本不一致。
例如说我加载了20个项目。全部使用完全相同的嵌套控件结构。我会得到奇怪的结果,其中18个项目将返回True,也许2个返回False。在基本解释中意味着我选择一个ListBoxItem。一切都按预期返回,一切都按照预期的方式进行。但是,我将从同一个列表中选择另一个ListBoxItem,它使用所有完全相同的部分,最外层的父元素将返回预期的选定项目的属性....但是,列表上的完全不同的项目将收到财产也。。
或者帮助可视化。想象一下,你正在查看一个列表框,你选择一个项目,里面的东西出现了。你选择另一个,同样的事情发生了预期。您从列表顶部选择另一个,列表底部的项目将显示针对您所选内容的操作。你想要选择的项目仍然会返回Focused并显示为聚焦,除了你没有触及的完全不同的项目得到动作结果并且当它应该为假时将bool抛给True。
希望我没有在这个混乱中失去你。我的问题是,到底是什么导致了这种行为?对你来说,除了显而易见的事情之外,还有什么警钟会消失吗?
在那里的其他任何地方都没有使用其他ListBox控件。我甚至不确定要找什么?也许这只是Silverlight中祖先关系绑定中的一个错误?也许是一些奇怪的命名碰撞或什么?我不确定,故障排除已经成为我存在的祸根,但考虑到它是我的选择,我对选项的限制。我把所有这些废话都撕掉了,并以更有意义的方式进行。
无论哪种方式,感谢让我借用一些大脑时间,考虑到我确信这对任何人来说都是多么令人困惑。 :)
答案 0 :(得分:2)
对我而言,这听起来像你的祖先类型链(这个术语是完全组成的)对于不同的项目看起来不同,因此你的祖先绑定产生一些项目是一个不期望的祖先(层次结构中的不同级别)
您可以尝试以下方法:
将BindableObjectReference
添加到ItemTemplate
或您的ItemContainerStyle.Template
的资源中,并使用对此新添加资源的绑定替换您的祖先绑定。这样,您可以确保在层次结构中达到正确的级别。
<ListBox.ItemTemplate>
<DataTemplate>
<Grid...>
<Grid.Resources>
<BindableObjectReference x:Key="TopLevelListBoxItem"
Object="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}}"/>
</Grid.Resources>
...
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<MyNestedSubControl
...
Foo="{Binding Path=Object.IsSelected, Source={StaticResource TopLevelListBoxItem}}"
.../>
BindableObjectReference
的代码:
public class BindableObjectReference : DependencyObject
{
public object Object
{
get { return GetValue( ObjectProperty ); }
set { SetValue( ObjectProperty, value ); }
}
public static readonly DependencyProperty ObjectProperty =
DependencyProperty.Register( "Object", typeof( object ),
typeof( BindableObjectReference ), new PropertyMetadata( null ) );
}
如果这不起作用:另一个原因可能是虚拟化。尝试禁用虚拟化并查看问题是否仍然存在。
答案 1 :(得分:0)
在此处添加一些其他信息。
FindAncestor,AncestorType也将查看基类。鉴于ListBoxItem是ComboBoxItem和ListViewItem的基类,它可能从不正确的控件中获取值。