在以下场景中使用WPF组合框时遇到问题:
ViewModel
-
提供
ObservableCollection<T>
;此集合包含用户可以选择的项目列表。 -
提供代表所选项目的
T
类型的属性。
用户应能够从ObservableCollection<T>
中的项目中选择现有项目,或通过键入字符串表示来添加新项目。
我有一个可用的转换器,可以将类型为T
的项目转换为string
,反之亦然。
查看
我的组合框绑定到集合和所选项目属性:
<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>
问题
使用convert可以正确显示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
,当然不能转换。
摘要
我希望用户能够从集合中选择一个项目,允许他通过输入字符串表示来添加新项目。集合中的项目应使用转换器在字符串和对象表示之间进行转换。转换应在下拉列表和组合框的文本框中进行。
编辑
这是我的转换器中的代码-没有魔法,只有简单的转换:
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
ItemsSource="{Binding Path=MyObservableCollection}"
Text="{Binding MySelectedItem, Converter={StaticResource DisplayConverter}}"
SelectedValue="{Binding MySelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource DisplayConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
请注意,绑定是在SelectedValue上完成的,而不是SelectedItem。然后显示转换器被添加到文本&项目模板属性。
- 在Text属性中,它将用于转换所选项目的显示值
- 在ItemTemplate上,转换列表框中的显示值
我甚至将这个片段与来自xaml中定义的ObjectDataProvider的Enum集合一起使用。我的枚举具有DisplayString属性,组合框可以很好地显示枚举的字符串值表示。
HTH
我现在使用不同的方法来解决这个问题:
我的视图模型提供了一个可观察的集合和一个字符串属性。集合绑定到ComboBox的ItemsSource属性,所选项绑定到字符串属性。
<ComboBox
ItemsSource="{Binding Path=MyCollection}"
Text="{Binding Path=MyProperty, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
IsReadOnly="False" IsEditable="True"/>
UpdateSourceTrigger=LostFocus
部分用于防止不必要的更新。