从MainViewModel调用ViewModel的方法

3
我目前在两个ViewModel之间通信方面遇到了问题。 下载我的应用程序以查看问题: http://www76.zippyshare.com/v/26081324/file.html 我有两个视图。
  • 一个名为'MainView.xaml'的视图,其数据上下文为'MainViewModel'。

  • 一个名为'FirstView.xaml'的视图,其数据上下文为'FirstViewModel'。

MainView具有一个ContentControl,其内容为FirstView。我的FirstViewModel如下所示:
public class FirstViewModel : ViewModelBase
{

    public FirstViewModel()
        {
        One = "0";
        Two = "0";
        Ergebnis = 0;
    }
    private string _one;
    public string One
    {
        get { return _one; }
        set
        {
            if (value != null)
            {
                    _one = value;
                    Calculate();
                    RaisePropertyChanged(() => One);
            }
        }
    }

    private string _two;
    public string Two
    {
        get { return _two; }
        set
        {
                    _two = value;
                    Calculate();
                    RaisePropertyChanged(() => Two9;
        }

    }

    private decimal _ergebnis;
    public decimal Ergebnis
    {
        get { return _ergebnis; }
        set
        {
            if (value != null)
            {
                if (value != _ergebnis)
                {
                    _ergebnis = value;
                    RaisePropertyChanged(() => Ergebnis);
                }
            }


        }
    }

    public void Calculate()
    {
        if (Two != null)
        {
            for (int i = 0; i < 500; i++)
            {
                Ergebnis = i;
            }
            Ergebnis = (decimal.Parse(One) + decimal.Parse(Two));
        }
    }

正如您看到的,每当属性'One'或'Two'的值被更改时,它都会调用Calculate()方法。现在我想要的是,当我在MainView中点击一个按钮时,MainViewModel必须调用FirstViewModel中的Calculate()方法。因此,我注释了属性中的Calculate()方法,并在MainViewModel中实现了一个RelayCommand:

MainView中的按钮

<Button Grid.Row="3" Command="{Binding ChangeValue}" />

主视图模型

public MainViewModel
{
    ChangeValue = new RelayCommand(ChangeValueCommandExecute);
}

public RelayCommand ChangeValue { get; private set; }
private FirstViewModel fwm;

private void ChangeValueCommandExecute()
{
    //CurrentView = Content of the ContentControl in the MainView, which is FirstView
    if (CurrentView.Content.ToString().Contains("FirstView"))
    {   
        fwm.Calculate();
    }
}

这意味着当我点击按钮时,将调用ChangeValueCommandExecute()。该命令将调用fwm.Calculate()并设置新的总和(= Ergebnis)。问题在于,当调用Calculate()时,“One”和“Two”的值始终为“0”。那么我如何在一个ViewModel中调用另一个ViewModel的方法?
编辑:为了明确起见:我想调用FirstViewModel()的方法'Calculate()',而不使用'new FirstViewModel()'!

我可能漏掉了什么,但是我没有看到 Calculate 方法应该如何更改 "One" 和 "Two" 的值。只有 "Ergebnis" 值会被更改。 - Kimko
没错,在我的第一篇文章中没有提到它。FirstView.xaml 有2个文本框,它们各自绑定到属性,如 <TextBox Text="{Binding One, Mode=TwoWay}"/> 和 'Ergebnis' -> <TextBlock Content="{Binding Ergebnis}"/>。您可以下载程序自己看看。正如我所说的,当我取消注释 setter 属性中的 'Calculate()' 时,计算正常工作,但是我想在单击另一个视图中的按钮(具有 DataContext 绑定到另一个 ViewModel)时才调用 Calculate()。 - Rudi
你调试过这个了吗?当点击按钮时,你有查看 Calculate() 中正在发生的事情吗?通常,如果我需要在 MVVM 应用程序中在视图模型之间进行通信,我会使用一个所有视图模型都可以使用来传递消息的消息系统。 - Chris
是的,我进行了调试。'One'和'Two'的值为“0”(标准值)。 - Rudi
1个回答

2

我无法查看您的项目,因为它需要Windows 8,但是您确定作为FirstViewDataContextFirstViewModel与您在MainViewModel中提到的FirstViewModel是相同的吗?从我的观察中,您在MainViewModel的构造函数中新建了一个私有的FirstViewModel


是的,你说得对...我正在MainViewModel的构造函数中创建一个FirstViewModel实例。由于我不知道如何调用FirstViewModel中的“Calculate()”方法,所以我这么做...还有其他方法可以调用“Calculate()”方法而不必创建一个新的FirstViewModel实例吗? - Rudi
1
是的,你应该在MainViewModel中有一个公共引用到你的FirstViewModel。然后你主窗口的DataContext将会是MainViewModel,ContentControl的DataContext将会是对于同一个FirstViewModel实例的引用,这个实例也在MainViewModel中。 - ChrisO
1
好的,搞定了!现在它可以工作了。就像你说的那样,在MainViewModel的构造函数中为FirstViewModel创建一个变量(例如fvm = new FirstViewModel)。然后说MyContent.DataContext = fvm; 现在我可以调用fvm.Calculate(); 并且值不会是0。 - Rudi

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