我有这样的组合框:
<ComboBox Grid.Column="1" Padding="0" Margin="5,0,0,0" VerticalAlignment="Center" HorizontalContentAlignment="Center" IsEnabled="{Binding CanUserEdit}" SelectedValue="{Binding ConfigValue, Converter={StaticResource BoolToStringConverter}, Mode=TwoWay}">
<ComboBoxItem x:Uid="NoButton" />
<ComboBoxItem x:Uid="YesButton" />
</ComboBox>
它应该是正常的是/否类型的组合框,但我想避免绑定到一些是/否项目源以避免不必要的复杂化。
BoolToStringConverter看起来像这样:
public class BoolToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var val = value as bool?;
if (val == true)
return ResourceLoader.GetForCurrentView().GetString("YesButton/Content");
else
return ResourceLoader.GetForCurrentView().GetString("NoButton/Content");
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
var val = value as string;
if (val == ResourceLoader.GetForCurrentView().GetString("YesButton/Content"))
return new bool?(true);
else
return new bool?(false);
}
}
所以一般来说,我有来自 ComboBoxItem 内部资源的字符串,而 ViewModel 中的值是一个对象(它不是布尔值,它不像我使用 TemplateSelector 那么简单,ComboBox 应该仅用于布尔值,其他人将是普通的 TextBox,里面有字符串(。
我从 ViewModel 中获取值,将其转换为资源中的完全相同的字符串,但在加载控件时它不会映射 SelectedValue(ComboBox 为空,即使它包含应有的是/否值(。但是"转换回来"工作正常。当我在此组合框中选择某些内容(例如"否"值(时,它将正确进入 ConvertBack 方法,比较字符串并设置正确的布尔值?视图模型中的值。因此,ConvertBack 运行良好,但初始转换没有正确设置 SelectedValue,因为它此时似乎无法将"Yes"识别为"Yes",将"No"识别为"No"(可能是因为它尝试比较字符串和 ComboBoxItem 之间的引用(。我该如何解决这个问题?
当我使用 x:String 而不是 ComboBoxItem 时,它有效...但是 x:String 无法本地化,我不想针对某些语言对其进行硬编码。
问题是类型不匹配。
在 XAML 中,ComboBox
的子项类型是ComboBoxItem,BoolToStringConverter.Convert
方法返回一个字符串。这两种类型无法建立正确的等效关系。
您可以尝试在ComboBox
中设置SelectedValuePath
属性:
<ComboBox Grid.Column="1"
...
SelectedValuePath="Content">
<ComboBoxItem x:Uid="NoButton" />
<ComboBoxItem x:Uid="YesButton" />
</ComboBox>
但我建议使用ItemsSource
进行数据源绑定,并使用DataTemplate
设置子项的布局。
下面是一个关于绑定的示例,您可以在ComboBox
此致敬意。