【问题标题】:Modify the SelectedItem works not with MVVM修改 SelectedItem 不适用于 MVVM
【发布时间】:2012-08-10 13:40:14
【问题描述】:

我有一个带有组合框的窗口。这个组合框有 5 个 ComboboxItems。

在示例中,我希望无法选择项目 3、4 和 5。

我尝试了两种不同的方式:MVVM 方式代码隐藏方式

MVVM方式:

xaml:

<ComboBox SelectedIndex="{Binding Path=SaveIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Path=SaveSelectedItemCheck}" Name="SaveCombobox">

视图模型:

public object SaveSelectedItemCheck
{
    get { return _control.SaveCombobox.Items[CurrentSaveIndex]; }
    set
    {
        if (value != _control.SaveCombobox.Items[0] && value != _control.SaveCombobox.Items[1])
        {
            OnPropertyChanged("SaveSelectedItemCheck");
        }
    }
}

代码隐藏方式:

xaml:

<ComboBox SelectedIndex="{Binding Path=SaveIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="Save_SelectionChanged">

代码隐藏:

private void Save_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox combobox = sender as ComboBox;
    if(combobox == null)
    {
        return;
    }

    if (combobox.SelectedItem != combobox.Items[0] && combobox.SelectedItem != combobox.Items[1])
    {
        combobox.SelectedItem = combobox.Items[1];
        e.Handled = true;
    }
}

但它只适用于代码隐藏方式,这是肮脏的。

为什么不能以 MVVM 方式工作?

【问题讨论】:

  • 为什么要绑定 selectedindex 和 selecteditem。只需使用 SelectedItem。另一种方法是将您的 itemssource 绑定到 CollectionView。 collectionView 将包含一个属性 Selected,因此您不必绑定到 selecteditem

标签: wpf mvvm selecteditem


【解决方案1】:

正如其他人所说,您实际上并没有在属性设置器中设置任何值。

但更重要的是 IMO,我认为您误解了 MVVM 的关键概念。您的 ViewModel 代码存在很多问题:

public object SaveSelectedItemCheck
{
    get { return _control.SaveCombobox.Items[CurrentSaveIndex]; }
    set
    {
        if (value != _control.SaveCombobox.Items[0] && value != _control.SaveCombobox.Items[1])
        {
            OnPropertyChanged("SaveSelectedItemCheck");
        }
    }
}

您指的是_control.SaveCombobox.Items,它们是 UI 概念/对象。这不是 ViewModel 的目标。并且您正在返回一个对象,您应该强烈键入您的模型!

您应该拥有以下内容:

  • 模型(强类型 POCO 类)
  • ViewModel不以任何方式处理视图控件(您甚至可以将视图和 ViewModel 分成不同的程序集以确保您遵守此规则)
  • 视图,绑定到ItemsSource 以进行控制,例如Combobox

型号:

public class SomeObject : INotifyPropertyChanged
{
    private string someProperty;
    public string SomeProperty
    {
        get { return this.someProperty; }
        set
        {
            if (this.someProperty != value)
            {
                this.someProperty = value;
                OnPropertyChanged("SomeProperty");
            }
        }
    }
    ...
}

视图模型:

public class ViewModel : SomeViewModelBase
{
    private ObservableCollection<SomeObject> items;
    private SomeObject selectedItem;

    public ObservableCollection<SomeObject> Items
    {
        get
        {
            return items;
        }
        set
        {
            if (this.items != value)
            {
                this.items = value;
                OnPropertyChanged("Items");
            }
        }
    }

    public ObservableCollection<SomeObject> SelectedItem
    {
        get
        {
            return selectedItem;
        }
        set
        {
            if (this.selectedItem != value)
            {
                this.selectedItem = value;
                OnPropertyChanged("SelectedItem");
            }
        }
    }

    ...

    // Anywhere in your view model:
    this.Items = new ObservableCollection<SomeObject>(...);
    this.SelectedItem = this.Items[2];
    // Etc.
}

查看:

<ComboBox 
    ItemsSource={Binding Items}
    SelectedItem="{Binding SelectedItem, Mode=TwoWay}">

查看代码隐藏:

没有你的例子

【讨论】:

    【解决方案2】:

    您的 ViewModel 方法不会设置属性的值 - 无论该值是否有效。它只是根据值是否有效触发一个事件。

    事实上,仔细观察后,您似乎对 MVVM 模式有所误解,因为您的 ViewModel 代码似乎直接引用了它所支持的控件。根据“正常”属性,您的属性应该有一个支持字段。

    更重要的是,您应该抛出 PropertyChanged 事件,无论该值是否有效,因为如果该值已被视图模型覆盖,那么 PropertyChanged 将通知 UI 组合框值需要重新设置为有效值。

    【讨论】:

      【解决方案3】:

      您不会以 MVVM 方式在 setter 中存储任何值。

      【讨论】:

      • +1,发布的代码也不会改变选中的索引。
      猜你喜欢
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2018-08-04
      • 2012-06-19
      • 2011-11-01
      • 2010-10-14
      相关资源
      最近更新 更多