98 lines
2.8 KiB
C#
98 lines
2.8 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Controls;
|
|||
|
|
using System.Windows.Data;
|
|||
|
|
using System.Windows.Documents;
|
|||
|
|
using System.Windows.Input;
|
|||
|
|
using System.Windows.Media;
|
|||
|
|
using System.Windows.Media.Imaging;
|
|||
|
|
using System.Windows.Shapes;
|
|||
|
|
|
|||
|
|
namespace Common
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// TipMessageWindow.xaml 的交互逻辑
|
|||
|
|
/// </summary>
|
|||
|
|
public partial class TipMessageWindow : Window
|
|||
|
|
{
|
|||
|
|
public TipMessageWindow(string message)
|
|||
|
|
{
|
|||
|
|
InitializeComponent();
|
|||
|
|
MessageTextBlock.Text = message;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static class DialogManager
|
|||
|
|
{
|
|||
|
|
// 事件:操作完成通知
|
|||
|
|
public static event Action OperationCompleted;
|
|||
|
|
|
|||
|
|
// 显示提示窗口并等待操作完成
|
|||
|
|
public static async Task ShowDialogAsync(Window owner, string message, Func<Task> operation)
|
|||
|
|
{
|
|||
|
|
var dialog = new TipMessageWindow(message);
|
|||
|
|
dialog.Owner = owner;
|
|||
|
|
|
|||
|
|
// 步骤1:先订阅事件(确保操作触发事件前已订阅)
|
|||
|
|
var closeTask = WaitForDialogCloseAsync(dialog);
|
|||
|
|
|
|||
|
|
// 步骤2:启动耗时操作(此时事件已订阅)
|
|||
|
|
var task = Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
await operation?.Invoke();
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
// 操作完成(无论成功/失败)都触发关闭事件
|
|||
|
|
OperationCompleted?.Invoke();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 步骤3:显示弹窗
|
|||
|
|
dialog.Show();
|
|||
|
|
|
|||
|
|
// 步骤4:等待弹窗关闭 + 操作完成
|
|||
|
|
await closeTask;
|
|||
|
|
await task;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static Task WaitForDialogCloseAsync(Window dialog)
|
|||
|
|
{
|
|||
|
|
var tcs = new TaskCompletionSource<bool>();
|
|||
|
|
// 定义事件处理方法(方便后续取消订阅)
|
|||
|
|
Action operationCompletedHandler = null;
|
|||
|
|
|
|||
|
|
// 事件触发时关闭弹窗
|
|||
|
|
operationCompletedHandler = () =>
|
|||
|
|
{
|
|||
|
|
// 必须在UI线程操作弹窗
|
|||
|
|
dialog.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
if (dialog.IsVisible)
|
|||
|
|
dialog.Close();
|
|||
|
|
});
|
|||
|
|
// 取消订阅(避免重复触发)
|
|||
|
|
OperationCompleted -= operationCompletedHandler;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 订阅事件
|
|||
|
|
OperationCompleted += operationCompletedHandler;
|
|||
|
|
|
|||
|
|
// 弹窗关闭时完成Task + 取消订阅
|
|||
|
|
dialog.Closed += (s, e) =>
|
|||
|
|
{
|
|||
|
|
OperationCompleted -= operationCompletedHandler;
|
|||
|
|
tcs.SetResult(true);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return tcs.Task;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|