2012-08-10 72 views
0

我有一个窗口与组合框。这个comboboxhas有5个ComboboxItems。修改SelectedItem不适用于MVVM

在这个例子中我想,这是无法选择的项目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方式?

+0

为什么你绑定selectedindex和selecteditem。只需使用SelectedItem。另一种方法是将你的itemssource绑定到一个CollectionView。 collectionView将包含所选属性,因此您不必绑定到selecteditem – 2012-08-10 13:43:30

回答

1

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

但更重要的IMO,我认为你误会了MVVM的关键概念。有很多的问题与您的视图模型代码:

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类)
  • 的ViewModels 不与视图控件以任何方式处理(你甚至可以独立意见和ViewModels到不同的程序集,以确保您遵循此规则)
  • 视图,与约束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}"> 

查看后台代码:

没有您例如

0

您不以MVVM方式在设置器中存储任何值。

+0

+1,发布的代码也不会更改所选索引。 – 2012-08-10 13:48:50

+0

@狂野downvoter,谨慎解释? – 2012-08-10 15:36:00

1

您的ViewModel方法不会设置该属性的值 - 无论该值是否有效。它只是基于值是否有效而触发事件。

事实上,仔细观察,你似乎有点误解了MVVM模式,因为看起来你的ViewModel代码可能直接指向它所支持的控件。根据“正常”属性,您应该有一个属性的后台字段。

更重要的是,你应该抛出PropertyChanged事件的值是否有效或无效的,因为如果该值已经由视图模型重写,然后PropertyChanged将通知组合框的值需要重新设置到UI一个有效的值。