avalonia自定义弹窗

简介: avalonia自定义弹窗

对于使用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的分享

目录
相关文章
|
7月前
|
移动开发 小程序 API
uniapp中uview组件库丰富的ActionSheet 操作菜单使用方法
uniapp中uview组件库丰富的ActionSheet 操作菜单使用方法
412 1
Avalonia使用默认弹窗
Avalonia使用默认弹窗
220 0
Avalonia使用默认弹窗
|
C++ Windows
Qt-QML-Popup,弹层界面编写
随着接触Qt的时间的增加,也逐渐的发现了Qt 的一些不人信话的一些地方,不由的想起一句话,也不知道是在哪里看到的了“一切变成语言都是垃圾,就C++还可以凑合用”大致意思是这样。最近项目的祝界面框架都基本写完了,那自我感觉良好,感觉自己QML的不得了了,全部用的都是自己YY出来的空间,今天小伙伴在同伴代码后,用到了我的模块,给我说了一个BUG,
541 0
Qt-QML-Popup,弹层界面编写
|
JavaScript
原生js写的一个下拉框功能插件
用原生js写的一个下拉框功能插件
209 0
Qml-Dialog不能隐藏标题栏和按钮自定义
在项目中,需要弹出一个对话框来完成用户输入的功能,为了考虑界面的同一,这里需要将原生自带的标题栏隐藏掉,换成自己写的
582 0
|
开发工具 C语言
Qt编写自定义控件9-导航按钮控件
一、前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有的CSS2属性,配合QPainter这个无敌大法工具,没有什么不能绘制的。
1278 0
|
C#
WPF 自定义模板 Button闪亮效果
原文:WPF 自定义模板 Button闪亮效果 Button的选中Effect,我们看下下面的效果:   让我们再放大一点: 怎么设置上面样式呢?直接设置Button的Effect,有点问题,因为Effect不是四周环绕的。
596 0
|
JavaScript 前端开发 搜索推荐