1

私は WPF ComboBox を持っており、MVVM を使用して ItemsSource プロパティと SelectedItem プロパティをバインドしています。基本的に私がやりたいことは、ユーザーがコンボボックスで特定のアイテムを選択すると、代わりにコンボボックスが別のアイテムを選択することです。

<ComboBox ItemsSource="{Binding TestComboItemsSource}" SelectedItem="{Binding TestComboItemsSourceSelected}"></ComboBox>

デモ用に、SelectedItem を更新するボタンもあります。

<Button Command="{Binding DoStuffCommand}">Do stuff</Button>

私は私のビューモデルにこれを持っています:

    public ObservableCollection<string> TestComboItemsSource { get; private set; }

    public MyConstructor()
    {
        TestComboItemsSource = new ObservableCollection<string>(new []{ "items", "all", "umbrella", "watch", "coat" });
    }

    private string _testComboItemsSourceSelected;
    public string TestComboItemsSourceSelected
    {
        get { return _testComboItemsSourceSelected; }
        set
        {
            if (value == "all")
            {
                TestComboItemsSourceSelected = "items";
                return;
            }

            _testComboItemsSourceSelected = value;
            PropertyChanged(this, new PropertyChangedEventArgs(TestComboItemsSourceSelected))
        }
    }

    private ICommand _doStuffCommand;

    public ICommand DoStuffCommand
    {
        get
        {
            return _doStuffCommand ?? (_doStuffCommand = new RelayCommand(p =>
                                                                              {
                                                                                  TestComboItemsSourceSelected = "items";
                                                                              })); }
    }

わかりましたので、ユーザーがアイテム「all」を選択するたびに、ComboBox にアイテム「items」を選択させたいと思います。ボタンを使用して、コンボボックスの SelectedItem を更新でき、これが UI に反映されていることがわかります

TestComboItemsSourceSelected プロパティのセッターで viewModel を更新する同様のロジックがあります。ユーザーが "all" を選択した場合は、代わりに SelectedItem を "items" に設定します。コード的には、viewmodel プロパティが変更されますが、これは何らかの理由で UI に反映されません。何か不足していますか?私がこれを実装した方法の何らかの副作用はありますか?

4

2 に答える 2

1

これは、別の変更が進行中にプロパティを変更するためです。WPFはPropertyChanged、このプロパティを設定している間、このプロパティのイベントをリッスンしません。

これを回避するには、ディスパッチャを使用して新しい変更を「スケジュール」できるため、現在の変更が完了した後に実行されます。

public string TestComboItemsSourceSelected
{
    get { return _testComboItemsSourceSelected; }
    set
    {
        if (value == "all")
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() => {
               TestComboItemsSourceSelected = "items";
            }));
            return;
        }

        _testComboItemsSourceSelected = value;
        PropertyChanged(this, new PropertyChangedEventArgs(TestComboItemsSourceSelected))
    }
}
于 2011-08-23T07:56:47.510 に答える
1

あなたが説明している動作は私にとって非常に奇妙に思えますが、「すべて選択」機能が必要な場合、標準的な方法は、アイテムにチェックボックスがあるコンボボックスを作成することです。

各アイテムは小さな ViewModel (通常は Id、Name、および IsChecked プロパティを使用) で表され、ObservableCollection に最初に追加される「すべてのアイテムを選択」を手動で作成し、その PropertyChanged をサブスクライブして残りのアイテムを設定します。 IsChecked プロパティを true に設定します。

于 2012-03-28T10:50:41.530 に答える