【问题标题】:How to set BindingContext of multiple pages to the same ViewModel in Xamarin.Forms?如何在 Xamarin.Forms 中将多个页面的 BindingContext 设置为同一个 ViewModel?
【发布时间】:2015-02-09 01:22:18
【问题描述】:

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

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 的内容并不重要。使用这种结构,我可以将相同的 _ViewModel 对象设置为多个窗口的 DataContext。 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 的正确方法,但我想知道这是否会导致每次打开 MainPage 时都会创建一个具有默认值的新 ViewModel 对象。而且我不明白其他页面如何能够使用与MainPage 相同的 ViewModel 对象。在我看来,上面的 WPF 项目代码是合乎逻辑且简单的。一个 ViewModel 对象就是这样。我必须为每个页面创建不同的 ViewModel 类吗?这对我来说似乎是错误的。

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

【问题讨论】:

    标签: c# xaml mvvm binding xamarin.forms


    【解决方案1】:

    是的,您当然可以将页面的 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;
        }
    }
    

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

    【讨论】:

    • 非常感谢!这种 ViewModelLocator 方法很棒!
    • 是的,它非常有用。您甚至可以使用 ViewModelLocator 模式将特定的 ViewModel 用于不同的条件(例如,用于调试构建的“模拟”ViewModel)。
    猜你喜欢
    • 2016-11-27
    • 1970-01-01
    • 2016-12-08
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2017-12-15
    相关资源
    最近更新 更多