使用IValueConverter通过远程桌面连接时出现NullReferenceException

时间:2017-06-20 23:42:15

标签: c# .net wpf remote-desktop ivalueconverter

这是一个奇怪的错误。我将枚举绑定到组合框并显示d​​escription属性。我在WPF Binding a ListBox to an enum, displaying the Description Attribute使用解决方案。所以我的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参数是一个字符串,但是没有太多信息需要排除故障,并且调用堆栈为空。

2 个答案:

答案 0 :(得分:2)

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

正确?

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

由于您不太可能在RDP会话的上下文中可靠地强制WPF改变其方式,唯一可行的解​​决方案是检查value的{​​{1}}值,并做一些合理的事情在那种情况下(例如null)。一旦WPF重新安定下来,它应该回到你再次获得实际值的状态,然后你将恢复正常状态。

答案 1 :(得分:0)

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

Binding Source={StaticResource MyEnumValues}}

为什么呢?因为如果你在下面的ToString()上得到null,那很可能意味着值本身是null。

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