枚举转换失败的 IValueConverter

IValueConverter with Enum convertback failure

我创建了一个 ComboBox 并将系统枚举值绑定到它。并且还为它创建了一个值转换器,以使其更易于阅读。 但是当我在 ComboBox 中 select 项目时,它显示错误并且在控制台中转储了一些错误消息 知道如何解决这个问题吗? 我还尝试为 SelectedItem 设置另一个值转换器,但它也不起作用。

cs文件:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.Ports;
using System.Linq;
using System.Windows;
using System.Windows.Data;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        private StopBits _stopBits;

        public StopBits SelectedStopBits
        {
            get { return _stopBits; }
            set { _stopBits = value; }
        }

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
    }

    public class DataConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var tmp = (int[])value;
            var convert = new Dictionary<StopBits, string>()
            {
                {StopBits.None, "none"},
                {StopBits.One, "1 bit"},
                {StopBits.Two, "2 bit"},
                {StopBits.OnePointFive, "1.5 bit"}
            };

            return tmp.Select(item => convert[(StopBits)item]).ToList();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
    }
}

xaml 文件:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:serialPort="clr-namespace:System.IO.Ports;assembly=System"
        xmlns:provider="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ObjectDataProvider x:Key="StopBitsProvider" MethodName="GetValues" ObjectType="{x:Type provider:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="serialPort:StopBits"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <local:DataConvert x:Key="DataConverter"/>
    </Window.Resources>
    <StackPanel>
        <TextBlock Text="Stop Bits:"/>
        <ComboBox ItemsSource="{Binding Source={StaticResource StopBitsProvider}, Converter={StaticResource DataConverter}}"
                  SelectedItem="{Binding SelectedStopBits}"/>
    </StackPanel>
</Window>

错误:

System.Windows.Data Error: 7 : ConvertBack cannot convert value '2 bit' (type 'String').
BindingExpression:Path=SelectedStopBits; DataItem='MainWindow' (Name=''); target element is 'ComboBox' (Name='');
target property is 'SelectedItem' (type 'Object') FormatException:'System.FormatException: 2 bit is not valid StopBits value
System.Enum.EnumResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument)
System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
MS.Internal.Data.ObjectTargetConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'

您需要将 SelectedItemstring 转换为 StopBits 值。

因此,您应用于 SelectedItem 绑定的转换器的 ConvertBack 方法应该 return 源 属性 实际上可以设置为的枚举值:

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    StopBits enumValue = default(StopBits);
    if (value != null)
        Enum.TryParse(value.ToString(), out enumValue);

    return enumValue;
}

您无法将 StopBits 属性 设置为 string

编辑: 或者您可以 return 来自转换器的字典:

public class DataConvert : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var tmp = (int[])value;
        var convert = new Dictionary<StopBits, string>()
        {
            {StopBits.None, "none"},
            {StopBits.One, "1 bit"},
            {StopBits.Two, "2 bit"},
            {StopBits.OnePointFive, "1.5 bit"}
        };

        return convert;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

...并稍微修改一下 XAML:

<ComboBox ItemsSource="{Binding Source={StaticResource StopBitsProvider}, Converter={StaticResource DataConverter}}"
          SelectedValuePath="Key"
          DisplayMemberPath="Value"
          SelectedValue="{Binding SelectedStopBits}"/>