如何将多个页面的BindingContext设置为Xamarin.Forms中的同一ViewModel?

时间:2014-12-10 18:09:15

标签: c# xaml mvvm binding xamarin.forms

我是Xamarin.Forms的新手,我想使用MVVM模式和XAML创建一个跨平台的应用程序。在我的表单项目(pcl)中,我想将 MainPage BindingContext 以及将来的多个页面设置为同一个ViewModel。这可能吗?让我展示一下我在说什么。以下是我之前的 WPF 项目的代码段( App.xaml.cs ):

public partial class App : Application
{
    private MainWindow _MainWindow;
    private MyViewModel _ViewModel;

    public App()
    {
        _ViewModel = new MyViewModel();

        _ViewModel.SomeEvent += new System.EventHandler(ViewModel_SomeEvent);
    }
}



protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    _MainWindow = new MainWindow();
    _MainWindow.DataContext = _ViewModel;
    _MainWindow.Show();         
}

private void ViewModel_SomeEvent(object sender, EventArgs e)
{
     //Do something
}

ViewModel的内容并不重要。通过这种结构,我能够设置与多个窗口的 DataContext 相同的_ViewModel对象。在Xamarin.Forms中是否有与此类似的东西?

这是我的pcl项目中的一个简单代码( App.cs ):

public class App
{
    public static Page GetMainPage ()
    {   
        return new MainPage();
    }
} 

来自 MainPage.xaml.cs 的代码:

public partial class MainPage : ContentPage
{   
    public MainPage ()
    {
        InitializeComponent ();
        BindingContext = new MyViewModel ();
    }
}

我知道这是设置页面的 BindingContext 的正确方法,但我想知道这是否会导致每次打开时都会创建一个具有默认值的新ViewModel对象{{1} }。而且我也不明白其他页面如何能够使用与MainPage相同的ViewModel对象。在我看来,上面的 WPF 项目代码是合乎逻辑且简单的。一个ViewModel对象就是这样。我是否必须为每个页面创建不同的ViewModel类?这对我来说似乎不对。

那么有没有办法以某种方式创建一个ViewModel对象 - 可能在 App.cs ?我对此表示怀疑。 - 我可能希望稍后添加到项目中的每个页面都使用的地方。我希望我已经清楚了,并提前感谢你!

1 个答案:

答案 0 :(得分:3)

是的,您当然可以将页面的BindingContext设置为应用程序管理的对象; ViewModel不必在构造函数中创建(甚至设置);这恰好是很多示例代码所做的事情。

您可以采用以下几种方法:ViewModelLocator,它创建单个ViewModel并将其公开给任何使用ViewModelLocator连接绑定上下文的视图,依赖注入容器(如MvvmLight提供的SimpleIOC)与ViewModel注册为单例,在Page工厂中手动设置,依此类推。

使用ctor中引用的ViewModelLocator的一个简单示例是:

public static class ViewModelLocator
{
    private static MyViewModel _myViewModel = new MyViewModel();
    public static MyViewModel MainViewModel
    {
        get
        {
            return _myViewModel;
        } 
    } 
}

...

public partial class MainView : ContentPage
{
    public MainView()
    {
        BindingContext = ViewModelLocator.MainViewModel;
    }
}

...

public partial class SomeOtherView : ContentPage
{
    public SomeOtherView()
    {
        BindingContext = ViewModelLocator.MainViewModel;
    }
}

你也可以拥有它,以便通过ViewModelLocator上的setter设置_myViewModel成员,从IOC容器中提取它等等。