c# – ListBox Item向子节点返回冲突属性

所以此刻我很难过,并希望另一双眼睛能够捕捉到我所缺少的东西,或者至少让我指向一个可以进一步挖掘的方向.提前抱歉,我不经常问快速简单的问题.

场景:巨大的Silverlight解决方案,带有一些不稳定的部分,它们希望用新功能构建,但没有大量的重写或任何东西.其中一个是虚拟化ListBox.这个ListBox是许多不同事物的父级,我通常不希望看到它们按照它们的方式完成.所以在伪中给出一点层次的可视化;

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.

希望我仍然对这个怪物有所了解,但如果没有,这里有一些更直观的东西来帮助传达我所遇到的问题;
《c# – ListBox Item向子节点返回冲突属性》

所以这是我目前的问题.基于他们想要的东西,没有做一些重大的重构,我正在尝试制作柠檬水并使用父列表框中的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并显示为焦点,除了您未触摸的完全不同的项目获取操作结果并且当它应该为False时将bool抛出True.

希望我没有在这个混乱中失去你.我的问题是,到底是什么导致了这种行为?为你做任何警钟(除了明显的警钟)吗?

在那里的其他任何地方都没有使用其他ListBox控件.我甚至不确定要找什么?也许这只是Silverlight中祖先关系绑定中的一个错误?也许是一些奇怪的命名碰撞或什么?我不确定,故障排除已经成为我存在的祸根,但考虑到它是我的选择,我对选项的限制.我把所有这些废话都撕掉了,并以更有意义的方式进行.

无论哪种方式,感谢让我借用一些大脑时间,考虑到我确信这对任何人来说都是多么令人困惑. 🙂

最佳答案 对我而言,这听起来像你的祖先类型链(这个术语是完全组成的)对于不同的项目看起来不同,因此你的祖先绑定产生一些项目是一个不期望的祖先(层次结构中的不同级别).

《c# – ListBox Item向子节点返回冲突属性》

您可以尝试以下方法:
将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 ) );
}

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

点赞