如何从字符串转换回Enum

时间:2013-08-27 04:48:24

标签: c# wpf mvvm type-conversion

我有一个由目标的属性信息(如类型和值)组成的类。 Iam使用这个UI以图形格式显示视图中的所有类型,例如Enum with comboboxes和boolean with checkboxes.Everything对我很有效,除了我在UI中更改组合框值时,它在viewmodel中没有变化。每次我改变值在combobox中它在我的转换器中调用convertback方法。我需要将此字符串转换为枚举类型,我可以轻松地为特定的枚举类型编写转换代码,但是如何使用此转换器转换所有其他枚举,我有以下信息:输入我可以传递给转换器并使用它的PropertyType属性,但我不知道该怎么做。

这是我的UI代码(仅限相关部分)

    <!-- Default DataTemplate -->
    <DataTemplate x:Key="DefaultDataTemplate">
        <Grid Margin="4" MinHeight="25">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}"  FontWeight="Bold"  />
            <TextBox Margin="8,0" Grid.Column="1" Text="{Binding Value}"  />
        </Grid>
    </DataTemplate>

    <!-- DataTemplate for Booleans -->
    <DataTemplate x:Key="BooleanDataTemplate">
        <Grid Margin="4" MinHeight="25">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}" FontWeight="Bold"  />
            <CheckBox Margin="8,0" Grid.Column="1" IsChecked="{Binding Value}" />
        </Grid>
    </DataTemplate>



    <!-- DataTemplate for Enums -->
    <DataTemplate x:Key="EnumDataTemplate">
        <Grid Margin="4" MinHeight="25">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}" FontWeight="Bold"  />
            <ComboBox Margin="8,0" SelectedItem="{Binding Value,Converter={StaticResource EnumToStringConverter},Mode=TwoWay}" 
                      ItemsSource="{Binding PropertyType, 
                      Converter={local:EnumToListConverter}}" Grid.Column="1"  
                      HorizontalAlignment="Stretch" />
        </Grid>
    </DataTemplate>

    <!-- DataTemplate Selector -->
    <local:PropertyDataTemplateSelector x:Key="templateSelector"
          DefaultnDataTemplate="{StaticResource DefaultDataTemplate}"
          BooleanDataTemplate="{StaticResource BooleanDataTemplate}" 
          EnumDataTemplate="{StaticResource EnumDataTemplate}"/>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition  Height="*"></RowDefinition>
        <RowDefinition  Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <ListView Grid.Row="0" ItemsSource="{Binding Model,Converter={StaticResource PropConverter}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Grid.IsSharedSizeScope="True" 
             HorizontalContentAlignment="Stretch" 
             ItemTemplateSelector="{StaticResource templateSelector}"
             />

和我的转换器和视图模型

  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        string EnumString;
        try
        {
            EnumString = Enum.GetName((value.GetType()), value);
            return EnumString;
        }
        catch
        {
            return string.Empty;
        }
    }



    public object ConvertBack(object value, Type targetType,
      object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
        //What to do here
    }

查看模型

public class PropertyValue
{
    private PropertyInfo propertyInfo;
    private object baseObject;

    public PropertyValue(PropertyInfo propertyInfo, object baseObject)
    {
        this.propertyInfo = propertyInfo;
        this.baseObject = baseObject;
    }

    public string Name
    {
        get { return propertyInfo.Name; }

    }

    public Type PropertyType { get { return propertyInfo.PropertyType; } }

    public object Value
    {
        get { return propertyInfo.GetValue(baseObject, null); }
        set
        {

            propertyInfo.SetValue(baseObject, value , null);


        }
    }



}

5 个答案:

答案 0 :(得分:3)

尝试

return (targetType)Enum.Parse(typeof(targetType), value.ToString());

答案 1 :(得分:0)

在ConvertBack中,targetType是正确的枚举类型吗?

如果是这样,我认为这应该有效:

Enum.Parse(targetType, (String)value)

答案 2 :(得分:0)

你应该这样做

enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };
string colorName = "Blue";
if (Enum.IsDefined(typeof(Colors), colorName))  //true
 {
     Colors clr = (Colors)Enum.Parse(typeof(Colors), colorName);
 }

 colorName = "Orange";
 if (Enum.IsDefined(typeof(Colors), colorName)) //false
 {
      Colors clr = (Colors)Enum.Parse(typeof(Colors), colorName);
 }

答案 3 :(得分:0)

我不认为使用转换器或使用多重绑定可行。我通过不使用转换器进行组合框并检查getter和setter中的值来解决了我的问题。

我修改了包含属性信息的类,现在可以正常工作,我正在对枚举类型进行特殊检查,其余类型我可以使用转换器。

public class PropertyValue
{
    private PropertyInfo propertyInfo;
    private object baseObject;

    public PropertyValue(PropertyInfo propertyInfo, object baseObject)
    {
        this.propertyInfo = propertyInfo;
        this.baseObject = baseObject;
    }

    public string Name
    {
        get { return propertyInfo.Name; }

    }

    public Type PropertyType
    {
        get { return propertyInfo.PropertyType; }
    }

    public object Value
    {
        get
        {
            var retVal = propertyInfo.GetValue(baseObject, null);
            if (PropertyType.IsEnum)
            {
                retVal = retVal.ToString();
            }
            return retVal;
        }
        set
        {
            if (PropertyType.IsEnum)
            {
                value = Enum.Parse(propertyInfo.PropertyType, value.ToString());
            }
            propertyInfo.SetValue(baseObject, value, null);
        }
    }
}

我不喜欢破坏视图模型但是我现在看不到任何选项。如果我的代码存在任何风险或者你有更好的方法,请告诉我。

答案 4 :(得分:0)

我能想到的是你可以用两个属性创建一个类EnumDescriptor:EnumString(string)和EnumType(Type)

您的“EnumToListConverter”可以返回EnumDescriptor列表,您可以将组合框的显示值绑定到EnumString属性。

在你的“EnumToStringConverter”中,在Convert()中你可以创建EnumDescriptor的实例,因为我们有枚举的类型和名称,在ConvertBack()中,你将获得EnumDescriptor的实例,你可以从中解析枚举值并返回它

由于