WPF: сброс ComboBox после изменения - PullRequest
1 голос
/ 07 января 2011

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

<ComboBox ItemsSource="{Binding Path=Persons, Mode=OneTime}"
          SelectedValue="{Binding Path=SelectedPerson, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Коллекция с элементами для этого ComboBox инициализируется «текстом инструкции» какпервый элемент, а затем набор обычных элементов:

Persons.Add("Open Person...");
Persons.Add("Anders Andersson");
Persons.Add("Bengt Bengtsson");
Persons.Add("Carl Carlsson");
Persons.Add("Daniel Danielsson");

Я хотел бы иметь поведение для этого ComboBox, которое первоначально показывает текст инструкции (это, конечно, легко выполняется).Когда пользователь выбирает человека в ComboBox, приложение предпринимает какое-то действие (открывает выбранного человека), а затем сбрасывает текст инструкции.

На первый взгляд, это будет легко, если иметь это свойство для выбранного элемента.:

private string _selectedPerson = "Open Person...";
public string SelectedPerson
{
    get
    {
        return _selectedPerson;
    }
    set
    {
        if (value != _selectedPerson)
        {
            OpenPerson(value);
            OnPropertyChanged("SelectedPerson");
        }
    }
}

Моя идея заключалась в том, что когда пользователь выбирает что-либо, кроме текста инструкции в ComboBox, OpenPerson () будет вызываться с выбранным значением, но выбранное значение не будет сохранено в приватномполе (_selectedPerson).Затем я запускаю событие PropertyChanged, которое заставит ComboBox прочитать значение свойства SelectedPerson и обновить себя (SelectedValue).Поскольку поле _seletedPerson по-прежнему является текстом инструкции, ComboBox будет сбрасывать себя на это.

Это НЕ работает.

На самом деле все происходит так, как я ожидал.OpenPerson () вызывается с правильным параметром, а затем вызывается событие PropertyChanged.Однако действие GUI для изменения значения, показанного ComboBox, фактически выполняется ПОСЛЕ всего этого.Это означает, что независимо от того, какое значение я выбрал для SelectedPerson, ComboBox покажет элемент, который был выбран в графическом интерфейсе.

Есть ли элегантный способ обойти это?

На самом деле, яобошел это сам.Но он включал код в CodeBehind, два флага в ViewModel и некоторый неприятный код в свойстве SelectedPerson.Решение, ну, в общем, неудовлетворительно, если не сказать больше ...;) Итак, я надеялся, что кто-то умнее меня сможет найти лучшее решение! :)

Ответы [ 2 ]

1 голос
/ 07 января 2011

Вы пытались создать обработчик SelectionChanged для Combobox и вместо этого переключиться обратно на "Open Person ..."?

Или даже Trigger для комбинированного списка, который устанавливает его в Index = 0 или что-то еще?

0 голосов
/ 11 марта 2013

Я только что нашел это в поисках чего-то другого, надеюсь, я все еще могу помочь.

Я связываю команду с событием selectionchanged, эта команда определена в модели представления и, следовательно, следует шаблону MVVM (без кода).

Я использую инфраструктуру MVVM-Light, поэтому вам необходимо включить следующее, включающее ссылку на интерактивную смесь:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"

вот как я это объявляю в своем xaml:

            <ComboBox Name="idClient" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"
                              Style="{StaticResource FTC_DetailComboBox}"
                              ItemsSource="{Binding ClientViewSource.View}"
                              SelectedItem="{Binding client}"
                              SelectedValuePath="idClient"
                              SelectedValue="{Binding idClient, Mode=TwoWay, ValidatesOnDataErrors=True}"
                              DisplayMemberPath="chrCompany"
                              >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <cmd:EventToCommand Command="{Binding LostFocusValidateCommand}" CommandParameter="idStatus"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </ComboBox>

Вот код из моей viewmodel (в vb.net). RelayCommand - это простая реализация ICommand

    Private _LostFocusValidateCommand As RelayCommand(Of String)

    Public ReadOnly Property LostFocusValidateCommand() As RelayCommand(Of String)
        Get
            If _LostFocusValidateCommand Is Nothing Then
                _LostFocusValidateCommand = New RelayCommand(Of String)(AddressOf LostFocusValidateExecute)
            End If
            Return _LostFocusValidateCommand
        End Get
    End Property

    Private Sub LostFocusValidateExecute(sParam As String)
        ''perform commands here
    End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...