[英]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上的集合。
這是你最終會遇到的更高級的東西。 如果你到達那里,這個答案可能對你有所幫助:
這個答案起初可能有點壓倒性,所以我建議使用網絡上眾多非常好的資源之一挖掘MVVM。 使用我的答案作為指導,為您的實際問題找到解決方案。 如果您在MVVM教程的幫助下理解了這個答案,那么您將適合以適當的MVVM方式解決您的問題。
編輯:關於UI元素的動態創建
在WPF和MVVM中,您所描述的動態控件創建是一個非常自然的概念。 基本思想是使用ItemsControl
,它綁定到ViewModelItems的集合,並使用DataTemplate
來指定每個ViewModel的呈現方式。 沒有限制,每個項目都可以在復雜的控件中呈現,並且可以通過'ItemsControl的ItemsPanel
屬性指定布局。 在深入了解MVVM時,事情會變得清晰,而你的場景是MVVM解決的常見問題。 只要睜大眼睛看WPF的ItemsControl
以及你可以用它做什么......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.