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

并且取名PopoverExample

然后一直默認創(chuàng)建。
創(chuàng)建彈窗組件
在Views文件夾中創(chuàng)建一個組件,選擇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>標題</TextBlock>
</Grid>
<Grid HorizontalAlignment="Right">
<Button Click="Close_OnClick" Name="Close">關(guān)閉</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();
}
}
創(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)
{
// 彈窗定時關(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)閉所以可能會出現(xiàn)異常
catch
{
}
});
}
});
}
// 添加到字典中
_dialogBases.TryAdd(type, dialog);
}
// 獲取當前屏幕
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實現(xiàn)自定義彈窗的示例詳解的文章就介紹到這了,更多相關(guān)Avalonia自定義彈窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c# OpenCvSharp實現(xiàn)常見檢測(斑點檢測,輪廓檢測,邊緣檢測)
這篇文章主要為大家詳細介紹了c#如何使用OpenCvSharp實現(xiàn)常見檢測(斑點檢測,輪廓檢測,邊緣檢測),文中的示例代碼講解詳細,需要的小伙伴可以參考下2023-12-12
C#判斷指定驅(qū)動器是否已經(jīng)準備就緒的方法
這篇文章主要介紹了C#判斷指定驅(qū)動器是否已經(jīng)準備就緒的方法,涉及C#針對硬件IO操作的技巧,需要的朋友可以參考下2015-04-04

