avalonia实现自定义小弹窗 | 您所在的位置:网站首页 › reactui框架 › avalonia实现自定义小弹窗 |
对于使用avalonia的时候某些功能需要到一些提示,比如异常或者成功都需要对用户进行提示,所以需要单独实现弹窗功能,并且可以自定义内部组件,这一期将手动实现一个简单的小弹窗,并且很容易自定义 创建项目实现我们需要创建一个avaloniaMVVM的项目模板 ![]() 并且取名PopoverExample ![]() 然后一直默认创建。 创建弹窗组件在Views文件夹中创建一个组件,选择Window模板,创建名称Dialog ![]() 然后打开Dialog.axaml文件,修改相关代码, 标题 关闭以下代码是用于隐藏默认的标题栏的 ExtendClientAreaToDecorationsHint="True" ExtendClientAreaChromeHints="NoChrome" ExtendClientAreaTitleBarHeightHint="-1"打开DialogBase.axaml.cs ,修改修改代码 using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; namespace Dialog.Views; public partial class DialogBase : Window { public DialogBase() { InitializeComponent(); #if DEBUG this.AttachDevTools(); #endif } private void InitializeComponent() { AvaloniaXamlLoader.Load(this); } private void Close_OnClick(object? sender, RoutedEventArgs e) { Close(); } } 创建DialogManage类创建DialogManage类,用于管理Dialog 创建DialogManage.cs,添加以下代码 using System; using System.Collections.Generic; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Threading; namespace Dialog.Views; public static class DialogManage { private static readonly Dictionary _dialogBases = new(); public static void Show(DialogType type, string content, int height = 100, int width = 200, int timing = 3000) { DialogBase dialog; // 防止并发可自行修改 lock (_dialogBases) { if (_dialogBases.Remove(type, out var dialogBase)) { try { dialogBase.Close(); } catch { } } dialog = new DialogBase { Height = height, Width = width, WindowStartupLocation = WindowStartupLocation.Manual // 不设置的话无法修改窗口位置 }; if (timing > 0) { // 弹窗定时关闭 _ = Task.Run(async () => { await Task.Delay(timing); // 先删除并且拿到删除的value if (_dialogBases.Remove(type, out var dialogBase)) { // 操作组件需要使用ui线程 _ = Dispatcher.UIThread.InvokeAsync(() => { try { // 关闭弹窗组件 dialogBase.Close(); } // 可能已经被关闭所以可能会出现异常 catch { } }); } }); } // 添加到字典中 _dialogBases.TryAdd(type, dialog); } // 获取当前屏幕 var bounds = dialog.Screens.ScreenFromVisual(dialog).Bounds; // 偏移 int skewing = 20; // window的任务栏高度 int taskbar = 50; int x, y; switch (type) { case DialogType.topLeft: x = skewing; y = skewing; break; case DialogType.topCenter: x = (int)((bounds.Width - dialog.Width) / 2); y = skewing; break; case DialogType.topRight: x = (int)((bounds.Width - dialog.Width) - skewing); y = skewing; break; case DialogType.leftLower: x = 20; y = (int)(bounds.Height - dialog.Height) - taskbar - skewing; break; case DialogType.centerLower: x = (int)((bounds.Width - dialog.Width) / 2); y = (int)(bounds.Height - dialog.Height) - taskbar - skewing; break; case DialogType.rightLower: x = (int)(bounds.Width - dialog.Width - skewing); y = (int)(bounds.Height - dialog.Height) - taskbar - skewing; break; default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } // 设置弹窗的位置 dialog.Position = new PixelPoint(x, y); // 获取内容显示的组件并且将内容显示上去 var contentBox = dialog.Find("Content"); contentBox.Text = content; dialog.Show(); } } public enum DialogType { /// /// 左上 /// topLeft, /// /// 居中靠上 /// topCenter, /// /// 右上 /// topRight, /// /// 左下 /// leftLower, /// /// 居中靠下 /// centerLower, /// /// 右下 /// rightLower }对于弹窗组件已经完成, 基本使用弹窗打开MainWindow.axaml文件修改代码 打开新弹窗打开 MainWindow.axaml.cs修改相关代码 using Avalonia.Controls; using Avalonia.Interactivity; namespace Dialog.Views; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } // 定义枚举开始的值 private int i = 0; private void OpenDialog_OnClick(object? sender, RoutedEventArgs e) { // 弹窗新窗口 DialogManage.Show((DialogType)i++, "弹窗内容:" + i); // 超过枚举值重新赋值 if (i == 6) { i = 0; } } } 执行效果![]() 来自token的分享 技术交流群:737776595 |
CopyRight 2018-2019 实验室设备网 版权所有 |