Reputation: 189
I created a ComboBox
and binding system enum valus to it. And also created a value converter for it to make it more human readable.
But when I select items in ComboBox
, it showes error and some error message dumpped in console
Any idea how to solve the issue?
I have also tried to set another value converter for SelectedItem
, but it does not work either.
cs file:
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 file:
<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>
error:
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)'
Upvotes: 0
Views: 1982
Reputation: 169340
You need to convert the SelectedItem
from a string
to a StopBits
value.
So the ConvertBack
method of the converter that you apply to the SelectedItem
binding should return an enumeration value that the source property can actually be set to:
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;
}
You can't set a StopBits
property to a string
.
Edit: Or you could just return the dictionary from the converter:
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;
}
}
...and modify your XAML a bit:
<ComboBox ItemsSource="{Binding Source={StaticResource StopBitsProvider}, Converter={StaticResource DataConverter}}"
SelectedValuePath="Key"
DisplayMemberPath="Value"
SelectedValue="{Binding SelectedStopBits}"/>
Upvotes: 2