我正在尝试在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<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;
}
}
}
目前有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>
答案 0 :(得分:1)
我想我现在明白了。您可以绑定到SelectedCondition.AvailableOptions
并完全取消ConditionValues
。但是,我在您的代码中看不到任何INotifyPropertyChanged
,因此,除非您使用notifypropertyweaver或其他技巧,否则您可能需要SelectedCondition
引发属性更改事件。< / p>