【问题标题】:NullReferenceException with IValueConverter when connecting via remote desktop通过远程桌面连接时带有 IValueConverter 的 NullReferenceException
【发布时间】:2017-11-23 16:22:59
【问题描述】:

这是一个奇怪的错误。我将枚举绑定到组合框并显示描述属性。我正在使用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参数是一个字符串,否则排查的信息不多,调用堆栈为空。

【问题讨论】:

  • 在此处添加调试语句并告诉我们,它是对象还是 null 值?然后查看堆栈跟踪并向后查找原因。对象类型是什么?
  • @JohnPeters value 函数的 Convert() 参数为 null,这会导致异常。 EnumConverter.Convert() 是堆栈跟踪中唯一的东西。
  • 好的,转换器是在 WPF 渲染时调用的,那么 Object 类型是什么?你能展示 XAML 部分....和绑定集合吗?
  • @JohnPeters 所有重要的 XAML 和代码都显示在上面。我没有包括的任何内容都只是自动生成的样板。

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


【解决方案1】:

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

正确吗?

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

由于您不太可能可靠地强制 WPF 在 RDP 会话的上下文中更改其方式,唯一可行的解​​决方案是检查 valuenull 值,并在这种情况下做一些合理的事情(例如return Binding.DoNothing;)。一旦 WPF 稳定下来,它应该会恢复到您再次拥有实际值的状态,并且您将恢复到正常状态。

【讨论】:

    【解决方案2】:

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

    Binding Source={StaticResource MyEnumValues}}
    

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

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

    【讨论】:

    • MyEnumValues 在 XAML 的 ObjectDataProvider 部分中定义。澄清一下,当我运行程序并从组合框中选择一个项目时,一切正常。 只有当我通过远程桌面连接时才会出现问题。
    • 那么这不是程序本身,而是环境。但是,我看不出有任何原因会因为 RDP 而失败。
    猜你喜欢
    • 1970-01-01
    • 2011-11-30
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 2015-02-02
    相关资源
    最近更新 更多