在窗口关闭时从另一个视图模型中获取属性值

时间:2017-02-06 14:35:49

标签: c# wpf mvvm viewmodel

我有一个视图模型,其中有一个命令,显示一个新窗口(它有自己的视图模型)。新窗口的视图模型具有各种属性,当我关闭新窗口时,我想将这些属性传递回调用它的第一个视图模型。

我打破了这里的MVVM模式,因为用ShowDialog()显示新窗口似乎更快更容易。这是我的代码示例:

MainViewModel:

//Note: The OnPropertyChanged and CanExecute functions are implemented

//method via command to show a new window
private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();
    syo.ShowDialog();
}

新窗口的视图模型:

class SYOWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;       

    private DateTime _timeStart;
    public DateTime TimeStart
    {
        get { return _timeStart; }
        set { _timeStart = value; OnPropertyChanged("TimeStart"); }
    }

    private DateTime _timeStart2;
    public DateTime TimeStart2
    {
        get { return _timeStart2; }
        set { _timeStart2 = value; OnPropertyChanged("TimeStart2"); }
    }

    // Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

以下是SYOWindow的代码隐藏:

using Proj1.ViewModels; //viewmodel located in different folder in project
public partial class SYOWindow : Window
{
    public SYOWindowViewModel vm => (SYOWindowViewModel)DataContext; //error here

    public SYOWindow()
    {
        InitializeComponent();
    }

    private void OKBtn_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
    }

    private void CancelBtn_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;
    }
}

所以在我用MainViewModel中的'syo.ShowDialog()'打开新窗口后,我在syo Window的SYOWindowViewModel中设置了一些属性,我想将这些属性返回给MainViewModel。我无法弄清楚“正确”和最干净的方法是什么。我已经读过我可以转换DataContext然后以这种方式获取值,但这似乎有点不对。但也许是自从我使用showdialog打破MVVM以来唯一的方法。

2 个答案:

答案 0 :(得分:1)

ShowDialog();阻止执行,直到对话框关闭,所以你需要做的就是:

form.ShowDialog();
var myVar = form.myVar;

答案 1 :(得分:1)

ShowDialog()阻止,因此您可以让父母在ShowDialog()退出后从孩子的视图模型中获取内容:

private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();
    syo.ShowDialog();

    var vm = (SYOWindowViewModel)syo.DataContext;

    this.Foo = vm.Foo;
}

如果您为SYOWindow提供ViewModel属性,则可以稍微简化一下代码:

public partial class SYOWindow : Window
{
    //  ...stuff

    //  C#6 version -- but if you're on an earlier version of C#, you'll get 
    //  "DataContext is a property but is used like a type" and a red squiggly.
    //public SYOWindowViewModel ViewModel => (SYOWindowViewModel)DataContext;

    //  C#<=5. This works fine in C#6 as well.
    public SYOWindowViewModel vm { get { return (SYOWindowViewModel)DataContext; } }

    //  ...more stuff
 }

然后父母可以这样做:

private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();

    syo.ShowDialog();

    this.Foo = syo.ViewModel.Foo;
}

如果SYOWindow使用its DialogResult property,您可以执行以下操作:

private void ShowSYOWindow(object parameter)
{
    SYOWindow syo = new SYOWindow();

    if (syo.ShowDialog().GetValueOrDefault())
    {
        this.Foo = syo.ViewModel.Foo;
    }
}