彩票走势图

Silverlight MVVM 模式下与子窗体交互

转帖|其它|编辑:郝浩|2011-06-30 14:51:17.000|阅读 1617 次

概述:Model View ViewModel(MVVM)是在 Silverlight 和 WPF 项目开发中应用最多的结构模式,也是 Silverlight 和 WPF 项目开发的最佳模式。本文的主要目的不是讲解 MVVM 模式。目前已有很多 MVVM 框架可以用来简化 MVVM 开发,如 Prism、SilverlightFX、MvvmLight、Caliburn、Simple MVVM Toolkit等。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  Model View ViewModel(MVVM)是在 Silverlight 和 WPF 项目开发中应用最多的结构模式,也是 Silverlight 和 WPF 项目开发的最佳模式。本文的主要目的不是讲解 MVVM 模式。目前已有很多 MVVM 框架可以用来简化 MVVM 开发,如 Prism、SilverlightFX、MvvmLight、Caliburn、Simple MVVM Toolkit等。

  在 程序开发中经常会遇到诸如弹出提示框、确认框、用户输入窗口等的情况,在 Silverlight 中这些情况都可以用子窗体(Child Window)来处理。在未使用 MVVM 模式的情况下,我们可以在用户控件或页面的后置代码(Code Behind)中实例化一个子窗体,调用子窗体的 Show 方法来弹出子窗体,然后通过子窗体的 Closed 方法用户的操作结果。但是在使用 MVVM 模式的情况下,为了使 Model 和 View 最大限度的分离,我们要使用尽可能少的后置代码。如果在后置代码中实例化并显示子窗体,这就使用代码和视图结合在一起了;当然也可以在 ViewModel 里实例化并显示子窗体,这样又使子窗体和 ViewModel 结合在一起了。

  本文将使用 MvvmLight 框架来演示如何在 MVVM 模式下与子窗体交互,即如何在 ViewModel 中弹出一个子窗体。

  首先我们来看一下示例程序的运行结果:

 

  程序运行后当用户单击 New Customer 按钮时,就会弹出一个子窗体,用户输入Customer Id、Customer Name、Customer City 后单击 OK 按钮就会在主页面的客户列表中显示出刚才输入的客户信息。下面是本示例具体的实现。

  新 建一个 Silverlight 项目,然后在项目中添加Views、Models、ViewModels、Locators文件夹(如果是通过 MvvmLight 模板创建的 Silverlight 项目,默认 ViewModel Locator 和 ViewModel 在同一文件夹中)。添加对程序集 GalaSoft.MvvmLight.Extras.SL4 和 GalaSoft.MvvmLight.SL4 的引用(如果通过 MvvLight 模板创建则会自动引用)。在 Model 文件夹中新建一个 Customer Model,完整代码如下:

 
01 public class Customer : INotifyPropertyChanged
02 {
03     private string customerId;
04     public string CustomerId
05     {
06         get { return customerId; }
07         set
08         {
09             customerId = value;
10             NotifyPropertyChanged("CustomerID");
11         }
12     }
13  
14     private string customerName;
15     public string CustomerName
16     {
17         get { return customerName; }
18         set
19         {
20             customerName = value;
21             NotifyPropertyChanged("CustomerName");
22         }
23     }
24  
25     private string city;
26     public string City
27     {
28         get { return city; }
29         set
30         {
31             city = value;
32             NotifyPropertyChanged("City");
33         }
34     }
35  
36     public event PropertyChangedEventHandler PropertyChanged;
37  
38     public void NotifyPropertyChanged(string propertyName)
39     {
40         if (PropertyChanged != null)
41             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
42     }
43 }

  下面是 MainPage 的后置代码:

 
01 public partial class MainPage : UserControl
02 {
03     public MainPage()
04     {
05         InitializeComponent();
06  
07         Messenger.Default.Register<string>(
08             this,
09             "MainWindow",
10             msg =>
11             {
12                 NewCustomerView newCustomer = new NewCustomerView();
13                 newCustomer.Title = msg;
14                 newCustomer.Show();
15             });
16     }
17 }

  从上面的代码中可以看到,我使用 MvvmLight 的 Messenger 在主窗体中注册了一个消息接收者,用于接收 ViewModel 发来的消息并弹出子窗体。下面是子窗体 NewCustomerView 的后置代码:

 
