You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Native项目无MVVM框架,如何在App.cs设置启动ViewModel?

在无MVVM框架的Xamarin Native项目中配置启动ViewModel

针对你的需求:使用原生UI控件(iOS用UITableView/UICollectionView,Android用ListView/RecyclerView),采用无框架原生MVVM,实现类似Xamarin.Forms在App.xaml.cs中设置启动页的效果,以下是具体实现步骤:

1. 共享项目中定义全局ViewModel管理逻辑

在共享类库(如.NET Standard项目)中创建App.cs,统一管理启动ViewModel的创建与绑定逻辑:

public class App
{
    // 全局启动ViewModel实例
    public static BaseViewModel StartupViewModel { get; private set; }

    public App()
    {
        // 在这里指定你的启动ViewModel
        StartupViewModel = new MainViewModel();
    }

    // 通用方法:将ViewModel关联到对应平台的View
    public static void AttachViewModelToView<TView, TViewModel>(TView view, TViewModel viewModel)
        where TViewModel : BaseViewModel
        where TView : class
    {
        if (view is Android.App.Activity activity)
        {
            activity.SetDataContext(viewModel);
        }
        else if (view is UIKit.UIViewController vc)
        {
            vc.ViewModel = viewModel;
        }
    }
}

// 基础ViewModel类,实现INotifyPropertyChanged以支持数据更新通知
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

// 示例启动ViewModel
public class MainViewModel : BaseViewModel
{
    private string _pageTitle = "首页";
    public string PageTitle
    {
        get => _pageTitle;
        set { _pageTitle = value; OnPropertyChanged(); }
    }

    // 可在此添加业务逻辑、命令等内容
}

2. Xamarin.iOS 平台配置

在iOS项目的AppDelegate.cs中初始化共享项目的App,并将启动ViewModel绑定到根ViewController:

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    public override UIWindow Window { get; set; }

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        // 初始化共享项目的App实例,创建启动ViewModel
        var app = new App();

        // 创建首页ViewController并绑定ViewModel
        var mainVC = new MainViewController();
        App.AttachViewModelToView(mainVC, App.StartupViewModel);

        // 设置应用根ViewController
        Window = new UIWindow(UIScreen.MainScreen.Bounds);
        Window.RootViewController = mainVC;
        Window.MakeKeyAndVisible();

        return true;
    }
}

// iOS首页ViewController示例
public class MainViewController : UIViewController
{
    // 自定义ViewModel属性,用于接收绑定的实例
    public BaseViewModel ViewModel { get; set; }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        View.BackgroundColor = UIColor.White;

        if (ViewModel is MainViewModel mainVM)
        {
            // 绑定标题到导航栏
            NavigationItem.Title = mainVM.PageTitle;
            // 监听属性变化,实时更新UI
            mainVM.PropertyChanged += (sender, e) =>
            {
                if (e.PropertyName == nameof(mainVM.PageTitle))
                {
                    NavigationItem.Title = mainVM.PageTitle;
                }
            };
        }
    }
}

3. Xamarin.Android 平台配置

在Android项目的启动Activity(如MainActivity.cs)中初始化App,并完成ViewModel与Activity的绑定:

[Activity(Label = "@string/app_name", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        // 初始化共享项目的App实例
        var app = new App();

        // 绑定ViewModel到当前Activity
        App.AttachViewModelToView(this, App.StartupViewModel);

        if (App.StartupViewModel is MainViewModel mainVM)
        {
            // 绑定标题到ActionBar
            SupportActionBar.Title = mainVM.PageTitle;
            // 监听属性变化,在UI线程更新界面
            mainVM.PropertyChanged += (sender, e) =>
            {
                if (e.PropertyName == nameof(mainVM.PageTitle))
                {
                    RunOnUiThread(() => SupportActionBar.Title = mainVM.PageTitle);
                }
            };
        }
    }
}

// 给Android Activity添加DataContext扩展属性,用于存储ViewModel实例
public static class ActivityDataContextExtensions
{
    private static readonly ConditionalWeakTable<Activity, object> _contextStore = new ConditionalWeakTable<Activity, object>();

    public static void SetDataContext(this Activity activity, object context)
    {
        _contextStore.Remove(activity);
        _contextStore.Add(activity, context);
    }

    public static T GetDataContext<T>(this Activity activity) where T : class
    {
        _contextStore.TryGetValue(activity, out object context);
        return context as T;
    }
}

核心要点

  • Xamarin Native为分平台架构,无法像Xamarin.Forms那样直接在App.cs中设置全局View,因此通过共享项目的App.cs统一管理ViewModel的创建,再在各平台启动入口完成View与ViewModel的绑定。
  • 基础ViewModel必须实现INotifyPropertyChanged接口,才能让ViewModel的属性变化同步到UI。
  • 各平台的View需自行处理ViewModel的绑定逻辑,比如监听PropertyChanged事件更新UI元素。

内容的提问来源于stack exchange,提问作者Samy Gray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 00:20:30