对于使用avalonia的时候某些功能需要到一些提示,比如异常或者成功都需要对用户进行提示,所以需要单独实现弹窗功能,并且可以自定义内部组件,这一期将手动实现一个简单的小弹窗,并且很容易自定义

创建项目

实现我们需要创建一个avaloniaMVVM的项目模板

并且取名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类

创建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<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;
}
}
}

执行效果

来自token的分享

技术交流群:737776595

最新文章

  1. WINDOWS SERVER 2008 RD服务器搭建
  2. mysql中导入txt文件
  3. android开发------编写用户界面之线性布局(补充知识)
  4. HTML5地理位置概述和地理位置对象的详解
  5. KKCapture 高清录像软
  6. 20151211jquery ajax进阶代码备份
  7. POJ 2234 Matches Game 尼姆博弈
  8. 项目Alpha冲刺Day6
  9. tomcat设置端口号,访问指定ip就访问指定项目
  10. Python之shutil模块(复制移动文件)
  11. Java【第十篇】集合
  12. jdk1.8新特性 lambda表达式和Stream
  13. ES6/ES2015的一些特性的简单使
  14. Ext.js入门:Window对象与FormPanel(六)
  15. Netty接收到一个请求但是代码段执行了两次
  16. 实例Python处理XML文件的方法
  17. Nodejs学习笔记(三)—模块
  18. Windows执行命令与下载文件总结
  19. C#统计给定的文本中字符出现的次数,使用循环和递归两种方法
  20. linux进程间的网络通信

热门文章

  1. Django系列---开发二
  2. C/C++ 知海拾遗
  3. &lt;四&gt;构造函数初始化列表
  4. 【题解】CF991C Candies
  5. MindSpore Graph Learning
  6. RabbitMq发布确认
  7. 2022春每日一题:Day 10
  8. 有关二级指针char **p 的问题
  9. 图文详解在VMware Workstation 16 PRO虚拟机上安装Rocky 8.6 linux系统
  10. 树莓派蓝牙rfcomm协议通信