01 public partial class NewCustomerView : ChildWindow
02 {
03     public NewCustomerView()
04     {
05         InitializeComponent();
06  
07         Messenger.Default.Register<Customer>(
08             this,
09             "ChildWindow",
10             msg =>
11             {
12                 this.DialogResult = true;
13             });
14     }
15 }

  我同样在子窗体中也注册一个消息接收者,接收 ViewModel 发来的消息并关闭子窗体。注意主窗体中注册的消息接收者的 Token 为 “MainWindow”,子窗体中注册的消息接收者的 Token 为 “ChildWindow”,在 ViewModel 中发送消息时,只有与发送的消息的 Token 相同的接收者才收到消息。下面是 MainViewModel 的代码,这里只是为了演示,主窗体和子窗体共用了一个 ViewModel。

 
01 public class MainViewModel : ViewModelBase
02 {       
03     public MainViewModel()
04     {
05         OKButtonCommand = new RelayCommand<Customer>(OKButtonClick);
06         NewCustomerCommand = new RelayCommand(NewCustomer);
07  
08         _customer = new Customer();
09         _customers = new ObservableCollection<Customer>();
10         // 注册一个接收者 Token 为 ChildWindow
11         Messenger.Default.Register<Customer>(this, "ChildWindow", AddCustomer);
12     }
13  
14     private void AddCustomer(Customer param)
15     {
16         _customers.Add(param);
17         RaisePropertyChanged("Customers");
18     }
19  
20     // customer list
21     private ObservableCollection<Customer> _customers;
22     public ObservableCollection<Customer> Customers
23     {
24         get
25         {
26             return _customers;
27         }
28     }
29  
30     // customer model
31     private Customer _customer;
32     public Customer Model
33     {
34         get
35         {
36             return _customer;
37         }
38         set
39         {
40             _customer = value;
41             RaisePropertyChanged("Model");
42         }
43     }
44  
45     // add customer command
46     public RelayCommand NewCustomerCommand { get; private set; }
47     private void NewCustomer()
48     {
49         /*
50             * 发送一个字符串信息 New Customer
51             * Token 为 MainWindow 只有具有相同 Token 接收者都会接收到该信息
52             */
53         Messenger.Default.Send("New Customer", "MainWindow");
54     }
55  
56     public RelayCommand<Customer> OKButtonCommand { get; private set; }
57     private void OKButtonClick(Customer param)
58     {
59         /*
60             * 发送一个 Customer 信息
61             * Token 为 ChildWindow 只有具有相同 Token 接收者都会接收到该信息
62             */
63         Messenger.Default.Send<Customer>(param, "ChildWindow");
64     }
65 }

  在 ViewModel 中也注册了一个消息接收者,用于接收子窗体返回的数据。ViewModel 中的 NewCustomerCommand 是绑定到主窗体的 NewCustomer 按钮的,单击按钮 NewCustomer 时调用 NewCustomer() 方法向主窗体发送一个消息, 主窗体接收到消息后弹出子窗体。ViewModel 中的 OKButtonCommand 是绑定到子窗体的 OKButton 的,单击按钮 OKButton 时调用 OKButtonClick() 向子窗体和 ViewModel 发送一个消息,子窗体接收到消息时关闭,ViewModel 接收到消息时将参数 Customer 添加 Customer 列表中。以下是按钮的事件绑定代码:

 
01 <Button Content="New Customer" Width="120" Height="30">
02     <i:Interaction.Triggers>
03         <i:EventTrigger EventName="Click">
04             <cmd:EventToCommand Command="{Binding NewCustomerCommand}" />
05         </i:EventTrigger>
06     </i:Interaction.Triggers>
07 </Button>
08  
09 <Button x:Name="OkButton" Content="OK" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1">
10     <i:Interaction.Triggers>
11         <i:EventTrigger EventName="Click">
12             <cmd:EventToCommand Command="{Binding OKButtonCommand}" CommandParameter="{Binding ElementName=Customer, Path=DataContext}" />
13         </i:EventTrigger>
14     </i:Interaction.Triggers>
15 </Button>

  本示例只是提供一个在 MVVM 模式下与子窗体交互的解决方法,这个解决方法也并不是纯粹的 MVVM,完整的示例请查看附件的示例代码。


标签:MVVM

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP