簡體   English   中英

將模型數組綁定到代碼隱藏中的viewmodel

[英]Binding model-array to viewmodel in code-behind

我遇到了一個問題,因為我有一個視圖,其中所有控件都是在運行時創建的。

我試圖將它們中的每一個綁定到我的viewmodel,但我想我可能有錯誤的方法。

我們將使用組合框作為示例。

我的模型包含數據:

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";
            }
    }
}

我想要做的是將數組綁定到viewmodel。 有沒有正確的方法來做到這一點,還是我需要完全改變我的approch?

我認為一個ObservableCollection可能是要走的路,但我無法弄清楚我是如何綁定它的。

你的例子中有一些混亂。 我建議熟悉MVVM模式,然后回到實際問題。 MVVM的主要思想(我認為你的目標是MVVM,因為你在談論模型,視圖和ViewModel)是為了解耦視圖和模型。 在MVVM中要避免訂閱UI事件(如SelectionChanged )。

您正在緊密地耦合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的適當基類。 有很多MVVM框架,比如MVVMLight:

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 了解 Model並將其自身值的更改轉發給模型。 但同樣, ViewModel並沒有關於View的任何信息

View使用WPF魔法綁定到ViewModel。 您只需要確保View的DataContext設置為ViewModel。 有很多方法可以實現這一點,MVVMLight等MVVM框架也提供了這樣做的方法。 我只會在這里展示用法。 假設你有ComboBox:

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

而已。 WPF負責其余的工作。

在更復雜的場景中,您的模型上的集合可以主動更改,即不僅由UI中的用戶而且由於其他原因,它會變得更復雜一些。 然后,您需要同步模型和ViewModel上的集合。

VMCollection同步

這是你最終會遇到的更高級的東西。 如果你到達那里,這個答案可能對你有所幫助:

回答模型和ViewModel上的集合

這個答案起初可能有點壓倒性,所以我建議使用網絡上眾多非常好的資源之一挖掘MVVM。 使用我的答案作為指導,為您的實際問題找到解決方案。 如果您在MVVM教程的幫助下理解了這個答案,那么您將適合以適當的MVVM方式解決您的問題。

編輯:關於UI元素的動態創建

在WPF和MVVM中,您所描述的動態控件創建是一個非常自然的概念。 基本思想是使用ItemsControl ,它綁定到ViewModelItems的集合,並使用DataTemplate來指定每個ViewModel的呈現方式。 沒有限制,每個項目都可以在復雜的控件中呈現,並且可以通過'ItemsControl的ItemsPanel屬性指定布局。 在深入了解MVVM時,事情會變得清晰,而你的場景是MVVM解決的常見問題。 只要睜大眼睛看WPF的ItemsControl以及你可以用它做什么......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM