使用 StaticResource 和 MouseDown 处理程序时事件侦听器上的 Nullpointer 错误

Posted

技术标签:

【中文标题】使用 StaticResource 和 MouseDown 处理程序时事件侦听器上的 Nullpointer 错误【英文标题】:Nullpointer error on event listeners when using StaticResource and MouseDown handler 【发布时间】:2012-10-28 09:08:37 【问题描述】:

当我在 Rectangle 上使用 StaticResource 转换器为其背景着色,同时在 DataTemplate 中的另一个组件上使用 MouseDown 处理程序时,我遇到了一个非常奇怪的错误情况。如果我将代码缩小一点,这就是重现错误所必需的:

在顶部我有这些资源,其中一个指向一个转换器,该转换器从绑定中获取布尔值并将其转换为填充背景颜色):

<Window.Resources>
 <vm:DesktopViewModel x:Key="DesktopVM" />
 <vm:BooleanToColorConverter x:Key="converter" />
</Window.Resources>

稍后在同一个 xaml 文件中,我使用它迭代了一个警报对象列表(我已经用 StackPanel 替换了网格布局并删除了一些其他组件以缩短代码示例,下面的这段代码 sn-p 仍然失败):

<ItemsControl ItemsSource="Binding Alarms">
 <ItemsControl.ItemTemplate>
   <DataTemplate>                                                        
    <StackPanel>
     <Rectangle Height="20" Stroke="Black" Width="20" RadiusX="4" RadiusY="4" Fill="Binding Alarm, Converter=StaticResource converter"/>
     <Image Source="/MyNamespace;component/images/chart.png" Stretch="None" MouseDown="Image_MouseDown" Cursor="Hand"/>
    </StackPanel>
  </DataTemplate>
 </ItemsControl.ItemTemplate>
</ItemsControl>

如果我删除图像上的 MouseDown 处理程序,它运行得很好,并且在开始时没有空指针错误。如果我删除 Rectangle 中的 Fill 标记,则代码与 MouseDown 处理程序一起工作得很好!!! (并且处理程序也可以正常工作)。似乎 Fill 中的 StaticResource 引用搞砸了一些东西,导致定位鼠标处理函数失败?!?

请注意,创建窗口时它会失败,而不是在运行或单击任何内容时失败。

编辑:如果我将转换器替换为使用带有触发器的 StaticResource 的样式以执行与转换器相同的操作,则会遇到相同的空指针问题。很明显,属性中的 StaticResource 引用是罪魁祸首,但我不知道为什么它会影响事件侦听器。

组件的顺序也不重要。如果我将图像放在 Rectangle 之前,则错误完全相同。

【问题讨论】:

这里是我自己的问题的“解决方案”,我能够使用this solution 来遍历 windows 加载事件中的所有图像并以编程方式附加 mousedown 事件。每当我在数据模板中的某处使用静态资源或样式时,如果知道设置事件侦听器失败并返回空引用仍然会很高兴。 【参考方案1】:

我的猜测是问题出在您的转换器代码中,它没有考虑到它可以获得空值。

为什么会出现mouseDown的效果?可能它会导致图像元素在更早的时刻呈现,并在您的 ViewModel 尚未创建的时刻请求 Fill 属性的值。

信息太少,无法确定地说明这一点,但根据我的经验,不能正确处理空值的转换器可能是 WPF 开发中的一大难题。许多设计时不稳定性的根源在于没有正确处理空值的转换器。

【讨论】:

不,转换器代码工作正常。如果我删除 MouseDown 事件属性,程序运行良好。如果同时具有转换器和 MouseDown,则程序在初始化时停止,并在 MouseDown 事件上使用空引用。但是如果我移除转换器,那么 MouseDown 就可以正常工作了!它很奇怪!我尝试在 Converter 中添加一些空指针检查,但没有效果。在发生空引用错误之前,甚至不会调用转换器。 好的,如果你能提供一些额外的信息会有所帮助。你能在一个简单的项目中重现它吗?资源和事件处理程序是否都与 Window 相关联?还是它们分布在不同的资源字典中?

以上是关于使用 StaticResource 和 MouseDown 处理程序时事件侦听器上的 Nullpointer 错误的主要内容,如果未能解决你的问题,请参考以下文章

[WPF]静态资源(StaticResource)和动态资源(DynamicResource)

[WPF]静态资源(StaticResource)和动态资源(DynamicResource)

StaticResource和DynamicResource

DynamicResource 和 StaticResource

wpf中staticresource和dynamicresource有啥区别

如何在 Windows Phone 8 中使用 ValueConverter 作为 StaticResource