MVVM模式下的Silverlight子窗口

11

我正在尝试使用Silverlight(3)中的MVVM模式找到从ChildWindow / 弹出窗口获取数据的正确方法。例如:我有一个包含数据输入表单的主页面,我想打开一个包含客户列表的弹出窗口。当用户选择客户时,我想将所选客户转移到主页面。这是我目前正在使用的(示例)代码:

主页面

public partial class MainPage : UserControl
{
    public MainPageViewModel ViewModel { get; private set; }

    public MainPage()
    {
        InitializeComponent();
        ViewModel = new MainPageViewModel();
        DataContext = ViewModel;
    }

    private void SearchCustomer_Click(object sender, RoutedEventArgs e)
    {
        ViewModel.SearchCustomer();
    }
}

public class MainPageViewModel: ViewModel
{
    private string customer;
    public string Customer
    {
        get { return customer; }
        set { customer = value; RaisePropertyChanged("Customer"); }
    }

    public void SearchCustomer()
    {
        // Called from a view
        SearchWindow searchWindow = new SearchWindow();
        searchWindow.Closed += (sender, e) =>
        {
            if ((bool)searchWindow.DialogResult)
            {
                Customer = searchWindow.ViewModel.SelectedCustomer.ToString();
            }
        };
        searchWindow.Show();
    }
}

子窗口

public partial class SearchWindow : ChildWindow
{
    public SearchWindowViewModel ViewModel { get; private set; }

    public SearchWindow()
    {
        InitializeComponent();
        ViewModel = new SearchWindowViewModel();
        DataContext = ViewModel;
    }

    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = ViewModel.OkButtonClick();
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = ViewModel.CancelButtonClick();
    }
}

public class SearchWindowViewModel: ViewModel
{
    private Customer selectedCustomer;        
    private ObservableCollection<Customer> customers;

    public ObservableCollection<Customer> Customers
    {
        get { return customers; }
        set {customers = value; RaisePropertyChanged("Customers"); }
    }

    public Customer SelectedCustomer
    {
        get { return selectedCustomer; }
        set { selectedCustomer = value; RaisePropertyChanged("SelectedCustomer"); }
    }

    public SearchWindowViewModel()
    {
        Customers = new ObservableCollection<Customer>();
        ISearchService searchService = new FakeSearchService();
        foreach (Customer customer in searchService.FindCustomers("dummy"))
            Customers.Add(customer);
    }

    public bool? OkButtonClick()
    {
        if (SelectedCustomer != null)
            return true;
        else
            return null; // show some error message before that
    }

    public bool? CancelButtonClick()
    {
        return false;
    }
}

这是正确的方式吗?还有更简单的方法吗?

谢谢, Rok

2个回答

6
更为棘手的问题是在VM中使用与View相关的术语和类型。点击事件、DialogResults等都不应该出现在ViewModels中。
关于这个问题,我曾在这里提出过类似的问题:Handling Dialogs in WPF with MVVM 我接受的答案是使用Mediator模式来解决这个问题。可以看一下。 :)

2
谢谢,我会看一下。我已经发现我做得“完全”错误了,我已经改变了我的代码来使用命令(绑定到ICommand)并将DialogResult从VM中删除。下一步是看中介者模式 :) - rrejc
我同意中介者模式是正确的选择。在博客中写到:http://basaratali.blogspot.com/2010/12/mediator-for-mvvmlight-like-one-by.html - basarat

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接