【发布时间】:2011-05-20 15:54:39
【问题描述】:
我正在尝试学习 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 个条件,这背后的基本思想是,条件对对象类型进行操作,并提供一组特定于该类型的“条件选项”(布尔有 isTrue、isFalse,而数字可能有 >= 等)。
所以现在我正在尝试创建一个视图,以使 Condition 更易于在 UI 上使用。使用从组合中选择的值调用更新,该组合具有数据类型。那时我构造了适当的条件,并希望通过 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')。我应该如何解决这个绑定问题?最终我有一些转换器也希望在枚举上工作,所以我不确定将结果转换为 Objects 是否正确:S
更新:
尝试将“Fields”绑定到 ComboBox,一旦它改变了对 Update 的调用,将修改绑定到另一个 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>
【问题讨论】:
-
我不确定你到底想绑定什么。你能发布相关的 XAML 吗?
-
当然,更新了问题并试图使其更清晰。这是我的“ConditionValues”,它可以包含来自 4 个不同枚举中的 1 个的值。
标签: wpf data-binding