WPF绑定到枚举

时间:2011-05-20 15:54:40

标签: wpf data-binding

我正在尝试在WPF中学习一些数据绑定,所以已经开始构建一个小的条件构建器测试应用程序,但是在找出我的绑定时遇到了一些麻烦。

所以我有一套基于泛型的条件。这是类结构,只有一个BooleanCondition的简单示例。

public abstract class AbstractCondition
{
    /// <summary>
    /// Gets the entry mode.
    /// </summary>
    /// <value>The entry mode.</value>
    public abstract InputFieldMode InputFieldMode { get; }
}

public abstract class GenericCondition<T, O> : AbstractCondition
{
    /// <summary>
    /// Checks the specified value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public abstract Boolean Check(T value);

    /// <summary>
    /// Gets or sets the value.
    /// </summary>
    /// <value>The value.</value>
    public object Value
    {
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the options.
    /// </summary>
    /// <value>The options.</value>
    public O Option
    {
        get;
        set;
    }

    /// <summary>
    /// Gets the available options.
    /// </summary>
    /// <value>The available options.</value>
    public abstract ObservableCollection<O> AvaliableOptions { get; }
}

/// <summary>
/// Describes a Condition that operations on a Boolean
/// </summary>
/// <typeparam name="U"></typeparam>
public class BooleanCondition : GenericCondition<Boolean?, BooleanConditionOption>
{
    /// <summary>
    /// Initializes a new instance of the <see cref="BooleanCondition&lt;U&gt;"/> class.
    /// </summary>
    /// <param name="option">The option.</param>
    public BooleanCondition(BooleanConditionOption option)
    {
        this.Option = option;
    }

    /// <summary>
    /// Checks the specified value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public override bool Check(bool? value)
    {
        if (value.HasValue)
        {
            switch (this.Option)
            {
                case BooleanConditionOption.IsFalse:
                    return !value.Value;

                case BooleanConditionOption.IsTrue:
                    return value.Value;
            }
        }

        return false;
    }

    /// <inheritdoc />
    public override InputFieldMode InputFieldMode
    {
        get { return InputFieldMode.NoField; }
    }

    /// <inheritdoc />
    public override ObservableCollection<BooleanConditionOption> AvaliableOptions
    {
        get
        {
            var options = Enum.GetValues(typeof(BooleanConditionOption));
            var optionsCollection = new ObservableCollection<BooleanConditionOption>(options.Cast<BooleanConditionOption>());
            return optionsCollection;
        }
    }
}

目前有4个条件,其背后的基本思想是条件对一种Object类型进行操作,并提供一组特定于该类型的“ConditionOptions”(Bool具有isTrue,isFalse,而一个数字)可能有&lt;&lt; =&gt;&gt; =等)。

所以现在我正在尝试创建一个视图,以便在UI上更容易使用Condition。使用具有数据类型的组合中的选定值调用更新。那时我构造了适当的条件,并希望通过ConditionValues属性公开ConditionOptions的集合(所以枚举的结果,但它可以是4中的任何一个)。

public class ConditionView
    {
        /// <summary>
        /// Gets the Fields that are available for selection.
        /// </summary>
        public ObservableCollection<IDataField> Fields { get; set; }

        public ObservableCollection<Object> ConditionValues { get; set; }

        /// <summary>
        /// Gets the Condition that has been selected.
        /// </summary>
        public AbstractCondition SelectedCondition { get; private set; }

        /// <summary>
        /// Update various options based upon the Selection
        /// </summary>
        /// <param name="field">The IDataField selected</param>
        public void Update(IDataField field)
        {
            if (field != null)
            {
                // Determine what sort of condition we need
                switch (field.Type)
                {
                    case DataType.Boolean:
                        BooleanCondition booleanCondition = new BooleanCondition(BooleanConditionOption.IsFalse);
                        this.SelectedCondition = booleanCondition;
                        this.ConditionValues = booleanCondition.AvaliableOptions;
                        break;

                    case DataType.String:
                        this.SelectedCondition = new StringCondition(StringConditionOption.Contains);
                        break;

                    case DataType.Numeric:
                        this.SelectedCondition = new NumericCondition(NumericConditionOption.Equals);
                        break;

                    case DataType.Date:
                        this.SelectedCondition = new DateCondition(DateConditionOption.Equals);
                        break;

                    default:
                        throw new InvalidOperationException("Unknown Data Type");
                }
            }
        }

我目前正在尝试使用布尔值,但我不确定ObservableCollection是否应该绑定到(我得到一个构建错误尝试:“错误5无法隐式转换类型'System.Collections .ObjectModel.ObservableCollection'到'System.Collections.ObjectModel.ObservableCollection')。我应该如何处理这个绑定问题?最终我有一些转换器也会期望在枚举上工作,所以我是不确定只是将结果转换为对象是对的:S

更新

尝试将“Fields”绑定到ComboBox,一旦调整到更新,将修改绑定到另一个ComboBox的“ConditionValues”。

<UserControl x:Class="ConditionBuilder.Views.Condition"
             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" 
             mc:Ignorable="d"
             xmlns:cb="clr-namespace:ConditionBuilder"
             xmlns:wm="clr-namespace:Watermark"
             >
    <UserControl.Resources>
        <cb:EnumToUIConvertor x:Key="enumItemsConverter"/>
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="229"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <ComboBox x:Name="cmbField" Grid.Column="0" Height="22" Width="120" ItemsSource="{Binding Path=Fields}" SelectionChanged="cmbField_SelectionChanged"> 
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding Path=Name, Mode=OneWay}" Height="Auto" Margin="-5" VerticalAlignment="Stretch"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
             <wm:Watermark.WatermarkContent>
                <Label Padding="0">Select Field...</Label>
            </wm:Watermark.WatermarkContent>
        </ComboBox>
        <ComboBox x:Name="cmbCondition" Grid.Column="1" Height="22" Width="120" ItemsSource="{Binding Path=ConditionValues, Mode=OneWay}">
            <wm:Watermark.WatermarkContent>
                <Label Padding="0">Select Condition...</Label>
            </wm:Watermark.WatermarkContent>
        </ComboBox>           
    </Grid>
</UserControl>

1 个答案:

答案 0 :(得分:1)

我想我现在明白了。您可以绑定到SelectedCondition.AvailableOptions并完全取消ConditionValues。但是,我在您的代码中看不到任何INotifyPropertyChanged,因此,除非您使用notifypropertyweaver或其他技巧,否则您可能需要SelectedCondition引发属性更改事件。< / p>