当前位置: 首页 > 知识库问答 >
问题:

使用MVVM重置设置中的组合框选定项目

裴卓君
2023-03-14

我正在我的 WPF 应用程序中使用 ComboBox 并遵循 MVVM。有一个字符串列表,我想在我的组合框中显示。

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.
    }
}

现在这段代码运行得非常好。我可以从视图中选择,我可以在视图模型中获得更改,如果我从视图模型中更改SelectedItem,我可以在视图中看到它。

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

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中的选定项就是我选择的值。因此,假设我的组合框中显示了10个字符串的集合。除第二个和第四个元素外,所有值都是好的(SomeCondition对第二个值和第四值返回false)。如果我选择了第二个或第四个元素selectedItem,我希望它不会改变。但我的代码没有正确地执行此操作。如果我选择了第二个图元,则视图仍会显示第二个选定图元。我知道我的代码有问题。但这是什么?

共有3个答案

拓拔野
2023-03-14

试试把XAML换成这样

<ComboBox ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
齐航
2023-03-14

我知道这有点晚了,但从 WPF 4.5 开始,您可以像这样使用延迟命令:

    <ComboBox ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay, Delay=1, UpdateSourceTrigger=PropertyChanged}" />

前几天我花了几个小时查找东西,这救了我。对于可能有效或可能无效的其他方法,您可以阅读这篇文章及其评论。

隆安然
2023-03-14

这是一个非常有趣的问题。首先,我同意其他人的观点,即这是一种不推荐的处理无效选择的方法。正如@的建议,IDataError Info是解决它的好方法之一。

回到问题本身。满足@Faisal Hafeez需求的解决方案是:

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同步的一种优雅方式。例如,在本例中,您希望在选择绑定期间重置选择。

这里的一个问题是为什么我们必须首先更新选择。这是因为< code>SelectedItem和< code>SelectedValue是分别赋值的,而< code>ComboBox上显示的内容并不取决于< code>SelectedItem(可能是< code>SelectedValue,我在这里不确定)。另一个有趣的地方是,如果SelectedValue发生变化,则< code>SelectedItem必须发生变化,但< code>SelectedItem不会在它发生变化时更新< code>SelectedValue。因此,您可以选择绑定到< code>SelectedValue,这样就不必先进行赋值。

 类似资料:
  • 我在后台有< code>ViewModel(实现< code > INotifyPropertyChanged )和类< code>Category,它只有一个< code>string类型的属性。我的ComboBox SelectedItem绑定到类别的实例。当我更改instance的值时,SelectedItem没有更新,Combobox也没有更改。 编辑:代码 组合框: 物业: 我尝试的是:

  • 我有一个列表类型的组合框。我通过datacontext绑定了ItemsSource和ItemSelected。如果所选项目已经更改,我会显示一条弹出消息,确认用户的操作。单击“确定”后,选择会发生变化。但是在点击“取消”时,选择应该被取消,而先前的项目应该被保留。下面是绑定到combobox的SelectedItem的属性。 组合框在弹出窗口中。那么Dispatcher对象在这种情况下能工作吗?

  • 我想在 WPF 中创建一个顶部有一个项的组合框,当它被选中时,选定项应设置为 null(重置为默认状态)。我一直在寻找,但没有找到令人满意的解决方案。 如果可能的话,我希望它只使用XAML代码或附加的行为来实现,因为我不太喜欢更改视图的ViewModel中的内容,或者重写标准控件。 这是我到目前为止想出的(缩短代码): 我认为最好的方法是以某种方式添加一个事件触发器,当项目被选中时,该触发器将设置

  • 我是C#的新手,我正在通过不连接到外部数据库的编码来制作一个简单的表。我有一个组合框(下拉列表),这样用户可以从下拉列表项中选择列的数据类型,然后将所选项设置为列的数据。我需要此行中的选定项目: 这是我的全班同学:

  • 使用Datagridtemplatecolumn将WPFDatagrid绑定到组合框。很难获得组合框绑定的selectedItem。我发现了类似的例子,但这并不能解决我的问题。 请在下面找到我的 XAML 的代码片段和数据结构: 我在上面定义了一个数据结构,它实现了INotifyPropertychanged接口。 现在,在视图模型中,有一个可观察的X列表集合,即XList,它绑定到XAML中的数

  • 问题内容: 我想设置一个先前选择的要在页面加载时显示的选项。我用以下代码尝试了它: 与 但这是行不通的。有任何想法吗? 问题答案: 这绝对应该工作。确保已将代码放入: