C#为复杂属性提供下拉式编辑框和弹出式编辑框

news2024/11/18 9:35:55

一.为属性提供编辑类

  弹出式和下拉式是如何实现的呢,这需要为属性提供一个专门的编辑类。.Net为我们提供了一个System.Drawing.Design.UITypeEditor类,它是所有编辑类的基类,从他继承出了诸如ColorEditor、FontEditor的类,因此我们可以在属性框中编辑颜色和字体。定义了这样的类,我们也可以为自己的属性实现弹出式和下拉式编辑方式。

  先看一下MSDN中对UITypeEditor的介绍:提供可用于设计值编辑器的基类,这些编辑器可提供用户界面 (UI),用来表示和编辑所支持的数据类型的对象值。

 UITypeEditor 类提供一种基类,可以从该基类派生和进行扩展,以便为设计时环境实现自定义类型编辑器。通常,您的自定义类型编辑器与 PropertyGrid 控件进行交互。在文本框值编辑器不足以有效地选择某些类型的值的情况下,自定义类型编辑器非常有用。

 

继承者说明:若要实现自定义设计时 UI 类型编辑器,必须执行下列步骤

using System;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

public class MyCustomEditor : UITypeEditor
{
    // 1. 指定编辑器样式:Modal 表示使用弹出对话框
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    // 2. 处理属性值的编辑
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    // 3. 支持绘制值的表示形式
    public override bool GetPaintValueSupported(ITypeDescriptorContext context)
    // 4. 绘制值的表示形式
    public override void PaintValue(PaintValueEventArgs e)
    //5 .设置默认值或执行其他初始化逻辑
    public MyCustomEditor() 

}

1. 定义一个从 UITypeEditor 派生的类

  • 目的:创建一个新的编辑器类,用于自定义编辑属性值的方式。
  • 步骤:从 UITypeEditor 基类继承,通常会定义一个新类,例如 MyCustomEditor

2. 重写 EditValue 方法

  • 目的:处理用户界面和用户输入操作,以及对属性值的分配。

  • 步骤:在 EditValue 方法中,你将实现弹出对话框或其他用户界面,允许用户输入新值,然后将这个值应用到目标属性上。例如:

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
     { 
     // 实现自定义编辑逻辑 
     // 例如,显示对话框让用户输入新值 
     // 更新并返回新的值
     }

3. 重写 GetEditStyle 方法

  • 目的:通知“属性”窗口该编辑器使用的编辑器样式。

  • 步骤GetEditStyle 方法返回一个 UITypeEditorEditStyle 枚举值,指示编辑器的类型(如 UITypeEditorEditStyle.ModalUITypeEditorEditStyle.DropDownUITypeEditorEditStyle.None)。例如:

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
       return UITypeEditorEditStyle.Modal; // 或其他适当的样式
    }

4. 支持值的表示形式(可选)

  • 目的:在属性窗口中显示值的可视化表示形式。

  • 步骤:实现这部分功能时,你需要:

    • 重写 GetPaintValueSupported 方法:指示编辑器是否支持显示值的表示形式。返回 true 表示支持,false 表示不支持。

      public override bool GetPaintValueSupported(ITypeDescriptorContext context) 
      { 
        return true; // 表示支持绘制值的表示形式 
      }
    • 重写 PaintValue 方法:实现如何绘制值的表示形式。例如,你可以绘制一个图标或图像,代表属性的当前值。

      public override void PaintValue(PaintValueEventArgs e) 
      { 
      // 实现绘制逻辑 
      // 例如绘制一个矩形来显示颜色值 
      e.Graphics.FillRectangle(new SolidBrush(Color.Red),e.Bounds); 
      }

5. 初始化行为(可选)

  • 目的:如果编辑器需要特定的初始化行为,你可以重写 UITypeEditor 的构造函数。

  • 步骤:在自定义构造函数中,你可以设置默认值或执行其他初始化逻辑。

    public MyCustomEditor() 
    { // 实现初始化逻辑 }

这些步骤为你提供了创建和自定义 UITypeEditor 的基础,以便在设计时属性窗口中更好地管理和展示属性值。

 

 接下来我们来实现下拉式编辑方式,接下来举一个具体的例子来说明:

  首先假如我们有一个控件类MyControl:

public class MyControl : System.Windows.Forms.UserControl
{
        private double _angle;

        [BrowsableAttribute(true)]
        public double Angle
        {
            get
            { return _angle; }
            set
            { _angle = value; }
        }

        public MyControl()
        {
            this._angle = 90;
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            e.Graphics.DrawString("The Angle is " + _angle, this.Font, Brushes.Red,0,0);
        }
}

其中有个属性Angle,我们要为其提供下拉式和弹出式编辑方式,当然了,一般都是较为复杂的属性才需要,这里只是为了举例说明。

二.下拉式编辑方式 

  我们为其定义一个派生的编辑类AngleEditor,EditValue和GetEditStyle两个函数,这是必须要重写的:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class AngleEditor : System.Drawing.Design.UITypeEditor
{
        public AngleEditor()
        {
        }
        //下拉式还是弹出式
        public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }

        // 为属性显示UI编辑框
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            //值类型不为double,直接返回value
            if (value.GetType() != typeof(double))
                return value;

            //值为double,显示下拉式或弹出编辑框
            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (edSvc != null)
            {
                // 显示编辑框并初始化编辑框的值
                AngleControl angleControl = new AngleControl((double)value);
                edSvc.DropDownControl(angleControl);
                // 返回编辑框中编辑的值.
                if (value.GetType() == typeof(double))
                    return angleControl.angle;
            }
            return value;
        }

        //下面两个函数是为了在PropertyGrid中显示一个辅助的效果
        //可以不用重写
        public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
        {
            int normalX = (e.Bounds.Width / 2);
            int normalY = (e.Bounds.Height / 2);

            e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
            e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);
            e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);

            double radians = ((double)e.Value * Math.PI) / (double)180;
            e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,
                e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),
                e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));
        }

        public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return true;
        }
    }

    // 这里是我们要显示出来的编辑器,把它作为一个内置类,本质上他就是一个显示form
    //从UserControl继承,要在上面EditValue函数中使用的
    internal class AngleControl : System.Windows.Forms.UserControl
    {
        public double angle; //编辑的角度
        private float x;     //鼠标位置
        private float y;

        public AngleControl(double initial_angle)
        {
            this.angle = initial_angle;
        }
        //显现时,显示属性的当前值
        protected override void OnLoad(EventArgs e)
        {
            int originX = (this.Width / 2);
            int originY = (this.Height / 2);
            this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);
            this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);
            base.OnLoad(e);
        }

        //绘制控件,用来显示编辑角度
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            int originX = (this.Width / 2);
            int originY = (this.Height / 2);

            e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);
            e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);
            e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);
        }
        //鼠标移动时设置角度
        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int originX = (this.Width / 2);
                int originY = (this.Height / 2);
                double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));
                double h = e.Y - originY;
                this.angle = Math.Asin(h / len);
                if ((e.X >= originX && e.Y >= originY))
                {
                    this.x = (float)(50 * Math.Cos(this.angle) + originX);
                    this.y = (float)(50 * Math.Sin(this.angle) + originY);
                    this.angle = this.angle * 180 / Math.PI;
                }
                else if (e.X < originX && e.Y > originY)
                {
                    this.x = (float)(originX - 50 * Math.Cos(this.angle));
                    this.y = (float)(50 * Math.Sin(this.angle) + originY);
                    this.angle = 180 - this.angle * 180 / Math.PI;
                }
                else if (e.X < originX && e.Y < originY)
                {
                    this.x = (float)(originX - 50 * Math.Cos(this.angle));
                    this.y = (float)(originY + 50 * Math.Sin(this.angle));
                    this.angle = 180 - this.angle * 180 / Math.PI;
                }
                else if (e.X >= originX && e.Y <= originY)
                {
                    this.x = (float)(originX + 50 * Math.Cos(this.angle));
                    this.y = (float)(originY + 50 * Math.Sin(this.angle));
                    this.angle = 360 + this.angle * 180 / Math.PI;
                }
                this.Invalidate();
            }          
        }      
}

这里有两个类,一个是AngleEditor,他就是我们要用于到属性特性中的编辑类,一个是AngleControl,他是辅助AngleEditor来编辑属性的,也就是说,他就是一个form,当我们编辑属性时,他会显现出来,供我们编辑属性值,可以是textBox,图形,表格,各种方式,只需要最后他返回编辑好的属性值给AngleEditor类。在AngleEditor类中的EditValue函数中,我们会调用AngleControl类,并接受它返回的值。

  设计好编辑类后,把它应用到MyControl类中的Angle属性中,在Angle属性中增加特性[EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))],相当于告诉PropertyGrid我们要用AngleEditor来编辑这个属性。  

[BrowsableAttribute(true)]
[EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))]
public double Angle
{
   get
   { return _angle; }
   set
   { _angle = value; }
}

效果如下:

三.弹出式编辑方式

  实现了下拉式,我们来实现弹出式,弹出式和下拉式非常的相像,现在要弹出一个编辑框,因此我们的AngleControl类不能从UserControl继承,而从From继承,让他成为一个对话框,在AngleEditor的EditValue函数中,弹出他并接受返回值,如下:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class AngleEditor : System.Drawing.Design.UITypeEditor
{
        public AngleEditor()
        {
        }
        //下拉式还是弹出式.
        //这里是第一个修改的地方,改为了弹出式。
        public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;//弹出式
        }

        // 为属性显示UI编辑框
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            //值类型不为double,直接返回value
            if (value.GetType() != typeof(double))
                return value;

            //值为double,显示下拉式或弹出编辑框
            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (edSvc != null)
            {
                // 显示编辑框并初始化编辑框的值,
                //这里是第二个修改点,改为showDialog
                AngleControl2 angleControl = new AngleControl2((double)value);
                edSvc.ShowDialog(angleControl);                
               // 返回编辑框中编辑的值.
                if (value.GetType() == typeof(double))
                    return angleControl.angle;
            }
            return value;
        }

        //下面两个函数是为了在PropertyGrid中显示一个辅助的效果
        //可以不用重写
        public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
        {
            int normalX = (e.Bounds.Width / 2);
            int normalY = (e.Bounds.Height / 2);

            e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
            e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);
            e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);

            double radians = ((double)e.Value * Math.PI) / (double)180;
            e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,
                e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),
                e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));
        }

        public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return true;
        }
    }

    // 这里是我们要显示出来的编辑器,把它作为一个内置类
    //从UserControl继承,要在上面EditValue函数中使用的
    //这里是第三个修改点,让他显示为对话框,所以继承了form类
    internal class AngleControl2 : System.Windows.Forms.Form
    {
        public double angle; //编辑的角度
        private float x;     //鼠标位置
        private float y;

        public AngleControl(double initial_angle)
        {
            this.angle = initial_angle;
        }
        //显现时,显示属性的当前值
        protected override void OnLoad(EventArgs e)
        {
            int originX = (this.Width / 2);
            int originY = (this.Height / 2);
            this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);
            this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);
            base.OnLoad(e);
        }

        //绘制控件,用来显示编辑角度
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            int originX = (this.Width / 2);
            int originY = (this.Height / 2);

            e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);
            e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);

            e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);
        }
        //鼠标移动时设置角度
        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int originX = (this.Width / 2);
                int originY = (this.Height / 2);
                double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));
                double h = e.Y - originY;
                this.angle = Math.Asin(h / len);
                if ((e.X >= originX && e.Y >= originY))
                {
                    this.x = (float)(50 * Math.Cos(this.angle) + originX);
                    this.y = (float)(50 * Math.Sin(this.angle) + originY);
                    this.angle = this.angle * 180 / Math.PI;
                }
                else if (e.X < originX && e.Y > originY)
                {
                    this.x = (float)(originX - 50 * Math.Cos(this.angle));
                    this.y = (float)(50 * Math.Sin(this.angle) + originY);
                    this.angle = 180 - this.angle * 180 / Math.PI;
                }
                else if (e.X < originX && e.Y < originY)
                {
                    this.x = (float)(originX - 50 * Math.Cos(this.angle));
                    this.y = (float)(originY + 50 * Math.Sin(this.angle));
                    this.angle = 180 - this.angle * 180 / Math.PI;
                }
                else if (e.X >= originX && e.Y <= originY)
                {
                    this.x = (float)(originX + 50 * Math.Cos(this.angle));
                    this.y = (float)(originY + 50 * Math.Sin(this.angle));
                    this.angle = 360 + this.angle * 180 / Math.PI;
                }
                this.Invalidate();
            }
          
        }
      
}

 

可以看到,只修改了三个地方:

1.AngleEditor类中GetEditStyle函数返回Modal,表明是以弹出式编辑。

2.AngleEditor类中EditValue函数中调用编辑控件的方式:

      AngleControl2 angleControl = new AngleControl2((double)value);
      edSvc.ShowDialog(angleControl);    

3.AngleControl2从Form继承,让他显示为对话框,这里为了区别上面的AngleControl类,将其改成了AngleControl2。

效果如下:

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

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

相关文章

信刻光盘摆渡系统安全合规实现跨网数据单向导入/导出

在当今信息化、数字化时代&#xff0c;各种数据传输和储存技术发展迅速&#xff0c;各安全领域行业对跨网数据交互需求日益迫切&#xff0c;数据传输的安全可靠性对于整个过程的重要性不可忽视。应如何解决网络安全与效率之间的矛盾&#xff0c;如何安全合规地实现跨网数据单向…

Spring Cloud Gateway 之动态路由

前言 熟悉 Spring Cloud Gateway 的人都知道 Gateway 提供了鉴权、路由等功能&#xff0c;本篇我们重点分析的是 Gateway 的动态路由功能。 Gateway Actuator API 方法源码解析 Spring Cloud Gateway 的 Actuator 端点允许监视 Spring Cloud Gateway 应用程序并与之交互&…

k8s学习(三十八) 使用OpenTelemetry+jaeger实现链路追踪

文章目录 前言一、安装jaeger二、安装cert-manager三、安装OpenTelemetry Operator四、配置 OpenTelemetry Collector五、配置 Instrumentation六、编写java示例程序并测试调用链跟踪 前言 OpenTelemetry 可以用于从应用程序收集数据。它是一组工具、API 和 SDK 集合&#xff…

《黑神话:悟空》Steam全球评价出炉:18个语言区好评率超90%

《黑神话&#xff1a;悟空》Steam在线人数已经不断打破纪录&#xff0c;连续三天刷榜&#xff0c;目前最高成绩超过241万。这个成绩也稳坐总榜第二&#xff0c;同时也是单机游戏的历史第一。 除了游玩人数之外&#xff0c;该作的评价口碑也非常出色&#xff0c;根据媒体汇总的数…

Flutter->`Flutter` 通过`ffi`调用`Rust`编译生成的产物.so文件(Android)和.a文件(iOS)接口方法

flutter_rust_ffi Flutter 通过ffi调用Rust编译生成的产物.so文件(Android)和.a文件(iOS)接口方法; 拾用本文您将获取以下技能: Rust编译.so文件的能力;Rust编译.a文件的能力;Flutter调用.so文件的能力;Flutter调用.a文件的能力; 附加Buff: Flutter环境安装指南;Rust环境安…

游戏行业如此竞争激烈,个人开发者是否仍存机会?

在当今这个数字化时代&#xff0c;游戏行业以其庞大的市场规模、高速的增长速度以及无限的创意空间&#xff0c;吸引了无数开发者投身其中。然而&#xff0c;随着技术的进步、资本的涌入以及大型游戏公司的强势扩张&#xff0c;游戏行业的竞争日益激烈&#xff0c;似乎形成了一…

选择合适系统

选择合适系统 原厂SDK系统 硬件兼容性 ⭐⭐⭐⭐⭐软件功能完善度 ⭐⭐⭐⭐⭐开发使用难度 ⭐⭐⭐⭐⭐烧写工具 全志自家烧录器。 TinaSDK-4.0 TF卡系统镜像 tina_v851se-tinyvision_uart0.img 默认TinaSDK编译出来 支持ADB 和默认SDK兼容性最好 tina-4.0_cameratest_ti…

使用知识图谱,大幅提升RAG准确性

大家好&#xff0c;图形检索—增强生成&#xff08;GraphRAG&#xff09;的发展势头日益强劲&#xff0c;已成为传统向量搜索检索方法的有力补充。这种方法利用图数据库的结构化特性&#xff0c;将数据组织为节点和关系&#xff0c;从而增强了检索信息的深度和上下文关联性。 知…

Stablediffusion有哪几种模型,小白入门必看!

前言 在Stable Diffusion中&#xff0c;模型有好几种&#xff0c;不同插件有不同的模型&#xff0c;分别作用于不同的功能。 今天卧龙君就带着大家一起来了解一下。 大模型&#xff1a;Stable Diffusion StableDiffusion大模型&#xff0c;可以理解为绘画风格集合&#xff…

16:【stm32】I2C的使用一:I2C片上外设的使用

I2C 1、片上外设1.1&#xff1a;寄存器与内部结构 2、通过I2C向外发送数据2.1&#xff1a;I2C的初始化2.1.1&#xff1a;初始化SCL和SDA2.1.2&#xff1a;使能时钟PCLK1&#xff08;APB1&#xff09;2.1.3&#xff1a;配置I2C1的参数 2.2&#xff1a;发送数据2.2.1&#xff1a;…

P2P 文件共享:现代网络中的高效文件传输

在互联网的世界中&#xff0c;不同应用程序的数据传输方法各异。P2P文件共享&#xff08;Peer-to-Peer File Sharing&#xff09; 作为一种高效的文件传输方式&#xff0c;使得用户可以在没有中央服务器的情况下直接进行文件交换。本文将详细介绍P2P文件共享的基本原理、优势及…

【通俗理解】CNN复杂度——卷积神经网络的计算成本解析

【通俗理解】CNN复杂度——卷积神经网络的计算成本解析 关键词提炼 #CNN复杂度 #卷积神经网络 #计算成本 #输入数据尺寸 #卷积核大小 #卷积核数量 #复杂度公式 第一节&#xff1a;CNN复杂度的类比与核心概念【尽可能通俗】 1.1 CNN复杂度的类比 CNN的复杂度就像是烹饪一道大…

引擎切换pdf识别简历分析

文章目录 1.EasyCode生成interview_history的crud1.在模板设置中手动指定逻辑删除的值2.生成代码&#xff0c;进行测试 2.PDF识别关键字1.引入依赖2.代码概览3.PDFUtil.java4.keyword1.EndType.java2.FlagIndex.java3.WordType.java4.KeyWordUtil.java 3.策略模式实现引擎切换&…

QT-window记事本

QT-window记事本 一、演示效果二、核心代码三、下载连接 一、演示效果 二、核心代码 #include <QMessageBox> #include <QFileDialog> #include <QDebug> #include <QProcess> #include <QDesktopServices> #include <QDateTime> #includ…

孙宇晨:区块链领域的坚韧领航者,以智慧铸就行业基石

​ 在区块链领域&#xff0c;孙宇晨以其卓越的智慧与不懈的韧性&#xff0c;成为行业内备受瞩目的领军人物。从创立波场 TRON 到引领去中心化的变革&#xff0c;孙宇晨始终以坚定的信念和独特的战略眼光推动着区块链技术的发展。 孙宇晨的成功不仅仅是因为他对技术的深入…

叉车驾驶员状态监控系统,司机身份安全识别,强化监管能力建设!

人脸识别技术作为人工智能领域的一个重要分支&#xff0c;已经广泛应用于安全识别、个人化推荐、社交网络等多个领域。其基于计算机视觉、图像处理、人脸检测、特征提取和人脸识别等先进技术&#xff0c;能够实现对人脸图像的精准分析和识别。在叉车驾驶场景中&#xff0c;AI人…

windows mfc webview2 接收html信息

webview2导入到mfc参考&#xff1a; windows vs2022 MFC使用webview2嵌入网页-CSDN博客 webview2与js交互参考&#xff1a;WebView2教程(基于C)【四】JS与C互访&#xff08;上&#xff09;_window.chrome.webview.postmessage-CSDN博客 一、JS端发送和接收 JS中&#xff0c;…

12代装win7影响性能吗?12代酷睿装win7关闭小核提高性能方法

12代酷睿装win7影响性能吗&#xff1f;12代酷睿装win7在性能上有点损耗&#xff0c;可以关闭小核提高性能。有些小朋友不知道怎么关闭上核来提高性能&#xff0c;下面电脑系统城小编就教大家12代酷睿装win7关闭核提高性能方法。 12代酷睿装win7说明&#xff1a;关闭小核解锁更多…

【分布式】分布式Session共享

这里通过SpringSession来实现Session的共享&#xff0c;Session数据存储在Redis中 SpringSession的操作指南&#xff1a; https://docs.spring.io/spring-session/docs/2.5.6/reference/html5/guides/boot-redis.html 导入相关的依赖 <dependency><groupId>org.s…

算法入门-递归3

第四部分&#xff1a;递归 143.重排链表&#xff08;中等&#xff09; 题目&#xff1a;给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → …