Avalonia学习(二十九)-仪表

news2024/11/19 7:29:28

Avalonia制作仪表盘,把控件给大家演示一下,Avalonia有三类自定义控件,分别是用户控件、模版控件、自主控件。前面已经很多用户控件了,这个是演示模版控件,另外一种不知道哪种情况下使用。

前端代码:

<Styles xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:GaugeAvalonia.Views;assembly=GaugeAvalonia"
    x:CompileBindings="False"
  >
  <Design.PreviewWith>
        <Border Padding="20">
            <!-- Add Controls for Previewer Here -->
        </Border>
    </Design.PreviewWith>

  <Style  Selector="local|ArcGauge">
    <Setter Property="Background" Value="#646464"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type local:ArcGauge}">
          <Border Margin="10">
            <Grid Width="{Binding RelativeSource={RelativeSource Self},Path=Height}">
              <Ellipse Fill="#FF3B3B3B"/>
              <Grid RenderTransformOrigin="0.5,0.5" Margin="2">
                <Grid.RenderTransform>
                  <TransformGroup>
                    <RotateTransform  Angle="{Binding Angle}"/>
                    </TransformGroup>
                </Grid.RenderTransform>
                <Ellipse Width="16" Height="14" Fill="Orange" VerticalAlignment="Top" >
                  <Ellipse.Effect>
                    <BlurEffect Radius="12"/>
                  </Ellipse.Effect>
                </Ellipse>
              </Grid>

              <Grid x:Name="bdGrid" Margin="12" UseLayoutRounding="True" ClipToBounds="True">
                <Ellipse>
                  <Ellipse.Fill>
                    <RadialGradientBrush>
                      <GradientStop Color="#4D000000"/>
                    </RadialGradientBrush>
                  </Ellipse.Fill>
                </Ellipse>
                <Grid>
                  <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition/>
                  </Grid.ColumnDefinitions>
                  <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="2*"/>
                    <RowDefinition/>
                  </Grid.RowDefinitions>
                  <Ellipse Stroke="#464646" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/>
                  <Ellipse Stroke="#959595" Margin="4" StrokeThickness="6" Grid.Column="1" Grid.Row="1"/>
                  <Ellipse Stroke="#464646" Margin="14" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/>
                </Grid>
                <Grid>
                  <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                  </Grid.RowDefinitions>
                  <Path  Data="M5,0 5,0 10,120 0,120z" Fill="#0FA9CE" Stretch="Uniform" Margin="0 30 0 0"  HorizontalAlignment="Center">
                    <Path.RenderTransform>
                      <TransformGroup>
                        <RotateTransform    Angle="{Binding Path=Angle, Mode=TwoWay}"/>
                      </TransformGroup>
                    </Path.RenderTransform>
                  </Path>
                </Grid>
                <Ellipse Width="28" Height="28" Fill="Black">
                  <Ellipse.Effect>
                  <!--<DropShadowEffect Color="#0FA9CE" ShadowDepth="0" Direction="0" BlurRadius="16"/>-->
                  </Ellipse.Effect>
                </Ellipse>
                <Border VerticalAlignment="Bottom" BorderBrush="#10ABD1" BorderThickness="2" Margin="0 0 0 12" Background="Black" Padding="8 2" HorizontalAlignment="Center">
                  <TextBlock Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent}}" FontSize="16" Width="30" TextAlignment="Center" Foreground="White" FontWeight="Bold"/>
                </Border>
              </Grid>
            </Grid>
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

</Styles>

后台代码:

using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using System.Collections.Generic;
using System.ComponentModel;
using Avalonia.Controls.Templates;
using Avalonia.Controls.Primitives;
using System.Linq;

namespace GaugeAvalonia.Views
{
    public class ArcGauge: TemplatedControl
    {
      
        Grid bdGrid;

        static ArcGauge()
        {
           
           // DefaultStyleKeyProperty.OverrideMetadata(typeof(ArcGauge), new FrameworkPropertyMetadata(typeof(ArcGauge)));
        }
        
        public ArcGauge()
        {
            this.Loaded += ArcGauge_Loaded;
            //Width = 200;
            //Height = 200;
            SetCurrentValue(ValueProperty, 0d);
            SetCurrentValue(MinValueProperty, 0d);
            SetCurrentValue(MaxValueProperty, 100d);
        }

        private void ArcGauge_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            InitTick();
        }









        public override void Render(DrawingContext context)
        {
           
            base.Render(context);
          
            bdGrid = (Grid)this.GetTemplateChildren().Where(x => x.Name == "bdGrid").First();
            Refresh();
        

        }
        private void InitTick()
        {
            // 画大刻度
            for (int i = 0; i < 9; i++)
            {
                Line line = new Line();
                line.StartPoint = new Point(0, 0);
                line.EndPoint=new Point(0, 12);
                line.HorizontalAlignment= Avalonia.Layout.HorizontalAlignment
                    .Center;
             
                line.Stroke = Brushes.White;
                line.StrokeThickness = 2;
                line.RenderTransformOrigin = RelativePoint.Center;
              
                line.RenderTransform = new RotateTransform() { Angle = -140 + i * 35 };
                 bdGrid.Children.Add(line);
                DrawText();
            }            // 画小刻度
            for (int i = 0; i < 8; i++)
            {
                var start = -140 + 35 * i + 3.5;
                for (int j = 0; j < 9; j++)
                {
                    Line line = new Line();
                    line.StartPoint = new Point(0, 0);
                    line.EndPoint = new Point(0, 6);
                   
                    line.Stroke = Brushes.White;
                    line.StrokeThickness = 1;
                    line.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment .Center;
                    line.RenderTransformOrigin = RelativePoint.Center;
                    line.RenderTransform = new RotateTransform() { Angle = start + j * 3.5 };
                    bdGrid.Children.Add(line);
                }
            }
        }
        List<TextBlock> textLabels = new List<TextBlock>();
        private void DrawText()
        {
            foreach (var item in textLabels)
            {
                  bdGrid.Children.Remove(item);
            }
            textLabels.Clear();
            var per = MaxValue / 8;
            for (int i = 0; i < 9; i++)
            {
                TextBlock textBlock = new TextBlock();
                textBlock.Text = $"{MinValue + (per * i)}";
                textBlock.HorizontalAlignment =  Avalonia.Layout.HorizontalAlignment.Center;
                textBlock.RenderTransformOrigin = RelativePoint.Center;
                textBlock.RenderTransform = new RotateTransform() { Angle = -140 + i * 35 };
                textBlock.Margin = new Thickness(12);
                textBlock.Foreground = Brushes.White;
                bdGrid.Children.Add(textBlock);
                textLabels.Add(textBlock);
            }
        }


       
        //public static readonly StyledProperty<IBrush> BackgroundProperty =
        //   AvaloniaProperty.Register<ArcGauge, IBrush>(nameof(Value));
        //public IBrush Background
        //{
        //    get
        //    {
        //        return GetValue(BackgroundProperty);
        //    }
        //    set
        //    {
        //        SetValue(BackgroundProperty, value);
        //    }
        //}

        //public static readonly StyledProperty<IBrush> ForegroundProperty =
        // AvaloniaProperty.Register<ArcGauge, IBrush>(nameof(Value));
        //public IBrush Foreground
        //{
        //    get
        //    {
        //        return GetValue(ForegroundProperty);
        //    }
        //    set
        //    {
        //        SetValue(ForegroundProperty, value);
        //    }
       // }



        [Category("值设定")]
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        public static readonly StyledProperty<double> ValueProperty =
            AvaloniaProperty.Register<ArcGauge, double>(nameof(Value), coerce: OnValueChanged);

        private static double OnValueChanged(AvaloniaObject @object, double arg2)
        {
            ArcGauge gauge= @object  as ArcGauge;
            gauge.Refresh();
            return arg2;
        }

