1

すべてのコントロールが実行時に作成されるビューがあるため、問題に直面しています。

それぞれをビューモデルにバインドしようとしていますが、アプローチが間違っている可能性があります。

例としてコンボボックスを使用します。

データを含む私のモデル:

public class ModelToContainTheData
{
    public string BuildType { get; set; }
    public string Section { get; set; }
    public string QuestionID { get; set; }
    public string Values { get; set; }
    public int Selectable { get; set; }
    public DateTime Changed { get; set; }
    public string User { get; set; }
}

次に、このモデルの配列を作成し、次のメソッドを ComboBox.SelectionChanged にバインドします。

private void ComboboxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var box = sender as ComboBox;

    foreach(ModelToContainTheDatamodel in currentSettingsModel)
    {
        if(model != null)
            if(model.QuestionID == box.Name)
            {
                model.Changed = DateTime.Now;
                model.Values = box.SelectedValue.ToString();
                model.User = "wc_set";
            }
    }
}

次にやりたいことは、配列をビューモデルにバインドすることです。これを行う適切な方法はありますか、それともアプローチを完全に変更する必要がありますか?

ObservableCollection が最適な方法であると考えましたが、それをバインドする方法がわかりませんでした。

4

1 に答える 1

4

あなたの例では、少し混乱しています。MVVM パターンに慣れてから、実際の問題に戻ることをお勧めします。MVVM の主なアイデア (そして、モデル、ビュー、および ViewModels について話しているので、MVVM を目指していると思います) は、ビューとモデルを切り離すことです。UI イベント ( などSelectionChanged) へのサブスクライブは、MVVM では避ける必要があります。

特にモデル プロパティを UI コントロール プロパティと一致させることにより、UI とモデルを緊密に結合しています ( model.QuestionID == box.Name)。

MVVM の方法で問題を解決するための一般的な概念を簡単に説明します。

モデルは、アプリのドメイン世界で起こっていることの全体像を描く必要があります。質問などがありますが、これらはすべて、ビジネス ロジックとも呼ばれるドメイン ロジックで表現する必要があります。いくつかのクラスがあります。私はあなたのコードから理解したことから何かを作り上げただけです。それがあなたがやろうとしていることと一致するかどうかはわかりません...

// Model for an answer ('Value' in your question
public class Answer { ... }

// Model for a question containing possible answers and the actual answer
public class Question 
{ 
   private Answer _answer;

   public List<Answer> PossibleAnswers { get; set; }

   public Answer Answer { get; set; }

   public DateTime Changed { get; set; }

   public Question()
   {
       // Acquire the values from wherever
       PossibleAnswers = ...;
   }
}

モデルは完全にスタンドアロンであることに注意してください。これは、ViewModel または View について何も知らないことを意味します。

次に、表示するデータにビューをバインドできるようにプロパティを公開する、このモデルの ViewModel を作成します。最も簡単なケースでは、モデルのプロパティを中継するだけです。を実装する適切な基本クラスを使用しますINotifyPropertyChanged。これには、MVVMLight など、多くの MVVM フレームワークがあります。

public class QuestionViewModel : NotifyingObject
{
    public Question Model { get; private set; }

    public List<AnswerViewModel> PossibleAnswers 
    {
        get { return _possibleAnswers; }
    }

    public DateTime Changed 
    {
        get { return Model.Changed; }

    public AnswerViewModel Answer 
    {
        get { return _answer; }
        set 
        {
            _answer = value;
            // Set properties on your model which are effected
            _model.Answer = _answer.Model;
            _model.Changed = DateTime.Now;
            // Raise property changed events. They are needed
            // to update the UI
            RaisePropertyChanged("Answer");
            RaisePropertyChanged("Date");
        }
    }

    public QuestionViewModel(Question model)
    {
        Model = model;
        _possibleAnswers = Model.Answers.Select(a => new AnswerViewModel(a));
    }

}

public class AnswerViewModel { ... }

ご覧のとおり、ViewModelはモデルを認識しており、独自の値の変更をモデルに中継します。しかし、繰り返しますが、ViewModel は View について何も知りません

View は、WPF マジックを使用して ViewModel にバインドします。DataContextビューの が ViewModel に設定されていることを確認する必要があります。これを実現する方法はいくつかありますが、ここでも MVVMLight などの MVVM フレームワークがそれを行う方法を提供しています。ここでは使用方法のみを示します。ComboBox があるとします:

<ComboBox ItemsSource="{Binding PossibleAnswers}" 
          SelectedItem="{Binding Answer}" />

それでおしまい。残りは WPF が処理します。

より複雑なシナリオでは、UI のユーザーだけでなく他の理由でもアクティブに変更できるモデルにコレクションがある場合、もう少し複雑になります。次に、モデルとビューモデルのコレクションを同期する必要があります。

VMCollection 同期

これは、最終的に遭遇するより高度なものです。あなたがそこに着いているなら、この答えはあなたを助けるかもしれません:

モデルとビューモデルのコレクションに関する SO の回答

この答えは、最初は少し圧倒されるかもしれないので、Web 上の多くの非常に優れたリソースの 1 つを使用して MVVM を掘り下げることをお勧めします。私の回答をガイドラインとして使用して、実際の問題の解決策を見つけてください。MVVM のチュートリアルとドキュメントの助けを借りてこの回答を理解すれば、適切な MVVM の方法で問題を解決することができます。

EDIT:UI要素の動的作成について

コントロールの動的な作成として説明するものは、WPF と MVVM では非常に自然な概念です。基本的な考え方はItemsControl、ViewModelItems のコレクションにバインドされたを使用し、 を使用DataTemplateして各 ViewModel のレンダリング方法を指定することです。制限はありません。各項目は複雑なコントロールでレンダリングでき、レイアウトは「ItemsControl」のItemsPanelプロパティを介して指定できます。MVVM を掘り下げると、状況が明らかになり、シナリオは MVVM で解決する非常に一般的なものです。WPFItemsControlとそれを使って何ができるか、目を光らせておいてください...

于 2013-10-09T09:33:28.033 に答える