2

我有一个由目标的属性信息(如 type 和 values )组成的类。我正在使用此 UI 以图形格式显示视图上的所有类型,例如带有组合框的枚举和带有复选框的布尔值。除了我在 UI 中更改组合框值的情况外,一切对我来说都很好,它在视图模型中不会改变。每次我更改值在组合框中,它在我的转换器中调用 convertback 方法。我需要将此字符串转换为枚举类型,我可以为特定枚举类型轻松编写 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);


        }
    }



}
4

5 回答 5

3

尝试

return (targetType)Enum.Parse(typeof(targetType), value.ToString());
于 2013-08-27T04:59:49.723 回答
0

我很快想到的是,您可以创建一个类 EnumDescriptor 仅具有两个属性:EnumString (string) 和 EnumType (Type)

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

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

谢谢

于 2013-08-27T08:42:42.457 回答
0

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

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

Enum.Parse(targetType, (String)value)
于 2013-08-27T04:56:54.833 回答
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);
        }
    }
}

我不喜欢为此破坏视图模型,但目前我看不到任何选项。请让我知道我的代码中是否存在任何风险,或者您是否有更好的方法。

于 2013-08-27T07:37:00.670 回答
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);
 }
于 2013-08-27T05:20:21.390 回答