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";
                                                                              })); }
    }

好的,所以我想让 ComboBox 在用户选择项目“全部”时选择项目“项目”。使用该按钮,我可以更新组合框的 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

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

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

于 2012-03-28T10:50:41.530 回答