Я пытаюсь изучить привязку данных в 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 условия, основная идея которых заключается в том, что Condition работает с типом Object и предоставляет набор«ConditionOptions», характерных для этого типа (в Bool есть isTrue, isFalse, тогда как число может иметь <<=>> = и т. д.).
Так что теперь я пытаюсь создать представление, чтобы сделатьСостояние проще потреблять на интерфейсе.Обновление вызывается с выбранным значением из комбинации, которая имеет тип данных.В этот момент я создаю соответствующее условие и хочу предоставить коллекцию ConditionOptions через свойство ConditionValues (так что это может быть результат перечисления, но это может быть любой из 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");
}
}
}
Яв настоящее время я просто пытаюсь запустить Boolean, но я не уверен, что ObservableCollection - это то, к чему я должен привязываться (я получаю ошибку сборки при попытке: "Ошибка 5 Не удается неявно преобразовать тип 'System.Collections.ObjectModel.ObservableCollection' в'System.Collections.ObjectModel.ObservableCollection'). Как мне подходить к этой проблеме привязки? В конечном счете, у меня есть несколько конвертеров, которые тоже будут работать над перечислением, поэтому я не уверен, что просто приведу результатыОбъекты правы: S
Обновление:
Попытка связать 'Поля' с ComboBox, и как только он меняет вызов Update, изменит 'ConditionValues'который связан с другим ComboBox.
<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>