WPF ComboBox SelectedItem绑定

时间:2011-08-23 07:44:12

标签: wpf combobox selecteditem two-way-binding

我有一个WPF ComboBox,我正在使用MVVM来绑定ItemsSource和SelectedItem属性。基本上我想要做的是当用户选择组合框中的特定项目时,组合框会选择不同的项目。

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

出于演示目的,我还有一个按钮来更新SelectedItem。

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

我在viewModel中有这个:

    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属性的setter中的viewModel。如果用户选择“全部”,而是将SelectedItem设置为“items”,那么在代码方面,viewmodel属性会发生变化,但由于某种原因,这不会反映在UI中。我错过了什么吗?我实施这种方式有某种副作用吗?

2 个答案:

答案 0 :(得分: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))
    }
}

答案 1 :(得分:1)

您所描述的行为对我来说似乎很奇怪,但如果您想要“全选”功能,则标准方法是创建一个组合框,其中的项目具有CheckBox。

每个项目都由一个小的ViewModel(具有Id,Name和IsChecked属性)表示,并且您手动创建一个“选择所有项目”,该项目首先在ObservableCollection中添加并订阅其PropertyChanged以设置其余项目o项目IsChecked属性为true。