列表框项目 returns 与 属性 与 children 冲突

ListBox Item returns conflicting property to children

所以我现在很困惑,希望另一双眼睛能看到我遗漏的东西,或者至少给我指明进一步挖掘的方向。提前抱歉,我不经常问快速简单的问题。

场景:巨大的 silverlight 解决方案,其中有一些不稳定的部分,他们希望在其基础上构建新功能,但不需要大量的努力重写或任何东西。其中之一是虚拟化的列表框。这个 ListBox 是许多不同事物的 parent,以我通常不希望看到的方式完成。因此,以伪形式对层次结构进行一些可视化;

ListBox (Parent)

-ListBoxItemTemplate --A user control that hosts a ContentControl where other UserControls are swapped out in it.

---Multiple other UserControls that get swapped out in the previous ContentControl at runtime based on numerous conditions.

----Within each nested UserControl there's often other nested ItemsControls and collections of sorts with their Item Template.

希望你对这个怪物有一定的了解,但如果没有,这里有一些更直观的东西可以帮助传达我要解决的问题;

这是我当前的问题。根据他们的需要,在不进行重大重构的情况下,我正在尝试制作柠檬水并使用 parent 列表框中的 SelectedItem bool 在其中一些 sub-view 用户控件中执行某些操作。

我通过对 parent ListBoxItem 的 IsSelected 的快速祖先抓取来执行此操作。我通过子用户控件的快速 {Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}} 执行此操作(xaml 明智)。

在大多数情况下都按预期工作,returns True/False 可以很好地完成它需要做的事情。但是,在某些情况下,当其他各种 UserControl 充当项目时,它可能 return True 作为 IsSelected 到第一级嵌套 UserControl,但 False 到其中一个 sub-nested UserControl。或相反亦然。有趣的是,它根本不一致。

例如说我加载了 20 个项目。所有这些都使用完全相同的嵌套控件结构。我会得到奇怪的结果,其中 18 个项目 return 正确,可能有 2 个 return 错误。这在基本解释中意味着我 select 一个 ListBoxItem。一切都按预期进行 returned,一切都按预期进行。但是,我将 select 来自同一列表的另一个 ListBoxItem,它使用所有完全相同的部分,最外层的 parent 元素将 return 属性 用于预期的 selected 项....但是列表中完全不同的项也将收到 属性。

或者帮助形象化。想象一下,您正在查看一个列表框,您 select 一个项目和里面的东西出现了。你 select 另一个和预期的一样的事情发生了。您 select 列表顶部的另一个项目,列表底部的项目将显示您已 select 编辑的操作。您想要 select 的项目仍将 return 聚焦并显示为聚焦,除了您未触及的完全不同的项目获得操作结果并在它应该为 False 时将 bool 抛出为 True。

希望我没有在这场混乱中失去你。我的问题是到底是什么导致了这种行为?是否为您敲响了警钟(除了明显的)?

那里的其他任何地方都没有使用其他 ListBox 控件。我什至不确定到底要寻找什么?也许这只是 Silverlight 中祖先关系绑定中的一个错误?也许是一些奇怪的命名冲突之类的?我不确定,故障排除已成为我生存的祸根,但考虑到这是否是我的选择,我的选择有限。我会把所有这些废话都撕掉,并以一种更有意义的方式去做。

无论如何,感谢你让我花点时间考虑这对任何人来说有多混乱。 :)

只是在此处添加一些附加信息。

FindAncestor、AncestorType 也会查看基 classes。鉴于 ListBoxItem 是 ComboBoxItem 和 ListViewItem 的基础 class,它可能从不正确的控件中获取值。

对我来说,这听起来像是你的祖先类型链(这个术语完全是编造的)对于不同的项目看起来不同,因此你的祖先绑定产生了一些项目的祖先,这不是预期的(不同级别的层次结构)。

您可以尝试以下方法: 将 BindableObjectReference 添加到 ItemTemplateItemContainerStyle.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 ) );
}

如果这不起作用:另一个原因可能是虚拟化。尝试禁用虚拟化,看看问题是否仍然存在。