枚举转换失败的 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)'
您需要将 SelectedItem
从 string
转换为 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}"/>
我创建了一个 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)'
您需要将 SelectedItem
从 string
转换为 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}"/>