MVVM model - association between models
Let's say I have following models:
class Worker
{
int Id;
string firstname;
string lastname;
}
class Department
{
string title;
s开发者_如何学Pythontring description;
List<Worker> workers;
}
I want to display, on UI, department's title,description and list of workers inside listbox (in listbox I want to display only firstname and lastname).
Do I need to create ONE viewmodel that will wrap this relation or I must I create a viewmodel for every model that I have?You can create on ViewModel Which wrap both of them like:
namespace XXXX.ViewModel
{
public class MainViewModel : ViewModelBase
{
private int _id;
private string _total;
private string _description;
private ObservableCollection<Worker> _workers;
public int Id
{
get { return _id; }
set
{
if (value == _id) return;
_id = value;
RaisePropertyChanged("Id");
}
}
public string Total
{
get { return _total; }
set
{
if (value == _total) return;
_total = value;
RaisePropertyChanged("Total");
}
}
public string Description
{
get { return _description; }
set
{
if (value == _description) return;
_description = value;
RaisePropertyChanged("Description");
}
}
public ObservableCollection<Worker> Workers
{
get { return _workers; }
set
{
if (value == _workers) return;
_workers = value;
RaisePropertyChanged("Workers");
}
}
//****************** You Logic *************************
public MainViewModel()
{
Department department = new Department();
}
//****************** You Logic *************************
}
}
You wouldn't have ViewModel for every Model, in MVVM you should have a unique ViewModel for almost every view. You would then map the Model to the ViewModel.
For example:
public class DepartmentViewModel
{
public string title { get; set; }
public string description { get; set; }
public IEnumerable<Worker> workers { get; set; }
//Additional ViewModel properties here
//These may or may not be items that exist in your Model
/// <summary>
/// Mapped to the description but truncated to 10 characters and followed by an elispe (...)
/// </summary>
public string ShortDescription
{
get
{
return description.Substring(0,10) + "...";
}
}
}
I realize at first this looks a little redundant. However, there could be other less 1:1 type of views you might create from the model.
Also check out automapper.org, this is a great tool for mapping object to object.
You have 1 view model that contains both the workers and the department.
If the view only wants to show certain attributes of the workers, then the view should do that filtering. Try using an item template:
<ListBox x:Name="_workers" ItemsSource="{Binding Workers}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding firstname}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding lastname}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The view model should contain:
private string _title;
public string Title {
get {return _title;}
set {_title = value; RaisePropertyChanged("Title");}
}
private string _description;
public string Description {
get {return _description;}
set {_description= value; RaisePropertyChanged("Description");}
}
public ObservableCollection Workers {get; private set;}
public Constructor()
{
Workers = new ObservableCollection();
}
//This method is called by the model once it has fetched data.
//This can be done as a callback or in an event handler
public CalledByTheModelAfterLoadingData(Department department)
{
Title = department.Title;
Description = department.Description;
foreach (var worker in department.Workers)
{
Workers.Add(worker);
}
}
精彩评论