我有一个由目标的属性信息(如类型和值)组成的类。 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);
}
}
}
答案 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的实例,你可以从中解析枚举值并返回它
由于