在用户控件 WPF 中使用数据模板选择器时抛出空引用异常
Null Reference Exception being thrown when using a data template selector in a user control WPF
您好,我遇到了一个问题,即在我的 xaml 中为使用数据模板选择器的用户控件抛出空引用异常,老实说,我不确定为什么。这是下面的代码,我们将不胜感激。
UPDATE 它只发生在设计时而不是 运行 时间
数据模板选择器代码:
using System.Windows;
using System.Windows.Controls;
using UI.ViewModel;
namespace UI.DataTemplateSelectors
{
public class CouponViewerDataTemplateSelector : DataTemplateSelector
{
public DataTemplate coupon1DataTemplateSelector { get; set; }
public DataTemplate coupon2DataTemplateSelector { get; set; }
public DataTemplate coupon3DataTemplateSelector { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item == null)
return null;
var CouponViewerViewModel = (CouponViewerViewModel)item;
switch (CouponViewerViewModel.Coupon.CouponBarcode )
{
case "994460":
return Coupon1DataTemplateSelector;
case "994470":
return Coupon2DataTemplateSelector;
case "994480":
return Coupon3DataTemplateSelector;
}
return null;
}
}
}
Xaml(我折叠了不同的 DataTemplates 代码,因为 xaml 文件很大)
<UserControl x:Class="UI.View.CouponViewerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModel="clr-namespace:UI.ViewModel"
xmlns:converter="clr-namespace:UI.View.Converter"
xmlns:converters="clr-namespace:UI.Converters"
xmlns:Web="clr-namespace:Web;assembly=Web"
xmlns:dataTemplateSelectors="clr-namespace:UI.DataTemplateSelectors"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModel:CouponViewerViewModel, IsDesignTimeCreatable=True}"
Height="1018" Width="720">
<UserControl.Resources>
<converter:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
<converters:AppendCharToBeginningAndEndOfStringConverter x:Key="AppendCharToBeginningAndEndOfStringConverter"/>
<converters:HexToBackgroundColourConverter x:Key="HexToBackgroundColourConverter"/>
<converters:HexToForegroundColourConverter x:Key="HexToForegroundColourConverter"/>
<converters:MaxCharcterSelectionNameConverter x:Key="MaxCharcterSelectionNameConverter"/>
<converters:DateTimeToSplitDataGridConverter x:Key="DateTimeToSplitDataGridConverter"/>
<converters:HeaderFormatterConverter x:Key="HeaderFormatterConverter"/>
<DataTemplate x:Key="Coupon1DataTemplateSelector" ...>
<DataTemplate x:Key="Coupon2DataTemplateSelector" ...>
<DataTemplate x:Key="Coupon3DataTemplateSelector" ...>
<dataTemplateSelectors:CouponViewerDataTemplateSelector
Coupon1DataTemplateSelector="{StaticResource Coupon1DataTemplateSelector}"
Coupon2DataTemplateSelector="{StaticResource Coupon2DataTemplateSelector}"
Coupon3DataTemplateSelector ="{StaticResource Coupon3DataTemplateSelector}"
x:Key="CouponViewerDataTemplateSelector" />
</UserControl.Resources>
<StackPanel>
<StackPanel x:Name="StackPanelToPrint">
<StackPanel.ContextMenu >
<ContextMenu>
<MenuItem Header="Print" Click="PrintCurrentForm" />
<MenuItem Header="OverLay Image" Command="{Binding Path=OverlayImageToCouponViewerCommand }" />
</ContextMenu>
</StackPanel.ContextMenu>
<Grid Margin="0,0,0,0">
<TextBlock Text="{Binding DesignTimeError}" Visibility="{Binding DesignTimeError, Converter={StaticResource EmptyStringToVisibilityConverter}}" Grid.ColumnSpan="2" Margin="0,0,0,34" />
<Canvas Grid.ColumnSpan="2" Margin="0,0,0,0">
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="11" Canvas.Top="128" />
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="742.5" Canvas.Top="128" />
<TextBlock Canvas.Left="338" FontSize="9" Foreground="Red" Canvas.Top="1046" Text="{Binding Path=MarkSenseCoupon.CouponBarcode}" />
<TextBlock FontFamily="Free 3 Of 9" Canvas.Left="24" Canvas.Top="1026" FontSize="110" Height="15" Text="{Binding Path=Coupon.CouponBarcode, Converter={StaticResource AppendCharToBeginningAndEndOfStringConverter}}"/>
<TextBlock Canvas.Left="409" FontSize="9" Foreground="Red" Canvas.Top="1046" Text="{Binding Path=MarkSenseCoupon.CouponInstance}" />
<TextBlock FontFamily="Free 3 of 9" Canvas.Left="409" Canvas.Top="1026" FontSize="110" Height="15" Text="{Binding Path=Coupon.CouponInstance, Converter={StaticResource AppendCharToBeginningAndEndOfStringConverter}}"/>
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="11.5" Canvas.Top="1043" />
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="742.5" Canvas.Top="1043" />
</Canvas>
<Image Canvas.ZIndex="1" Source="{Binding Coupon.OverlayImage}" Margin="0,-21,-76,108" Stretch="Fill" x:Name="PrintImageContextMenu" />
<StackPanel Margin="-105,146,66,0" Height="900" VerticalAlignment="Top" >
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource CouponViewerDataTemplateSelector}" />
</StackPanel>
</Grid>
</StackPanel>
</StackPanel>
</UserControl>
堆栈跟踪:
at UI.DataTemplateSelectors.CouponViewerDataTemplateSelector.SelectTemplate(Object item, DependencyObject container)
at System.Windows.Controls.ContentPresenter.ChooseTemplate()
at System.Windows.Controls.ContentPresenter.EnsureTemplate()
at System.Windows.Controls.ContentPresenter.OnPreApplyTemplate()
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.UIElement.UpdateLayout()
属性 名称区分大小写。
public DataTemplate coupon1DataTemplateSelector { get; set; }
对比
Coupon1DataTemplateSelector="{StaticResource Coupon1DataTemplateSelector}"
在我之前一直从事此工作的我的同事在我没有注意到的情况下将这行代码添加到 ViewModel,这导致了所有问题,因为它在设计时数据加载之前就返回了
public CouponViewerViewModel()
{
if (DesignerProperties.IsInDesignMode == true)
{
return;
}
if (DesignerProperties.IsInDesignMode)
{
LoadDesignTimeData();
}
}
最后对一个愚蠢的问题表示歉意
您好,我遇到了一个问题,即在我的 xaml 中为使用数据模板选择器的用户控件抛出空引用异常,老实说,我不确定为什么。这是下面的代码,我们将不胜感激。
UPDATE 它只发生在设计时而不是 运行 时间
数据模板选择器代码:
using System.Windows;
using System.Windows.Controls;
using UI.ViewModel;
namespace UI.DataTemplateSelectors
{
public class CouponViewerDataTemplateSelector : DataTemplateSelector
{
public DataTemplate coupon1DataTemplateSelector { get; set; }
public DataTemplate coupon2DataTemplateSelector { get; set; }
public DataTemplate coupon3DataTemplateSelector { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item == null)
return null;
var CouponViewerViewModel = (CouponViewerViewModel)item;
switch (CouponViewerViewModel.Coupon.CouponBarcode )
{
case "994460":
return Coupon1DataTemplateSelector;
case "994470":
return Coupon2DataTemplateSelector;
case "994480":
return Coupon3DataTemplateSelector;
}
return null;
}
}
}
Xaml(我折叠了不同的 DataTemplates 代码,因为 xaml 文件很大)
<UserControl x:Class="UI.View.CouponViewerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModel="clr-namespace:UI.ViewModel"
xmlns:converter="clr-namespace:UI.View.Converter"
xmlns:converters="clr-namespace:UI.Converters"
xmlns:Web="clr-namespace:Web;assembly=Web"
xmlns:dataTemplateSelectors="clr-namespace:UI.DataTemplateSelectors"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModel:CouponViewerViewModel, IsDesignTimeCreatable=True}"
Height="1018" Width="720">
<UserControl.Resources>
<converter:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
<converters:AppendCharToBeginningAndEndOfStringConverter x:Key="AppendCharToBeginningAndEndOfStringConverter"/>
<converters:HexToBackgroundColourConverter x:Key="HexToBackgroundColourConverter"/>
<converters:HexToForegroundColourConverter x:Key="HexToForegroundColourConverter"/>
<converters:MaxCharcterSelectionNameConverter x:Key="MaxCharcterSelectionNameConverter"/>
<converters:DateTimeToSplitDataGridConverter x:Key="DateTimeToSplitDataGridConverter"/>
<converters:HeaderFormatterConverter x:Key="HeaderFormatterConverter"/>
<DataTemplate x:Key="Coupon1DataTemplateSelector" ...>
<DataTemplate x:Key="Coupon2DataTemplateSelector" ...>
<DataTemplate x:Key="Coupon3DataTemplateSelector" ...>
<dataTemplateSelectors:CouponViewerDataTemplateSelector
Coupon1DataTemplateSelector="{StaticResource Coupon1DataTemplateSelector}"
Coupon2DataTemplateSelector="{StaticResource Coupon2DataTemplateSelector}"
Coupon3DataTemplateSelector ="{StaticResource Coupon3DataTemplateSelector}"
x:Key="CouponViewerDataTemplateSelector" />
</UserControl.Resources>
<StackPanel>
<StackPanel x:Name="StackPanelToPrint">
<StackPanel.ContextMenu >
<ContextMenu>
<MenuItem Header="Print" Click="PrintCurrentForm" />
<MenuItem Header="OverLay Image" Command="{Binding Path=OverlayImageToCouponViewerCommand }" />
</ContextMenu>
</StackPanel.ContextMenu>
<Grid Margin="0,0,0,0">
<TextBlock Text="{Binding DesignTimeError}" Visibility="{Binding DesignTimeError, Converter={StaticResource EmptyStringToVisibilityConverter}}" Grid.ColumnSpan="2" Margin="0,0,0,34" />
<Canvas Grid.ColumnSpan="2" Margin="0,0,0,0">
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="11" Canvas.Top="128" />
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="742.5" Canvas.Top="128" />
<TextBlock Canvas.Left="338" FontSize="9" Foreground="Red" Canvas.Top="1046" Text="{Binding Path=MarkSenseCoupon.CouponBarcode}" />
<TextBlock FontFamily="Free 3 Of 9" Canvas.Left="24" Canvas.Top="1026" FontSize="110" Height="15" Text="{Binding Path=Coupon.CouponBarcode, Converter={StaticResource AppendCharToBeginningAndEndOfStringConverter}}"/>
<TextBlock Canvas.Left="409" FontSize="9" Foreground="Red" Canvas.Top="1046" Text="{Binding Path=MarkSenseCoupon.CouponInstance}" />
<TextBlock FontFamily="Free 3 of 9" Canvas.Left="409" Canvas.Top="1026" FontSize="110" Height="15" Text="{Binding Path=Coupon.CouponInstance, Converter={StaticResource AppendCharToBeginningAndEndOfStringConverter}}"/>
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="11.5" Canvas.Top="1043" />
<Rectangle Fill="Black" Width="8.5" Height="8.5" Canvas.Left="742.5" Canvas.Top="1043" />
</Canvas>
<Image Canvas.ZIndex="1" Source="{Binding Coupon.OverlayImage}" Margin="0,-21,-76,108" Stretch="Fill" x:Name="PrintImageContextMenu" />
<StackPanel Margin="-105,146,66,0" Height="900" VerticalAlignment="Top" >
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource CouponViewerDataTemplateSelector}" />
</StackPanel>
</Grid>
</StackPanel>
</StackPanel>
</UserControl>
堆栈跟踪:
at UI.DataTemplateSelectors.CouponViewerDataTemplateSelector.SelectTemplate(Object item, DependencyObject container)
at System.Windows.Controls.ContentPresenter.ChooseTemplate()
at System.Windows.Controls.ContentPresenter.EnsureTemplate()
at System.Windows.Controls.ContentPresenter.OnPreApplyTemplate()
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.UIElement.UpdateLayout()
属性 名称区分大小写。
public DataTemplate coupon1DataTemplateSelector { get; set; }
对比
Coupon1DataTemplateSelector="{StaticResource Coupon1DataTemplateSelector}"
在我之前一直从事此工作的我的同事在我没有注意到的情况下将这行代码添加到 ViewModel,这导致了所有问题,因为它在设计时数据加载之前就返回了
public CouponViewerViewModel()
{
if (DesignerProperties.IsInDesignMode == true)
{
return;
}
if (DesignerProperties.IsInDesignMode)
{
LoadDesignTimeData();
}
}
最后对一个愚蠢的问题表示歉意