当在DataTemplate中使用ListView.View时,它的值为null。

4
我想创建一个WPF UserControl,可以以不同的布局方式显示数据,基本上包括表格、GroupBox和带选项卡的TabControl。我希望该控件能够递归地托管自身。例如,我希望在其中一个单元格中显示一个GroupBox的表格,并在GroupBox内部再次使用表格布局。
为了实现这一点,我在XAML中使用了一个名为“GenericLayoutTemplateSelector”的模板选择器(TemplateSelector)作为顶级元素,并使用了不同的模板。对于表格布局,我希望使用Code Project上的示例“Binding a ListView to a Data Matrix”: http://www.codeproject.com/Articles/36462/Binding-a-ListView-to-a-Data-Matrix Code Project的示例很好用,但是当我将其用于我的上下文时,它失败了。由于我所做的唯一更改是将XAML放置在DataTemplate/TemplateSelector中,因此问题可能与此相关。
<DataTemplate x:Key="TableTemplate">
    <Border BorderThickness="2" BorderBrush="SteelBlue">
        <ListView x:Name="TableLayoutListView" tableLayout:ListViewExtension.MatrixSource="{Binding Converter={StaticResource ListToMatrixConverter}}">                    
            <ListView.View>
                <GridView>                           
                    <GridViewColumn DisplayMemberBinding="{Binding Path=[0]}" Header="Dummy" 
                         CellTemplateSelector="{DynamicResource GenericLayoutTemplateSelector}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Border>
</DataTemplate>

它在ListViewExtension.MatrixSource的内部,获取GridView的地方失败了:

private static void OnMatrixSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ListView listView = d as ListView;
    Matrix matrix = e.NewValue as Matrix;
    listView.ItemsSource = matrix;       
    GridView gridView = listView.View as GridView;
    DataTemplateSelector cellTemplateSelector = gridView.Columns.First().CellTemplateSelector;
listView.View为空。我可以在代码中创建GridView并将其分配给listView.View,但这样我就无法访问我想要用作GridView的CellTemplateSelector的GenericTemplateSelector。
有任何想法为什么listView.View为空以及我该怎么做?
编辑: SledgeHammer明确指出,我试图做的是一个糟糕的hack,它失败了。正确的方法是直接将GenericTemplateSelector传递给附加属性,而不是通过虚拟的GridView列。
我正在尝试找出一种使用多绑定的附加属性的方法。
<DataTemplate x:Key="TableTemplate">
    <Border BorderThickness="2" BorderBrush="SteelBlue">
        <ListView x:Name="TableLayoutListView">
            <tableLayout:ListViewExtension.MatrixSourceWithTemplateSelector>
                <MultiBinding Converter={StaticResource ListToMatrixConverter}>
                    <Binding Path="this" />
                    <Binding {DynamicResource GenericLayoutTemplateSelector}/>
                </MultiBinding>
            </tableLayout:ListViewExtension.MatrixSourceWithTemplateSelector>

然而,这不是有效的XAML。有什么想法可以将{DynamicResource GenericLayoutTemplateSelector}添加到多绑定中吗?

通过在ListToMatrixConverter类的Convert方法中设置断点,检查返回值。你是否在运行时期望了返回值? - Ramin Bateni
转换器按预期工作,并返回一个不为空且包含一些行和列的矩阵。 - Joe Kopp
1个回答

0
我猜测MatrixSource属性是在View属性之前被设置的。显然它们不能同时设置。处理MatrixSource和View的更改,调用一个公共方法并检查是否为null。

你是对的。这是关于设置器调用顺序的问题。然而,为MatrixSource更改和View更改创建一个公共方法并不符合所附属性MatrixSource的概念,这将需要从ListView派生。 - Joe Kopp
不是这样的。当您设置附加属性时,如果View为空,则等待View被设置并返回。您可以使用DependencyPropertyDescriptor.FromProperty() / AddValueChanged()附加到View更改“事件”。 - SledgeHammer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接