真假空组合框

时间:2015-07-27 07:31:42

标签: c# wpf xaml combobox

我正在努力开发WPF中的组件。 这是我的问题:

我有一个布尔?我想要绑定到ComboBox的SelectedValue的属性。 我的ComboBox应该有3个选项:“是”(bool == true),“否”(bool == false),“”(bool == null)。

我创建了一个继承自ComboBox的UserControl。在构造函数中,我使用所需的值填充ItemCollection(“是”/“否”/“”)。

代码隐藏:

public class YesNoNullComboBox : RadComboBox
{
    public YesNoNullComboBox()
    {
        this.Items.Add("Yes");
        this.Items.Add("No");
        this.Items.Add(string.Empty);
    }
}

XAML:

<utils:YesNoNullComboBox SelectedValue="{Binding BoolValue}" />

我设法按照我想要的方式运行,但为此,我不得不使用转换器。因此,我有一个UserControl和一个转换器来添加到我的XAML。

我考虑过将我的UserControl设置为默认使用Converter,但我没弄明白怎么做.. 这甚至可能吗?或者有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

ValueConverters的目的是绑定具有不兼容类型的2个属性。在这里,您希望布尔值成为字符串。对字符串的隐式强制转换为你提供了真实的&#34;或&#34; false&#34;,但不是你想要的字符串。

在我看来,ValueConverters是解决您情况的最佳和最简单的解决方案。

答案 1 :(得分:2)

您必须在绑定声明中指定转换器,但您可以在中执行 我已经勾画了这个:

1)一个辅助类,用于存储在ComboBox和转换器中运行的字符串值:

public static class ThreeStateComboBoxItemsSource
{
    public const string None = "(none)";
    public const string Yes = "Yes";
    public const string No = "No";

    public static readonly string[] ItemsSource = new[]
    {
        None,
        Yes,
        No
    };
}

2)转换器:

[ValueConversion(typeof(bool?), typeof(string))]
public sealed class NullableBoolToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return ThreeStateComboBoxItemsSource.None;

        return (bool)value ? ThreeStateComboBoxItemsSource.Yes : ThreeStateComboBoxItemsSource.No;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        switch ((string)value)
        {
            case ThreeStateComboBoxItemsSource.Yes:
                return true;
            case ThreeStateComboBoxItemsSource.No:
                return false;
            default:
                return null;
        }
    }
}

3)用户控制。我不希望用户能够覆盖CombeBox的行为(例如,设置另一个ItemsSource),我已将CB包裹到UserControl中,而不是继承:

XAML:

<UserControl x:Class="WpfApplication4.ThreeStateComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication4"
             mc:Ignorable="d">

    <UserControl.Resources>
        <local:NullableBoolToStringConverter x:Key="NullableBoolToStringConverterKey"/>
    </UserControl.Resources>

    <ComboBox x:Name="InnerComboBox"
              SelectedItem="{Binding Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Converter={StaticResource NullableBoolToStringConverterKey}}"
              ItemsSource="{x:Static local:ThreeStateComboBoxItemsSource.ItemsSource}"/>
</UserControl>

代码隐藏:

public partial class ThreeStateComboBox : UserControl
{
    public ThreeStateComboBox()
    {
        InitializeComponent();
    }

    public bool? Value
    {
        get { return (bool?)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value",
        typeof(bool?),
        typeof(ThreeStateComboBox),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
}

4)使用样本:

    <local:ThreeStateComboBox Value="{Binding MyProperty1}"/>

由于转换器在用户控件内部使用,因此您无需在其他地方使用转换器,只需将bool / bool?属性绑定到Value