wpf从嵌套的datatemplate中引用值转换器(导致空引用异常)

时间:2013-10-07 20:18:41

标签: wpf nested datatemplate nullreferenceexception ivalueconverter

我遇到了来自嵌套datatemplate (ListViewItems)的IValueConverters问题。

我有包含其他对象和对象列表列表的复杂(列表)对象(太多源代码可以放在这里)...

除了更深层次的嵌套级别的IValueConverter实现外,一切正常......

简化和缩短XAML:

    <Window x:Class="XXXX.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:converter="clr-namespace:XXXX.Converter"
    Width="800"
    Height="600"
    Icon="/Images/Icons/Calendar.ico"
    Loaded="Window_Loaded"
    Style="{StaticResource WindowDefaultStyle}"
    WindowState="Maximized">
<Window.Resources>
    <!--  <converter:ValueToVisibilityConverter x:Key="ValueToVisibility" />  -->
    <converter:PercentageConverter x:Key="PercentFromValue" />
    <converter:SubtractionConverter x:Key="SubstractFromValue" />
    <converter:SingleTextLineConverter x:Key="inSingleLine" />
    <converter:B2VConverter x:Key="B2V" />
</Window.Resources>

    <Grid Name="grid_Supplier">
        <ListView Name="listview_Product"
            Grid.Row="1"
            Height="{Binding ElementName=grid_Supplier,
            Path=ActualHeight,
            Converter={StaticResource SubstractFromValue},
            ConverterParameter=60}"
            ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
            AncestorType=Window},Path=SuppliersProducts}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ListView Name="listview_CM"
                                Width="{Binding ElementName=grid_SupplierProduct,
                                Path=ActualWidth,
                                Converter={StaticResource PercentFromValue},
                                ConverterParameter=80}"
                                ItemsSource="{Binding CM}">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <ListView Name="listview_Comments"
                                            ItemsSource="{Binding Comments}">
                                            <ListView.ItemTemplate>
                                                <DataTemplate>
                                                    <TextBlock
                                                            Text="{Binding Comment.DueDate, StringFormat='dd.MM.yyyy'}"
                                                            Background="{Binding Status

,Converter = {StaticResource B2V}

}"/>
                                                </DataTemplate>
                                            </ListView.ItemTemplate>
                                        </ListView>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                        </ListView>
                    </DataTemplate>
                </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>

正如您所看到的,有3个嵌套的ListView,“第一”级别的转换器(PercentFromValue)正常工作 - 使用Binding和Parameter ...

一旦Binding的转换器部分( StaticResource B2V )存在,我的问题就出现在下一个嵌套“级别”,运行时空引用异常上升(没有进一步的解释或嵌套异常)信息是可用的... - 但是一旦转换器消失就没有问题了......没有例外,但也没有背景 - 正如所期望的那样......)

我试图创建“listview资源”部分,但也有Null引用异常上升(我假设在这种情况下找不到路径的“converter:”部分。

由于我正在使用Backgroundworker(gui上显示的信息是从9个以上的相关表中收集的),因此不可能将Brush传递给gui(继承自Dispatcher并导致“DependencySource必须在与DependencyProperty相同的线程中创建” “错误)。

现在我正在准备背景中的所有内容,并在同一个线程中仅添加Background-Brush作为解决方法,但它很难看......

使用转换器会好得多,但如何从嵌套的datatemplate中引用它?

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我已经通过在Window.Resources中移动DataTemplates并使它们相互引用来解决它,从而创建了“扁平”结构而不是直接嵌套......

<Window x:Class="XXXX.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:converter="clr-namespace:XXXX.Converter"
   Width="800"
   Height="600"
   Icon="/Images/Icons/Calendar.ico"
   Loaded="Window_Loaded"
   Style="{StaticResource WindowDefaultStyle}"
   WindowState="Maximized">
<Window.Resources>
   <converter:PercentageConverter x:Key="PercentFromValue" />
   <converter:SubtractionConverter x:Key="SubstractFromValue" />
   <converter:SingleTextLineConverter x:Key="inSingleLine" />
   <converter:B2VConverter x:Key="B2V" />

   <DataTemplate x:Key="CommentTemplate">
<TextBlock Text="{Binding Comment.DueDate, StringFormat='dd.MM.yyyy'}" Background="{Binding Status, Converter={StaticResource B2V}}"
   </DataTemplate>

   <DataTemplate x:Key="CommentsTemplate">
<ListView Name="listview_Comments"
          ItemsSource="{Binding Comments}"
            ItemTemplate={StaticResource CommentTemplate} />
   </DataTemplate>


   <DataTemplate x:Key="CMTemplate">
        <ListView Name="listview_CM"
        Width="{Binding ElementName=grid_SupplierProduct,
        Path=ActualWidth,
        Converter={StaticResource PercentFromValue},
        ConverterParameter=80}"
        ItemsSource="{Binding CM}"
        ItemTemplate={StaticResource CommentsTemplate} />
   </DataTemplate>

</Window.Resources>

<Grid Name="grid_Supplier">
    <ListView Name="listview_Product"
        Grid.Row="1"
        Height="{Binding ElementName=grid_Supplier,
        Path=ActualHeight, Converter={StaticResource SubstractFromValue},
        ConverterParameter=60}"
        ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
        AncestorType=Window},Path=SuppliersProducts}"
        ItemTemplate={StaticResource CMTemplate}/>
</Grid>

注意将最里面的模板定义为第一个,依此类推。否则,将找不到模板。

由于文件的这种结构,我们在一个级别上都“平坦”,并且找到并引用了转换器。