WPF ComboBox SelectedItem 绑定

发布于 2024-12-01 02:01:47 字数 1947 浏览 1 评论 0原文

我有一个 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”时选择项目“items”。 使用该按钮,我可以更新组合框的 SelectedItem,并且可以在 UI 中看到这一点,

我有类似的逻辑来更新 TestComboItemsSourceSelected 属性的 setter 中的 viewModel。如果用户选择“all”,请将 SelectedItem 设置为“items”,因此从代码角度来看,viewmodel 属性会发生更改,但由于某种原因,这不会反映在 UI 中。我错过了什么吗?我的实现方式是否有某种副作用?

I have a WPF ComboBox and am using MVVM to bind the ItemsSource and SelectedItem properties. Basically what I want to do is when a user selects a specific item in the combobox, the combobox instead selects a different item.

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

For demo purposes, I also have a button to update the SelectedItem.

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

I have this in my 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";
                                                                              })); }
    }

OK, so I want to have the ComboBox select the item "items" whenever the user selects the item "all".
Using the button, I am able to update the combobox's SelectedItem, and I can see this reflected in the UI

I have similar logic to update the viewModel in my setter of the TestComboItemsSourceSelected property. If the user selects "all", instead set the SelectedItem to "items" So code-wise, the viewmodel property gets changed, but this is not reflected in the UI for some reason. Am I missing something? Is there some sort of side-effect of the way I've implemented this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆依然 2024-12-08 02:01:47

嗯,这是因为您在另一个更改正在进行时更改了属性。设置此属性时,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))
    }
}

Well, this is because you change the property while another change is in progress. WPF will not listen to the PropertyChanged event for this property while setting it.

To workaround this, you can "schedule" the new change with the dispatcher, so it will be executed after it is done with the current change:

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))
    }
}
许你一世情深 2024-12-08 02:01:47

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

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

The behaviour you are describing seems very weird for me, but if you want a "Select All" feature, the standar way is to create a combobox where items has a CheckBox.

Each item is represented by a small ViewModel (tipically with Id, Name and IsChecked properties), and you manually create a "select all item" that is added first in the ObservableCollection and subscribe to its PropertyChanged in order to set the rest o the items IsChecked property to true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文