使用 MVVM 重置组合框选定的项目 [英] Reset combobox selected item on set using MVVM

查看:19
本文介绍了使用 MVVM 重置组合框选定的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 WPF 应用程序中使用 ComboBox 并遵循 MVVM.我想在 ComboBox 中显示一个字符串列表.

I am using a ComboBox in my WPF application and following MVVM. There is a list of strings which I want to show in my ComboBox.

XAML:

<ComboBox ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem}" />

查看模型:

public Collection<string> ItemsCollection; // Suppose this has 10 values.
private string _selectedItem;
public string SelectedItem
{
    get { return _selectedItem; }
    set
    {
        _selectedItem = value;
        Trigger Notify of property changed.
    }
}

现在这段代码工作得很好.我可以从视图中进行选择,并且可以在 ViewModel 中进行更改,如果我从我的 ViewModel 中更改 SelectedItem,我可以在我的视图中看到它.

Now this code is working absolutely fine. I am able to select from view and I can get changes in ViewModel and if I change SelectedItem from my ViewModel I can see it in my view.

现在这就是我想要实现的目标.当我从我的视图中更改选定的项目时,我需要检查值是好/坏(或任何)设置选定的项目,否则不要设置它.所以我的视图模型变成了这样.

Now here is what I am trying to achieve. When I change selected item from my view I need to put a check that value is good/bad (or anything) set selected item else do not set it. So my view model changes like to this.

public string SelectedItem
{
    get { return _selectedItem; }
    set
    {
        if (SomeCondition(value))
            _selectedItem = value;           // Update selected item.
        else
            _selectedItem = _selectedItem;   // Do not update selected item.
        Trigger Notify of property changed.
    }
}

现在,当我执行此代码并且 SomeCondition(value) 返回 false 时,SelectedItem 返回旧字符串值,但在我看来,ComboBox 中的选定项是我选择的值.所以让我们假设我的 ComboBox 中显示了 10 个字符串的集合.除了第二个和第四个元素外,所有值都很好(SomeCondition 为第二个和第四个值返回 false).如果我选择第 2 个或第 4 个元素 selectedItem,我想要什么不要改变.但是我的代码没有正确执行此操作.如果我选择第二个元素,则视图仍将第二个元素显示为选定的.我知道我的代码有问题.但它是什么?

Now when I execute this code and SomeCondition(value) returns false, SelectedItem returns old string value, but in my view selected item in ComboBox is the the value which I selected. So lets assume I have collection of 10 strings showing in my ComboBox. All values are good except second and fourth element (SomeCondition returns false for 2nd and 4th value). What I want that if I select 2nd or 4th element selectedItem do not change. But my code is not doing this properly. If I select 2nd element then view still displays 2nd element as selected. I know there is something wrong in my code. But what is it?

推荐答案

这是一个非常有趣的问题.首先,我同意其他人的看法,这是处理无效选择的不推荐方法.正如@blindmeis 所建议的,IDataErrorInfo 是解决它的好方法之一.

This is a very interesting question. First I agree with other guys that this is a not recommended approach to handle invalid selection. As @blindmeis suggests, IDataErrorInfo is one of good way to solve it.

回到问题本身.满足@Faisal Hafeez 想要的解决方案是:

Back to the question itself. A solution satisfying what @Faisal Hafeez wants is:

public string SelectedItem
{
    get { return _selectedItem; }
    set
    {
        var oldItem=_selectedItem;
        _selectedItem=value;
        OnPropertyChanged("SelectedItem")

        if (!SomeCondition(value)) //If does not satisfy condition, set item back to old item
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SelectedItem = oldItem),
                                                 DispatcherPriority.ApplicationIdle);
    }
}

Dispatcher 是一种在另一个 UI 同步期间处理某些 UI 同步的优雅方式.例如,在这种情况下,您希望在选择绑定期间重置选择.

Dispatcher is an elegant way to handle some UI synchronization during another UI sync. For example in this case, you want to reset selection during a selection binding.

这里的一个问题是为什么我们首先必须更新选择.那是因为 SelectedItemSelectedValue 是分开赋值的,ComboBox 上的显示不依赖于 SelectedItem(也许 >SelectedValue,我在这里不确定).另一个有趣的一点是,如果 SelectedValue 发生变化,SelectedItem 必须更改,但 SelectedItem 在更改时不会更新 SelectedValue.因此,您可以选择绑定到SelectedValue,这样您就不必先分配了.

A question here is why we have to update selection anyway at first. That's because SelectedItem and SelectedValue are separately assigned and what display on ComboBox does not depend on SelectedItem (maybe SelectedValue, I am not sure here). And another interesting point is if SelectedValue changes, SelectedItem must change but SelectedItem does not update SelectedValue when it changes. Therefore, you can choose to bind to SelectedValue so that you do not have to assign first.

这篇关于使用 MVVM 重置组合框选定的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