【问题标题】:MVVM - NullReferenceException when set ControlTemplate that has DataGridMVVM - 设置具有 DataGrid 的 ControlTemplate 时出现 NullReferenceException
【发布时间】:2012-10-25 07:18:44
【问题描述】:

在我的一个视图中,我有一个 ContentControl 绑定到同一页面中定义为资源的 DataTemplate。在其中,我通过设置在 dataTemplate 的触发器中声明的绑定属性,在运行时使用不同的 controlTemplates(四个)填充了一个控件:

    <DataTemplate x:Key="DeviceSetupDataTemplate">
        <Control x:Name="theControl" Template="{DynamicResource BanknotesReaderControlTemplate}" />
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding DeviceSetup.ShowBanknotesReaderControlTemplate, Source={StaticResource Locator}}" Value="true" >
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource BanknotesReaderControlTemplate}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding DeviceSetup.ShowCoinsReaderControlTemplate, Source={StaticResource Locator}}" Value="true" >
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource CoinsReaderControlTemplate}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding DeviceSetup.ShowHoppersControlTemplate, Source={StaticResource Locator}}" Value="true" >
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource HoppersControlTemplate}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding DeviceSetup.ShowCoinsCashBoxControlTemplate, Source={StaticResource Locator}}" Value="true" >
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource CoinsCashBoxControlTemplate}" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

...以及我的 Grid 中的内容控件:

<ContentControl ContentTemplate="{DynamicResource DeviceSetupDataTemplate}" Margin="5" />

在我的两个 ControlTemplates 中,我有一个 DataGrid,绑定到我的自定义对象列表(这里有一个):

    <ControlTemplate x:Key="BanknotesReaderControlTemplate" TargetType="{x:Type Control}">
        <Grid d:DesignWidth="772.02" d:DesignHeight="532.76" Margin="15,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="0.08*" />
                <RowDefinition Height="0.1*" />
                <RowDefinition Height="0.1*" />
                <RowDefinition Height="0.1*" />
                <RowDefinition Height="0.1*" />
                <RowDefinition Height="0.08*" />
                <RowDefinition Height="0.44*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="35*" />
                <ColumnDefinition Width="40*" />
                <ColumnDefinition Width="25*" />
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" >
                <Button Margin="0,3,10,3" Command="{Binding DeviceSetup.AddBanknoteType, Mode=OneWay, Source={StaticResource Locator}}" Content="{DynamicResource 442}" Width="85" Style="{DynamicResource DeviceSetupButtonStyle}" Height="Auto" Padding="2,1" />
                <Button Margin="0,3,10,3" Command="{Binding DeviceSetup.ChangeBanknoteType, Mode=OneWay, Source={StaticResource Locator}}" Content="{DynamicResource 444}" Width="85" Style="{DynamicResource DeviceSetupButtonStyle}" Padding="2,1" />
                <Button Margin="0,3" Command="{Binding DeviceSetup.DeleteBanknoteType, Mode=OneWay, Source={StaticResource Locator}}" Content="{DynamicResource 443}" Width="85" Style="{DynamicResource DeviceSetupButtonStyle}" Height="Auto" Padding="2,1" />
            </StackPanel>
            <DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Top" HorizontalContentAlignment="Center" AutoGenerateColumns="False" ScrollViewer.VerticalScrollBarVisibility="Hidden" Grid.Row="6" Grid.ColumnSpan="3" Margin="0,5" 
                      ItemsSource="{Binding DeviceSetup.BanknotesDetails, Source={StaticResource Locator}}" SelectedItem="{Binding DeviceSetup.SelectedBanknoteDetails, Source={StaticResource Locator}}" >
                <DataGrid.Columns>
                    <DataGridCheckBoxColumn Binding="{Binding IsEnabled}" Width="5*" />
                    <DataGridTextColumn Binding="{Binding Value}" IsReadOnly="True" Header="{DynamicResource 445}" Width="20*" ElementStyle="{DynamicResource SmallSizedTextBlockBlackPlusMatic}" />
                    <DataGridTextColumn Binding="{Binding Currency}" IsReadOnly="True" Header="{DynamicResource 446}" Width="25*" ElementStyle="{DynamicResource SmallSizedTextBlockBlackPlusMatic}" />
                    <DataGridTextColumn Binding="{Binding MoneyCode}" IsReadOnly="True" Header="{DynamicResource 447}" Width="50*" ElementStyle="{DynamicResource SmallSizedTextBlockBlackPlusMatic}" />
                </DataGrid.Columns>    
            </DataGrid>
        </Grid>    
    </ControlTemplate>

现在的问题是:在视图上,我有四个按钮通过命令连接到 viewModel,在其中我更改属性的 bool 值以更改控件模板的回调。 有时,似乎是随机的,当我将布尔属性设置为 true 以显示数据网格内部的控件模板时,我得到了 NullReferenceException。 此外,在异常的堆栈跟踪中,我找到了对 DataGridCellItemAutomationPeer 的引用......我认为这可以作为一个很好的调查起点,但我真的不知道该怎么做。

提前谢谢你..

【问题讨论】:

  • 我现在发现如果我在更改控件模板时选择数据网格的一行会​​系统地出现问题...

标签: wpf mvvm datagrid datatemplate


【解决方案1】:

找到了!!

我真的不解释为什么,但是如果我在更改 DataTemplate 之前将 DataGrid 的 IsEnabled 属性设置为 false,我不会收到任何异常。

所以我只是简单地绑定到数据网格的 IsEnabled,在更改为不同的 ControlTemplate 之前,我将属性设置为 false,然后在命令回调结束时设置为 true。

L.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    相关资源
    最近更新 更多