        [Category("值设定")]
        public double MinValue
        {
            get { return (double)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }
        public static readonly StyledProperty<double> MinValueProperty =
            AvaloniaProperty.Register<ArcGauge, double>(nameof(MinValue), coerce: OnValueChanged);
        public double MaxValue
        {
            get { return (double)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }
        public static readonly StyledProperty<double> MaxValueProperty =
           AvaloniaProperty.Register<ArcGauge, double>(nameof(MaxValue), coerce: OnValueChanged);


        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }
        public static readonly StyledProperty<double> AngleProperty =
         AvaloniaProperty.Register<ArcGauge, double>(nameof(Angle));


      
        private void Refresh()
        {

           
            if (Value > MaxValue)
            {
                Angle = 140;

            }
            else if (Value < MinValue)
            {
                Angle = -140;

            }
            else
            {
                var range = MaxValue - MinValue;
                var process = Value / range;
                var tAngle = process * 280 - 140;
                Angle = tAngle;

            }

            
        }
    }
}

运行效果:

目前Avalonia的内容也不知道该演示什么了。估计博文会更新慢了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1488101.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常用的java反编译工具介绍

在软件开发和逆向工程领域&#xff0c;反编译工具是一个重要的工具&#xff0c;它们可以帮助开发者理解、分析和修改编译后的Java字节码文件&#xff08;.class文件&#xff09;。这些工具通常用于以下几个目的&#xff1a; 1. 调试&#xff1a;帮助开发者理解字节码的…

CloudCanal x Hive 构建高效的实时数仓

简述 CloudCanal 最近对于全周期数据流动进行了初步探索&#xff0c;打通了Hive 目标端的实时同步&#xff0c;为实时数仓的构建提供了支持&#xff0c;这篇文章简要做下分享。 基于临时表的增量合并方式基于 HDFS 文件写入方式临时表统一 Schema任务级的临时表 基于临时表的…

华为手环 8:返校季新宠,助力高效学习与健康生活

随着春节假期的结束&#xff0c;学生们也纷纷踏上了返校的旅途。新的学期&#xff0c;新的气象&#xff0c;让华为手环8为你的带来全新的智能生活体验。它不仅仅是一款风格多变的时尚手环&#xff0c;还拥有了智能消息提醒、100多种运动模式和睡眠监测等强大功能&#xff0c;让…

Linux 实现打印彩色进度条

文章目录 预备知识一、理解回车换行二、认识行缓冲1、代码一、二&#xff08;回车换行理解&#xff09;2、代码三、四&#xff08;sleep函数和ffush函数理解&#xff09; 三、简单倒计时1. 倒计时代码2、效果展示 四、进度条1、效果展示2、进度条代码makefileProcessBar.hProce…

【数据结构和算法初阶(C语言)】双向循环带头链表的增删查改详解(天才设计的链表结构,应用简单逆天!!!!!)

目录 ​编辑​编辑 1.双向链表的定义&#xff1a;前赴后继 2.带头链表的定义-----哨兵位 3.增删查改 3.1创建新节点函数----方便后续增加节点调用 3.2创建哨兵位----创建头结点 3.3增加节点&#xff0c;尾部插入数据 3.4尾删除 3.5查找函数----遍历对比&#xff…

程序人生:当看到男友学测试拿高薪后,我突然悟了......

Hello&#xff0c;大家好&#xff0c;我是小雨 认识软件测试是因为我男朋友&#xff0c;他在华测教育培训软测后出去就业非常不错&#xff0c;所以我也萌生了转行的想法&#xff0c;当时我的想法是&#xff0c;他都能学会&#xff0c;那我肯定没问题&#xff0c;所以在他的介绍…

【编程系列----编译文件解析】Program size: Code, RO-data , RW-data, ZI-data

1.先给个 axf 文件 转编译bin文件的代码 2.解析下编译文件MAP 先给个编译提示 Code 是代码占用的空间 RO-data是 Read Only 只读常量的大小&#xff0c;如const型 RW-data是&#xff08;Read Write&#xff09; RW是可读可写变量&#xff0c;就是初始化时候就已经赋值了的&a…

图书管理系统的设计与实现

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1 课题…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:组件内容模糊)

为当前组件添加内容模糊效果。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 foregroundBlurStyle foregroundBlurStyle(value: BlurStyle, options?: ForegroundBlurStyleOptions) 为当前组件提供…

Linux 学习笔记(12)

十二、 系统服务 1 、系统服务分类&#xff0c;根据其使用的方法来分&#xff0c;可以被分为三类 a、由 init 控制的服务&#xff1a;基本都是系统级别的服务&#xff0c;运行级别这一章讲的就是这一类的服务 b、由 System V 启动脚本启动的服务&#xff1a;和我们打交道最多…

政务浏览器——打通信创闭环最后一公里

当前&#xff0c;信创建设工作主要集中在芯片、操作系统、数据库以及pc整机&#xff0c;这些领域基本可用&#xff0c;或者达到了市场主流水平。但是&#xff0c;政务办事场景下的信创落地仍然困难重重&#xff0c;很多地方不得不装双系统或买两台设备来来平衡日常业务和信创考…

关于企业数字化转型:再认识、再思考、再出发

近年来&#xff0c;随着国家数字化政策不断出台、新兴技术不断进步、企业内生需求持续释放&#xff0c;数字化转型逐步成为企业实现高质量发展的必由之路&#xff0c;成为企业实现可持续发展乃至弯道超车的重要途径。本文重点分析当下阻碍企业数字化转型的难点&#xff0c;提出…

[项目设计] 从零实现的高并发内存池(二)

&#x1f308; 博客个人主页&#xff1a;Chris在Coding &#x1f3a5; 本文所属专栏&#xff1a;[高并发内存池] ❤️ 前置学习专栏&#xff1a;[Linux学习] ⏰ 我们仍在旅途 ​ 目录 2.高并发内存池整体架构 3.ThreadCache实现 3.1 ThreadCache整体架构…

【JSON2WEB】08 Amis的事件和校验

CRUD操作中&#xff0c;新增、编辑、删除数据后要同步刷新列表&#xff0c;这个可以用Amis的事件来实现。 1 新增数据后刷新列表 Step 1 找到【新增数据】弹窗的【提交】按钮 Step 2 添加鼠标点击事件 这里的 组件ID&#xff1a;u:13d67a44214e 为表格2的组件ID&#xff0c; …

2024常用开源测试开发工具!

今天为大家奉献一篇测试开发工具集锦干货。在本篇文章中&#xff0c;将给大家推荐几款日常工作中经常用到的测试开发工具神器&#xff0c;涵盖了自动化测试、性能压测、流量复制、混沌测试、造数据等。 1、AutoMeter-API 自动化测试平台 AutoMeter 是一款针对分布式服务&…

MySQL 8.0.35 企业版安装和启用TDE插件keyring_encrypted_file

本文主要记录MySQL企业版TDE插件keyring_encrypted_file的安装和使用。 TDE说明 TDE( Transparent Data Encryption,透明数据加密) 指的是无需修改应用就可以实现数据的加解密&#xff0c;在数据写磁盘的时候加密&#xff0c;读的时候自动解密。加密后其他人即使能够访问数据库…

Vue-03

Vue指令 v-bind 作用&#xff1a;动态设置html的标签属性&#xff08;src url title…&#xff09; 语法&#xff1a;v-bind:属性名"表达式" 举例代码如下&#xff1a; 实现效果如下&#xff1a; 案例&#xff1a;图片切换 实现代码如下&#xff1a; 实现的效果…

#WEB前端(CCS常用属性,补充span、div)

1.实验&#xff1a; 复合元素、行内元素、块内元素、行内块元素 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; span为行内元素&#xff1a;不可设置宽高&#xff0c;实际占用控件决定分布空间。 div为块内元素&#xff1a;占满整行&#xff0c;可以设置宽高 img为行内块元…

新手想玩硬件,买单片机还是树莓派好?

新手想玩硬件&#xff0c;买单片机还是树莓派好&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#x…

单链表的排序-力扣算法题

文章目录 概要例题解题思路&#xff1a;1、递归分割2、递归排序实际的含义3、递归回溯与合并 case解析&#xff1a;1、初始链表&#xff1a;2、第一轮分割&#xff1a;3、继续分割&#xff1a;有序子链表合并&#xff1a;最终合并&#xff1a;结果&#xff1a; 代码实现总结&am…