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

WinUI3中从C#事件处理器操作UI的正确方法及页面切换方案

WinUI 3 页面切换与UI线程问题解决方案

1. 从UI线程正确捕获事件

OnAppIsReady事件确实可能在后台线程触发,而WinUI要求所有UI操作必须在UI线程执行。解决方法是通过DispatcherQueue将UI操作调度到UI线程:

实现代码

// MainWindow.xaml.cs
public MainWindow()
{
    this.InitializeComponent();
    // 订阅App的初始化完成事件
    App.OnAppIsReady += App_OnAppIsReady;
    // 初始化时先显示LoadingPage
    MainFrame.Navigate(typeof(LoadingPage));
}

private void App_OnAppIsReady(object sender, EventArgs e)
{
    // 强制在UI线程执行页面切换操作
    DispatcherQueue.TryEnqueue(() =>
    {
        MainFrame.Navigate(typeof(RegularContentPage));
        // 清除导航栈,避免用户返回LoadingPage
        MainFrame.BackStack.Clear();
    });
}

如果需要在App.xaml.cs中直接触发切换,也可以获取主窗口的DispatcherQueue来调度:

// App.xaml.cs
private async void RunInitialization()
{
    // 执行耗时初始化操作
    await LoadAppResourcesAsync();
    
    // 获取主窗口并调度UI操作
    if (Application.Current.Windows[0] is MainWindow mainWindow)
    {
        mainWindow.DispatcherQueue.TryEnqueue(() =>
        {
            mainWindow.MainFrame.Navigate(typeof(RegularContentPage));
            mainWindow.MainFrame.BackStack.Clear();
        });
    }
}

2. 更优的页面切换方案

推荐两种更贴合WinUI设计的方案:

方案一:基于Frame的原生导航管理

用MainWindow中的Frame作为页面容器,统一管理页面切换逻辑:

  • 优点:遵循WinUI原生导航规范,自带导航栈管理,适合多页面场景
  • 核心逻辑:初始化时导航到LoadingPage,初始化完成后导航到RegularContentPage,同时清理导航栈避免返回加载页

方案二:MVVM模式下的数据绑定切换

通过ViewModel驱动视图切换,解耦UI与业务逻辑:

// MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
    private Page _currentPage;
    public Page CurrentPage
    {
        get => _currentPage;
        set
        {
            _currentPage = value;
            OnPropertyChanged();
        }
    }

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

// MainWindow.xaml.cs
public MainWindow()
{
    this.InitializeComponent();
    ViewModel = new MainViewModel();
    // 初始显示LoadingPage
    ViewModel.CurrentPage = new LoadingPage();
    DataContext = ViewModel;
    App.OnAppIsReady += App_OnAppIsReady;
}

public MainViewModel ViewModel { get; }

private void App_OnAppIsReady(object sender, EventArgs e)
{
    DispatcherQueue.TryEnqueue(() =>
    {
        ViewModel.CurrentPage = new RegularContentPage();
    });
}

// MainWindow.xaml
<ContentControl Content="{Binding CurrentPage}" />
  • 优点:完全遵循MVVM模式,UI与业务逻辑分离,适合复杂应用的视图扩展

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:01:09