基于Avalonia实现自定义弹窗的示例详解
作者:tokengo 时间:2022-02-27 16:30:45
对于使用avalonia
的时候某些功能需要到一些提示,比如异常或者成功都需要对用户进行提示,所以需要单独实现弹窗功能,并且可以自定义内部组件,这一期将手动实现一个简单的小弹窗,并且很容易自定义
创建项目
实现我们需要创建一个avalonia
MVVM的项目模板
并且取名PopoverExample
然后一直默认创建。
创建弹窗组件
在Views
文件夹中创建一个组件,选择Window模板
,创建名称Dialog
然后打开Dialog.axaml
文件,修改相关代码,
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Dialog.Views.DialogBase"
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaTitleBarHeightHint="-1"
Title="DialogBase">
<StackPanel>
<Grid>
<Grid HorizontalAlignment="Left">
<TextBlock>标题</TextBlock>
</Grid>
<Grid HorizontalAlignment="Right">
<Button Click="Close_OnClick" Name="Close">关闭</Button>
</Grid>
</Grid>
<Grid>
<TextBlock Name="Content"></TextBlock>
</Grid>
</StackPanel>
</Window>
以下代码是用于隐藏默认的标题栏的
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类
创建Dialog
Manage类,用于管理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<DialogType, DialogBase> _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<TextBlock>("Content");
contentBox.Text = content;
dialog.Show();
}
}
public enum DialogType
{
/// <summary>
/// 左上
/// </summary>
topLeft,
/// <summary>
/// 居中靠上
/// </summary>
topCenter,
/// <summary>
/// 右上
/// </summary>
topRight,
/// <summary>
/// 左下
/// </summary>
leftLower,
/// <summary>
/// 居中靠下
/// </summary>
centerLower,
/// <summary>
/// 右下
/// </summary>
rightLower
}
对于弹窗组件已经完成,
基本使用弹窗
打开MainWindow.axaml
文件修改代码
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Dialog.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Dialog.Views.MainWindow"
Height="400"
Width="400"
Icon="/Assets/avalonia-logo.ico"
Title="Dialog">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<StackPanel HorizontalAlignment="Center">
<Button Height="40" Name="OpenDialog" Click="OpenDialog_OnClick">打开新弹窗</Button>
</StackPanel>
</Window>
打开 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;
}
}
}
执行效果
来源:https://www.cnblogs.com/hejiale010426/p/17097846.html
标签:Avalonia,自定义,弹窗
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
java中Struts2文件上传问题详解
2023-12-16 10:27:54
解析Tars-Java客户端源码
2023-04-08 01:18:39
![](https://img.aspxhome.com/file/2023/7/89587_0s.jpg)
C#获取CPU编号的方法
2022-01-05 10:57:37
Spring Boot多个定时任务阻塞问题的解决方法
2023-09-20 11:43:36
Kotlin协程概念原理与使用万字梳理
2023-03-28 21:29:32
![](https://img.aspxhome.com/file/2023/7/94287_0s.png)
java图片识别文字的方法
2021-11-11 02:43:03
Java 阻塞队列和线程池原理分析
2022-04-19 11:57:45
![](https://img.aspxhome.com/file/2023/3/81993_0s.png)
SpringMVC拦截器创建配置及执行顺序
2023-06-06 20:41:16
![](https://img.aspxhome.com/file/2023/1/62351_0s.png)
springmvc不进入Controller导致404的问题
2023-03-18 01:29:20
![](https://img.aspxhome.com/file/2023/2/62102_0s.png)
java实现转圈打印矩阵算法
2022-11-27 06:38:21
mybatis中<if>标签bool值类型为false判断方法
2023-11-20 11:28:33
java客户端登陆服务器用户名验证
2023-11-09 07:03:09
![](https://img.aspxhome.com/file/2023/3/63283_0s.png)
C语言实现两个矩阵相乘
2023-07-22 12:41:20
![](https://img.aspxhome.com/file/2023/6/103076_0s.png)
C# WPF如何反射加载Geometry几何图形数据图标
2021-09-06 11:39:08
![](https://img.aspxhome.com/file/2023/9/86969_0s.png)
Spring自动配置之condition条件判断下篇
2023-10-15 10:04:59
![](https://img.aspxhome.com/file/2023/0/62060_0s.png)
Java编程Webservice指定超时时间代码详解
2023-11-02 23:17:12
基于C#调用OCX控件的常用方法(推荐)
2021-06-24 11:56:29
![](https://img.aspxhome.com/file/2023/9/79099_0s.png)
Java注解与反射原理说明
2021-06-18 01:56:00
Springboot RestTemplate设置超时时间的简单方法
2022-06-12 23:40:24
C#操作DataGridView设置单元格只读
2023-12-22 15:05:26