【问题标题】:ListView.View is null when used in DataTemplate在 DataTemplate 中使用时 ListView.View 为空
【发布时间】:2015-08-17 21:54:58
【问题描述】:

我想构建一个 WPF 用户控件,它可以在不同的布局中显示数据,基本上是表格、组框和带有选项卡的选项卡控件。我希望控件能够递归地托管自己。例如,我想在其中一个单元格中显示一个带有 groupbox 的表格,并在 groupbox 内再次显示表格布局。

为了实现这一点,我使用了 TemplateSelector(“GenericLayoutTemplateSelector”)作为 xaml 中具有不同模板的顶级元素。对于表格布局,我想在代码项目中使用示例“将 ListView 绑定到数据矩阵”:http://www.codeproject.com/Articles/36462/Binding-a-ListView-to-a-Data-Matrix

codeproject 示例工作正常,但是当我在上下文中使用它时它失败了。由于我所做的唯一更改是将 xaml 放入我认为的数据模板/模板选择器中,因此问题可能与此有关。

<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 为 null 以及我能做些什么?

编辑: 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} 进入多重绑定?

【问题讨论】:

  • 通过将breakpoint 放入其类的Convert 方法来检查来自ListToMatrixConverter 的返回值。您是否期望在运行时返回值?
  • 转换器按预期工作并返回一个不为空且包含一些行和列的矩阵。

标签: c# wpf listview


【解决方案1】:

我不得不猜测 MatrixSource 属性是在 View 属性之前设置的。显然,它们不能同时设置。处理 MatrixSource 和 View 的变化并调用一个通用方法并检查 null。

【讨论】:

  • 你是对的。这是二传手的顺序。但是,更改 MatrixSource 和 View 更改的通用方法不符合附加 MatrixSource 属性的概念,它需要从 ListView 派生。
  • 不是它没有。设置附加属性时,如果 View 为 null,则等待 View 设置并返回。您可以使用 DependencyPropertyDescriptor.FromProperty() / AddValueChanged() 附加到视图更改“事件”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 2021-05-05
  • 2021-09-20
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多