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

Gáb*_*kás 4 c# xaml binding mvvm xamarin.forms

我是 Xamarin.Forms 的新手,我想使用 MVVM 模式和 XAML 创建一个跨平台应用程序。在我的形式项目(PCL),我想设置的BindingContext我的的MainPage在未来的多个页面,并以同样的视图模型。这可能吗?让我展示一下我在说什么。下面是我早期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
}
Run Code Online (Sandbox Code Playgroud)

ViewModel 的内容并不重要。使用这个结构,我能够设置与多个窗口_ViewModelDataContext相同的对象。Xamarin.Forms 中是否有与此等效的内容?

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

public class App
{
    public static Page GetMainPage ()
    {   
        return new MainPage();
    }
} 
Run Code Online (Sandbox Code Playgroud)

来自MainPage.xaml.cs的代码:

public partial class MainPage : ContentPage
{   
    public MainPage ()
    {
        InitializeComponent ();
        BindingContext = new MyViewModel ();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*per 6

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

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

使用 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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