Взаимодействие wpf combobox с iseditable, itemssource и validationrule

Я пытаюсь сделать следующее. У меня есть поле со списком, привязанное к настраиваемому классу с ItemsSource, DisplayMembePath, установленным для свойства этого класса. Это само по себе отлично работает, все привязки работают. Перейдите в конец, чтобы узнать о моих проблемах.

        <ComboBox Name="Field" Width="{Binding FieldWidth}" ItemsSource="{Binding LookupValues}" DisplayMemberPath="Description" SelectedValue="{Binding SelectedValue}" 
              Grid.Column="1" HorizontalAlignment="{Binding FieldAlignment}" Margin="{Binding FieldMargin}" IsEditable="True"/>

Мой собственный класс довольно простой:

public class LookupValue : ILookupValue
{
    public LookupValue() { }
    public LookupValue(CODETABLE codeTable)
    {
        Id = codeTable.ID;
        Name = codeTable.CODE;
        Description = codeTable.DESCR;
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public int? Sequence { get; set; }
    public override bool Equals(object obj)
    {
        if (obj is LookupValue)
        {
            LookupValue lookupValue = (LookupValue)obj;
            return Id == lookupValue.Id && String.Compare(Name, lookupValue.Name) == 0 && String.Compare(Description, lookupValue.Description) == 0;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return Id;
    }

Как и соответствующий раздел моей модели просмотра

    public ILookupValue SelectedValue
    {
        get {
            return (ILookupValue)GetValue(SelectedValueProperty);
        }
        set { SetValue(SelectedValueProperty, value); NotifyPropertyChanged("SelectedValue"); }
    }

    public static readonly DependencyProperty SelectedValueProperty =
        DependencyProperty.Register("SelectedValue", typeof(ILookupValue), typeof(MarriageComboBox), new PropertyMetadata(new MarriageLookupValue(), SelectedValueChanged));

    private static void SelectedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MarriageComboBox box = d as MarriageComboBox;
    }

    public IList<ILookupValue> LookupValues
    {
        get { return (IList<ILookupValue>)GetValue(LookupValuesProperty); }
        set { SetValue(LookupValuesProperty, value); NotifyPropertyChanged("LookupValues"); }
    }

    public static readonly DependencyProperty LookupValuesProperty =
        DependencyProperty.Register("LookupValues", typeof(IList<ILookupValue>), typeof(MarriageComboBox), new PropertyMetadata(null));

Все работает, кроме части IsEditable = true в ComboBox. Требование состоит в том, что пользователю разрешено вводить свои собственные значения и он не должен быть одним из элементов списка. Но для обязательных полей мне также нужно проверить, что что-то было введено или выбрано.

Мои проблемы:

  • Я использую ValidationRules для проверки, но для пользовательских записей всегда отправляется нулевое значение.
  • Привязка обновляется только при изменении выбора на новую предопределенную опцию. Он не обновляется, когда я ввожу пользовательское значение или когда то, что я набираю, отличается от предварительно определенного параметра. Например, если вариант «США» и я ввожу «Трусы», он будет обновлен до «США», когда я введу букву «U», но затем останется «США», когда я введу остальную часть слова. И если я начну с буквы, не совпадающей ни с чем в списке, она останется пустой.

Что я пробовал:

  • По совету некоторых других похожих, но не одинаковых вопросов, я попытался добавить нулевую проверку и создать новое значение LookupValue для моего получателя SelectedValue. Похоже, это не имеет никакого эффекта.

  • Я также пробовал привязаться к списку строк и самостоятельно обрабатывать сопоставление с моим списком настраиваемых классов, но даже для списка строк поведение такое же.

  • Мне удалось обойти вторую проблему, связав событие KeyUp и установив для SelectedValue новое значение LookupValue, если совпадения нет. Но это все еще не помогает решить проблему ValidationRules.

Любая помощь была бы замечательной.

Я думаю, что было бы лучше полностью описать здесь поведение, которого вы хотите добиться. Большинство элементов управления ComboBox, которые я использовал / видел, работают следующим образом: Пользователь нажимает ComboBox. Пользователь может выбрать элемент из раскрывающегося списка с помощью мыши, стрелок или путем ввода. Ввод соответствующего слова быстрым нажатием клавиш выделит этот элемент в ComboBox. Судя по звукам того, о чем вы спрашиваете, вам может потребоваться изменить шаблон и создать собственный ComboBox.

David Bentley 13.09.2018 20:25

Я ищу именно то, что вы описываете, с добавленной функциональностью, позволяющей отправлять пользовательскую информацию, отсутствующую в списке.

Dragonfiremalus 13.09.2018 22:22

Тогда вам действительно нужно создать собственный элемент управления ComboBox. Если вам понадобится помощь, дайте мне знать. Я рекомендую НЕ создавать редактируемое поле, а вместо этого использовать TextBox для вставки новых данных. Этому есть две причины: это проще и интуитивно понятнее для пользователя. Опять же, дайте мне знать, если вам понадобится помощь.

David Bentley 13.09.2018 23:47

Определенно, я предпочитаю добавить опцию «Другое», а затем отображать новое текстовое поле, если они выберут его, как и любую другую приличную форму. Но, к сожалению, меня сдерживают безумные замыслы кого-то другого, кто этого не хочет.

Dragonfiremalus 14.09.2018 17:50

Тогда вам понадобится настраиваемый элемент управления ComboBox или создайте элемент управления с нуля, чтобы делать то, что вы хотите. Элементы управления ComboBox имеют такие свойства, как SelectedValue и SelectedItem, и я не уверен, что у них есть свойство для EditBox.

David Bentley 14.09.2018 17:54
0
5
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После долгих проб и ошибок я нашел следующее исправление, которое позволяет делать то, что я хочу. Вместо привязки к свойству SelectedItem я привязал к свойству Text. Затем я смог создать новый элемент списка с введенной информацией, если это необходимо в событии потери фокуса.

Другие вопросы по теме