基于Avalonia實(shí)現(xiàn)自定義彈窗的示例詳解
對于使用avalonia的時(shí)候某些功能需要到一些提示,比如異?;蛘叱晒Χ夹枰獙τ脩暨M(jìn)行提示,所以需要單獨(dú)實(shí)現(xiàn)彈窗功能,并且可以自定義內(nèi)部組件,這一期將手動(dòng)實(shí)現(xiàn)一個(gè)簡單的小彈窗,并且很容易自定義
創(chuàng)建項(xiàng)目
實(shí)現(xiàn)我們需要?jiǎng)?chuàng)建一個(gè)avaloniaMVVM的項(xiàng)目模板

并且取名PopoverExample

然后一直默認(rèn)創(chuàng)建。
創(chuàng)建彈窗組件
在Views文件夾中創(chuàng)建一個(gè)組件,選擇Window模板,創(chuàng)建名稱Dialog

然后打開Dialog.axaml文件,修改相關(guān)代碼,
<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>標(biāo)題</TextBlock>
</Grid>
<Grid HorizontalAlignment="Right">
<Button Click="Close_OnClick" Name="Close">關(guān)閉</Button>
</Grid>
</Grid>
<Grid>
<TextBlock Name="Content"></TextBlock>
</Grid>
</StackPanel>
</Window>以下代碼是用于隱藏默認(rèn)的標(biāo)題欄的
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();
}
}
創(chuàng)建DialogManage類
創(chuàng)建DialogManage類,用于管理Dialog 創(chuàng)建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;
// 防止并發(fā)可自行修改
lock (_dialogBases)
{
if (_dialogBases.Remove(type, out var dialogBase))
{
try
{
dialogBase.Close();
}
catch
{
}
}
dialog = new DialogBase
{
Height = height,
Width = width,
WindowStartupLocation = WindowStartupLocation.Manual // 不設(shè)置的話無法修改窗口位置
};
if (timing > 0)
{
// 彈窗定時(shí)關(guān)閉
_ = Task.Run(async () =>
{
await Task.Delay(timing);
// 先刪除并且拿到刪除的value
if (_dialogBases.Remove(type, out var dialogBase))
{
// 操作組件需要使用ui線程
_ = Dispatcher.UIThread.InvokeAsync(() =>
{
try
{
// 關(guān)閉彈窗組件
dialogBase.Close();
}
// 可能已經(jīng)被關(guān)閉所以可能會(huì)出現(xiàn)異常
catch
{
}
});
}
});
}
// 添加到字典中
_dialogBases.TryAdd(type, dialog);
}
// 獲取當(dāng)前屏幕
var bounds = dialog.Screens.ScreenFromVisual(dialog).Bounds;
// 偏移
int skewing = 20;
// window的任務(wù)欄高度
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);
}
// 設(shè)置彈窗的位置
dialog.Position = new PixelPoint(x, y);
// 獲取內(nèi)容顯示的組件并且將內(nèi)容顯示上去
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
}
對于彈窗組件已經(jīng)完成,
基本使用彈窗
打開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修改相關(guān)代碼
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++, "彈窗內(nèi)容:" + i);
// 超過枚舉值重新賦值
if (i == 6)
{
i = 0;
}
}
}
執(zhí)行效果

到此這篇關(guān)于基于Avalonia實(shí)現(xiàn)自定義彈窗的示例詳解的文章就介紹到這了,更多相關(guān)Avalonia自定義彈窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用Socket實(shí)現(xiàn)本地多人聊天室
這篇文章主要為大家詳細(xì)介紹了C#使用Socket實(shí)現(xiàn)本地多人聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Windows下C#的GUI窗口程序中實(shí)現(xiàn)調(diào)用Google Map的實(shí)例
這篇文章主要介紹了Windows下C#的GUI窗口程序中實(shí)現(xiàn)調(diào)用Google Map的實(shí)例,如果只想調(diào)用瀏覽器打開網(wǎng)頁的話可以看文章最后的方法,需要的朋友可以參考下2016-04-04
C#多線程學(xué)習(xí)之(一)多線程的相關(guān)概念分析
這篇文章主要介紹了C#多線程學(xué)習(xí)之多線程的相關(guān)概念,涉及C#中多線程的相關(guān)概念與使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
C#實(shí)現(xiàn)為類和函數(shù)代碼自動(dòng)添加版權(quán)注釋信息的方法
這篇文章主要介紹了C#實(shí)現(xiàn)為類和函數(shù)代碼自動(dòng)添加版權(quán)注釋信息的方法,主要涉及安裝文件的修改及函數(shù)注釋模板的修改,需要的朋友可以參考下2014-09-09
詳解C#中三個(gè)關(guān)鍵字params,Ref,out
本文主要討論params關(guān)鍵字,ref關(guān)鍵字,out關(guān)鍵字。非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-05-05
C#關(guān)聯(lián)自定義文件類型到應(yīng)用程序并實(shí)現(xiàn)自動(dòng)導(dǎo)入功能
今天通過本文給大家分享C#關(guān)聯(lián)自定義文件類型到應(yīng)用程序并實(shí)現(xiàn)自動(dòng)導(dǎo)入功能,代碼中寫入了兩個(gè)注冊表,實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09

