WPF绑定到枚举
我正在尝试学习WPF中的一些数据绑定,因此我已经开始构建一个小的condition builder测试应用程序,但在理解绑定时遇到了一些困难 所以我有一组基于泛型的条件。这是类结构,只是一个布尔条件的简单示例WPF绑定到枚举,wpf,data-binding,Wpf,Data Binding,我正在尝试学习WPF中的一些数据绑定,因此我已经开始构建一个小的condition builder测试应用程序,但在理解绑定时遇到了一些困难 所以我有一组基于泛型的条件。这是类结构,只是一个布尔条件的简单示例 public abstract class AbstractCondition { /// <summary> /// Gets the entry mode. /// </summary> /// <value>The
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<U>"/> 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;
}
}
}
公共抽象类AbstractCondition
{
///
///获取输入模式。
///
///进入模式。
公共抽象InputFieldMode InputFieldMode{get;}
}
公共抽象类GenericCondition:AbstractCondition
{
///
///检查指定的值。
///
///价值。
///
公共抽象布尔检查(T值);
///
///获取或设置该值。
///
///价值。
公共对象价值
{
得到;
设置
}
///
///获取或设置选项。
///
///选项。
公共O选项
{
得到;
设置
}
///
///获取可用的选项。
///
///可用选项。
公共摘要ObservableCollection AvailableOptions{get;}
}
///
///描述在布尔值上执行操作的条件
///
///
公共类布尔条件:GenericCondition
{
///
///初始化类的新实例。
///
///选择权。
公共布尔条件(布尔条件选项)
{
这个选项=选项;
}
///
///检查指定的值。
///
///价值。
///
公共覆盖布尔检查(布尔值)
{
if(value.HasValue)
{
开关(此选项)
{
case BooleanConditionOption.IsFalse:
return!value.value;
case BooleanConditionOption.IsTrue:
返回值;
}
}
返回false;
}
///
公共覆盖InputFieldMode InputFieldMode
{
获取{return InputFieldMode.NoField;}
}
///
公共覆盖可观测收集可用性
{
得到
{
var options=Enum.GetValues(typeof(BooleanConditionOption));
var optionscolection=newobservetecollection(options.Cast());
返回选项集合;
}
}
}
目前有4个条件,其基本思想是,一个条件对一种类型的对象进行操作,并提供一组特定于该类型的“条件选项”(Bool有isTrue、isFalse,而数字可能有<>=等)
因此,现在我尝试创建一个视图,使该条件更容易在UI上使用。使用具有数据类型的组合中的选定值调用更新。此时,我构造了适当的条件,并希望通过ConditionValues属性公开ConditionOptions的集合(因此枚举的结果可以是4中的任何一个)
公共类条件视图
{
///
///获取可供选择的字段。
///
公共ObservableCollection字段{get;set;}
公共ObservableCollection条件值{get;set;}
///
///获取已选择的条件。
///
public AbstractCondition SelectedCondition{get;private set;}
///
///根据选择更新各种选项
///
///选定的IDataField
公共无效更新(IDataField字段)
{
如果(字段!=null)
{
//确定我们需要什么样的条件
开关(字段类型)
{
案例数据类型。布尔值:
BooleanCondition BooleanCondition=新的BooleanCondition(BooleanConditionOption.IsFalse);
this.SelectedCondition=布尔条件;
this.ConditionValues=booleanCondition.availableOptions;
打破
案例数据类型。字符串:
this.SelectedCondition=新的StringCondition(StringConditionOption.Contains);
打破
案例数据类型。数字:
this.SelectedCondition=新的数值条件(数值条件选项.Equals);
打破
案例数据类型。日期:
this.SelectedCondition=new DateCondition(DateConditionOption.Equals);
打破
违约:
抛出新的InvalidOperationException(“未知数据类型”);
}
}
}
我目前正在尝试使用布尔值,但我不确定ObservaleCollection是否是我应该绑定的对象(我在尝试时遇到了一个生成错误:“错误5无法隐式地将类型'System.Collections.ObjectModel.ObservaleCollection'转换为'System.Collections.ObjectModel.ObservaleCollection')。我应该如何处理这个绑定问题?最终,我有一些转换器预期也会在枚举上工作,所以我不确定将结果强制转换到对象是否正确:S
更新:
尝试将“字段”绑定到一个组合框,一旦它发生变化,一个更新调用将修改绑定到另一个组合框的“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>
选择字段。。。
选择条件。。。
我想我现在明白了。您可能可以绑定到SelectedCondition.AvailableOptions
并完全删除条件值。但是,我在y中没有看到任何INotifyPropertyChanged
<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>