通过远程桌面连接时带有 IValueConverter 的 NullReferenceException



这是一个奇怪的错误。我正在将枚举绑定到组合框并显示描述属性。我正在使用 WPF 将列表框绑定到枚举的解决方案,显示说明属性。因此,我的 XAML 的相关部分是:

<Window.Resources>
<local:EnumConverter x:Key="EnumConverter"/>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type local:MyEnum}"
x:Key="MyEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:MyEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<ComboBox Name="MyComboBox" ItemsSource="{Binding Source={StaticResource MyEnumValues}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

那么我的代码是:

public enum MyEnum
{
[Description("foo")]
Foo,
[Description("bar")]
Bar
}
public class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
FieldInfo field_info = value.GetType().GetField(value.ToString());
object[] attributes = field_info.GetCustomAttributes(false);
if (attributes.Length == 0)
return value.ToString();
else
{
DescriptionAttribute attribute = attributes[0] as DescriptionAttribute;
return attribute.Description;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}

现在奇怪的部分。我启动程序并从组合框中选择一个值(此步骤很重要)。一切按预期工作。然后我通过远程桌面连接到计算机。我立即在Convert()函数的第一行得到一个 NullReferenceException。Type参数是一个字符串,但除此之外,没有太多信息要排除故障,并且调用堆栈为空。

如果我正确理解您的描述,则通过 RDP 连接时引发异常的程序实例与您使用直接登录会话在计算机上启动的程序实例相同。 即,您首先坐在计算机上启动程序,然后通过RDP接管相同的用户会话并与已经运行的程序进行交互。

正确?

如果是这样,那么这是正常行为。切换到 RDP 连接会导致 WPF 程序丢失其所有视频资源,因为它不再呈现到本地视频卡,而是呈现到用于 RDP 的虚拟化视频驱动程序。因此,WPF 必须重新生成 UI。在执行此操作的过程中,绑定会暂时具有null值。在此期间调用转换器,您可以在不先检查null值的情况下调用ToString(),这会导致NullReferenceException

由于您不太可能可靠地强制 WPF 在 RDP 会话的上下文中更改其方式,因此唯一可行的解决方案是检查value是否有null值,并在这种情况下执行一些合理的操作(例如return Binding.DoNothing;)。一旦 WPF 安定下来,它应该会回到你再次具有实际值的状态,你将返回到正常状态。

您的静态资源中没有任何内容。或者找不到。 打开输出窗口,查看此视图出现时的绑定错误。

Binding Source={StaticResource MyEnumValues}}

为什么?因为如果您在下面的 ToString() 上获得 null,这很可能意味着值本身为 null。

Enum myEnum = (Enum)value;
var stringValue = myEnum.ToString();

最新更新