在以下场景中,我在使用 WPF ComboBox 时遇到了麻烦:
ViewModel
提供一个
ObservableCollection<T>
;该集合包含用户可以选择的项目列表。提供一个类型为
T
的属性,表示所选项目。
用户应该能够从 ObservableCollection<T>
中的现有项或通过键入字符串表示来添加新项。
我有一个可用于将类型为 T
的项转换为 string
和反之亦然的转换器。
View
我的 ComboBox 绑定到集合和所选项目属性:
<ComboBox ItemsSource="{Binding Path=MyObservableCollection}"
SelectedItem="{Binding Path=MySelectedItem}"
IsReadOnly="False" IsEditable="True"/>
数据模板用于正确显示项目:
<DataTemplate DataType="{x:Type T}">
<TextBlock Text="{Binding Converter={StaticResource ResourceKey=MyConverter}}"/>
</DataTemplate>
问题
ComboBox
下拉列表中使用转换器正确显示项目。但是在ComboBox
的TextBox
中显示的所选项不正确;它没有使用我的转换器,而是使用了ToString
方法。
是否可以为Text属性指定转换器?我尝试使用以下代码:
<ComboBox ItemsSource="{Binding Path=MyObservableCollection}"
SelectedItem="{Binding Path=MySelectedItem}"
Text="{Binding Path=MySelectedItem, Converter={StaticResource ResourceKey=MyConverter}}"
IsReadOnly="False" IsEditable="True"/>
这解决了显示问题,但现在我在转换器的ConvertBack方法中获取T的Type.FullName - 当然无法转换。 摘要 我希望用户能够从集合中选择项目,并允许他通过输入字符串表示来添加新项目。集合中的项目应使用转换器在字符串和对象表示之间进行转换。该转换应在ComboBox的下拉列表和文本框中均可完成。 编辑 以下是我的转换器代码 - 没有什么魔法,只有直接的转换:
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return MyConverter.Convert(value as T);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return MyConverter.Convert(value as string);
}
public static string Convert(T key)
{
// Conversion from T to string.
}
public static T Convert(string key)
{
// Conversion from string to T.
}
}
好的,现在我找到了符合我的需求的东西:
<TextBox Text="{Binding Path=MySelectedItem, Converter={StaticResource ResourceKey=MyConverter}}"/>
<ListBox ItemsSource="{Binding Path=MyObservableCollection}"
SelectedItem="{Binding Path=MySelectedItem, Converter={StaticResource ResourceKey=MyConverter}}"/>
这正好符合我的要求;我可以选择预定义的值,用户也可以自己添加值。ComboBox能够实现这个功能吗?
type.GetType((string)value, true, true)
仍然需要值为实际值,但它实际上是包含Type.FullName
的string
。 - Korexio