C# WPF实现加载模态弹窗:数据加载时禁用父视图
WPF 自动触发模态加载弹窗解决方案
实现步骤
1. 创建加载模态窗口
新建一个LoadingWindow.xaml,设置为居中、无标题、不可调整大小的模态窗口:
<Window x:Class="YourAppNamespace.LoadingWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="150" Width="300" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterOwner"> <Grid> <TextBlock Text="等待数据获取完成" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="14"/> </Grid> </Window>
2. 新窗口的加载逻辑处理
在目标窗口(比如DataWindow.xaml)的后台代码中,处理窗口加载事件,自动触发加载弹窗并异步获取数据:
private async void Window_Loaded(object sender, RoutedEventArgs e) { // 先隐藏主内容区域,避免旧数据显示 MainContent.Visibility = Visibility.Collapsed; // 初始化加载窗口,设置父窗口确保居中 var loadingWindow = new LoadingWindow(); loadingWindow.Owner = this; // 启动异步数据加载任务,完成后关闭加载窗口 var dataLoadTask = LoadNewDataAsync().ContinueWith(task => { // 必须在UI线程操作窗口 Application.Current.Dispatcher.Invoke(() => loadingWindow.Close()); return task.Result; }); // 显示模态加载窗口,此时父窗口会被冻结,直到窗口关闭 loadingWindow.ShowDialog(); // 数据加载完成后更新视图 var newData = await dataLoadTask; UpdateViewData(newData); // 显示新数据 MainContent.Visibility = Visibility.Visible; } // 替换为你的实际异步数据获取逻辑 private async Task<YourDataModel> LoadNewDataAsync() { // 模拟数据获取延迟,实际替换为API调用、数据库查询等 await Task.Delay(3000); return new YourDataModel(); // 返回你的数据模型 } // 替换为你的视图更新逻辑 private void UpdateViewData(YourDataModel data) { // 绑定数据到UI控件,比如: // DataGrid.ItemsSource = data; // TextBlock.Text = data.SomeProperty; }
3. 配置目标窗口的主内容区域
在DataWindow.xaml中,给主内容容器(比如Grid、StackPanel)命名为MainContent,初始设为隐藏:
<Window x:Class="YourAppNamespace.DataWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="数据窗口" Height="450" Width="800" Loaded="Window_Loaded"> <!-- 主内容区域,初始隐藏 --> <Grid x:Name="MainContent" Visibility="Collapsed"> <!-- 你的数据展示控件,比如DataGrid、TextBlock等 --> </Grid> </Window>
关键说明
ShowDialog()本身会让父窗口处于禁用/冻结状态,无需额外处理父窗口的禁用逻辑。- 数据加载必须用异步方法(
async/await),避免阻塞UI线程导致加载窗口无响应。 - 关闭加载窗口时必须通过
Dispatcher.Invoke切换到UI线程,因为WPF控件只能在创建它的线程中操作。
内容的提问来源于stack exchange,提问作者MuriTuri
相关产品推荐
相关产品推荐

