我有一个非常奇怪的错误案例,当我在Rectangle上使用StaticResource转换器为其背景着色并同时在DataTemplate中的旁边的另一个组件上使用MouseDown处理程序时,就出现了这种情况。如果我将代码缩小一点,这就是重现错误所需的:
在顶部我有这些资源,一个指向转换器,它从绑定中获取布尔值并将其转换为填充背景颜色):
<Window.Resources>
<vm:DesktopViewModel x:Key="DesktopVM" />
<vm:BooleanToColorConverter x:Key="converter" />
</Window.Resources>
稍后在同一个xaml文件中,我使用这个迭代一个Alarm对象列表(我已经用StackPanel替换了一个Grid布局,并删除了一些其他组件以获得更短的代码示例,下面的代码片段仍然失败):
<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处理程序,它就可以正常运行而不会在开始时出现nullpointer错误。如果我删除Rectangle中的Fill标签,代码可以正常使用MouseDown处理程序! (并且处理程序也可以正常工作)。看起来像Fill中的StaticResource引用搞乱了一些使定位鼠标处理函数失败的东西?!?
请注意,它在创建窗口时失败,而不是在运行或单击任何内容时失败。
编辑:如果我使用带有触发器的StaticResource将样式替换为转换器,并且转换器执行相同操作,则会出现相同的nullpointer问题。很明显,属性中的StaticResource引用是罪魁祸首,但我不知道它为什么会影响事件监听器。
此外,组件的顺序也无关紧要。如果我将图像放在矩形之前,则错误完全相同。
答案 0 :(得分:1)
我的猜测是问题在于您的转换器代码,它没有考虑到它可以获得空值。
为什么mouseDown会有效果?可能它会导致在较早时刻呈现图像元素,并在尚未创建ViewModel的时刻请求Fill属性的值。
信息太少,无法确定地说明,但是根据我的经验,不能正确处理空值的转换器可能是WPF开发中的一个主要问题。很多设计时间的不稳定性已经在没有正确处理空值的转换器中产生了根源。