0

コンボボックスのあるウィンドウがあります。このコンボボックスには 5 つの ComboboxItems があります。

この例では、項目 3、4、および 5 を選択できないようにします。

私は2つの異なる方法を試しました: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 の方法で動作しないのはなぜですか?

4

3 に答える 3

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.ItemsUIコンセプト/オブジェクトである を参照しています。これは 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}">

コード ビハインドを表示:

あなたの例には何もありません

于 2012-08-10T14:27:43.577 に答える
1

ViewModel メソッドは、値が有効かどうかに関係なく、プロパティの値を設定しません。値が有効かどうかに基づいてイベントを発生させるだけです。

実際、よく調べてみると、ViewModel コードがサポートしているコントロールを直接参照しているように見えるため、MVVM パターンを多少誤解しているようです。「通常の」プロパティに従って、プロパティのバッキング フィールドが必要です。

さらに重要なことは、値が有効かどうかに関係なくイベントをスローする必要があることです。これは、値がビューモデルによってオーバーライドされた場合、コンボボックスの値を有効な値に再設定する必要があることを UI に通知するためです。PropertyChangedPropertyChanged

于 2012-08-10T13:49:18.640 に答える
0

MVVM の方法でセッターに値を保存しません。

于 2012-08-10T13:43:38.793 に答える