我正在使用文章Model View View-Model (MVVM) in Silverlight作为在Silverlight中创建自己的MVVM示例的基础。
我已经收到了以下所有内容:
在我的主页I:
但是现在我如何将ModelView连接到Model?我觉得我需要将我的客户Model以某种方式注入CustomerViewModel,是吗?但到底怎么样?完成此MVVM示例的下一步是什么,以便我可以开始使用MVVM模式的优点,例如使用测试模型交换模型,使用新视图交换视图等。
MainPage.xaml.cs: 创建ViewModel,将View附加到ViewModel
using System.Windows.Controls;
using System.Collections.Generic;
namespace TestMvvm345
{
public partial class MainPage : UserControl
{
private CustomerViewModel customerData;
public MainPage()
{
InitializeComponent();
customerData = new CustomerViewModel();
customerHeaderView.DataContext = customerData;
List<Customer> customers = Customer.GetCustomers();
}
}
}
MainPage.xaml: 在主页的上下文中显示视图
<UserControl x:Class="TestMvvm345.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestMvvm345"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Left">
<local:CustomerHeaderView x:Name="customerHeaderView" Margin="10"/>
</StackPanel>
</Grid>
</UserControl>
CustomerViewModel.xaml: ViewModel
using System.ComponentModel;
namespace TestMvvm345
{
public class CustomerViewModel : INotifyPropertyChanged
{
private string firstName;
private string lastName;
public string FirstName
{
get { return firstName; }
set
{
firstName = value;
RaisePropertyChanged("FirstName");
}
}
public string LastName
{
get { return lastName; }
set
{
lastName = value;
RaisePropertyChanged("LastName");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
CustomerHeaderView.xaml 视图
<UserControl x:Class="TestMvvm345.CustomerHeaderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Left">
<ListBox x:Name="CustomerList" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{FirstName}"/>
<TextBlock
Text="{LastName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
</UserControl>
Customers.cs 模型
using System;
using System.Collections.Generic;
namespace TestMvvm345
{
public class Customer
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int NumberOfContracts { get; set; }
public static List<Customer> GetCustomers()
{
List<Customer> customers = new List<Customer>();
customers = new List<Customer>();
customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23 });
customers.Add(new Customer { FirstName = "Jane", LastName = "Smith", NumberOfContracts = 22 });
customers.Add(new Customer { FirstName = "John", LastName = "Tester", NumberOfContracts = 33 });
customers.Add(new Customer { FirstName = "Robert", LastName = "Smith", NumberOfContracts = 2 });
customers.Add(new Customer { FirstName = "Hank", LastName = "Jobs", NumberOfContracts = 5 });
return customers;
}
}
}
答案 0 :(得分:1)
我使用ViewModel的方式有些不同。在我的例子中,它实际上包装了Model类,将大部分数据传递给模型。这样,模型中的所有标准业务规则仍然可以按照它们应该的方式运行。 ViewModel仅公开数据绑定或其他UI目的实际需要的属性。此外,ViewModel可能包含用于数据绑定的其他属性/方法。
所以使用您的客户示例: 命名空间TestMvvm345 { 公共类CustomerViewModel:INotifyPropertyChanged {
private Customer _model;
public Customer Model
{
get
{ return _model; }
set
{
if (_model != null)
Model.PropertyChanged -= Model_PropertyChanged;
_model = value;
if (_model != null)
Model.PropertyChanged += Model_PropertyChanged;
}
}
void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
RaisePropertyChanged(e.PropertyName);
if (e.PropertyName == "FirstName" || e.PropertyName == "LastName")
RaisePropertyChanged("FullName");
}
public string FirstName
{
get { return Model.FirstName; }
set { Model.FirstName = value; }
}
public string LastName
{
get { return Model.LastName; }
set { Model.LastName = value; }
}
public string FullName
{
get { return FirstName + " " + LastName; }
}
public static IList<CustomerViewModel> GetCustomers()
{
var result = new List<CustomerViewModel>();
var customers = Customer.GetCustomers();
foreach (var customer in customers)
{
result.Add(new CustomerViewModel() { Model = customer });
}
return result;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
public class Customer : INotifyPropertyChanged
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int NumberOfContracts { get; set; }
public static List<Customer> GetCustomers()
{
List<Customer> customers = new List<Customer>();
customers = new List<Customer>();
customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23 });
customers.Add(new Customer { FirstName = "Jane", LastName = "Smith", NumberOfContracts = 22 });
customers.Add(new Customer { FirstName = "John", LastName = "Tester", NumberOfContracts = 33 });
customers.Add(new Customer { FirstName = "Robert", LastName = "Smith", NumberOfContracts = 2 });
customers.Add(new Customer { FirstName = "Hank", LastName = "Jobs", NumberOfContracts = 5 });
return customers;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}
现在在您的UI中使用以下代码进行绑定: customerHeaderView.DataContext = CustomerViewModel.GetCustomers();
ViewModel中的代码确实变得有点大,但可以将很多内容放在基类中,并且所有转到模型的属性都完全相同(想想T4模板)。