当前位置: 首页 > news >正文

C#/WinForm拖拽文件上传

 

一、首先创建一个上传文件的类,继承Control类,如下:


public class UploadControl : Control{private Image _image;public UploadControl(){this.SetStyle(ControlStyles.UserPaint |  //控件自行绘制,而不使用操作系统的绘制ControlStyles.AllPaintingInWmPaint | //忽略背景擦除的Windows消息,减少闪烁,只有UserPaint设为true时才能使用。ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。ControlStyles.SupportsTransparentBackColor, //支持透明背景颜色true);_image =Properties.Resources.upload;this.Cursor = Cursors.Hand;this.AllowDrop = true;}}

 准备好上传的图片

二、我们需要绘制圆角矩形,所以先准备一个圆角路径,如下:


private GraphicsPath GetRoundedRectPath(Rectangle rect, uint radius){int r = (int)radius << 1;Rectangle arcRect = new Rectangle(rect.Location, new Size(r, r));GraphicsPath path = new GraphicsPath();path.AddArc(arcRect, 180, 90);// 右上圆弧arcRect.X = rect.Right - r;path.AddArc(arcRect, 270, 90);// 右下圆弧arcRect.Y = rect.Bottom - r;path.AddArc(arcRect, 0, 90);// 左下圆弧arcRect.X = rect.Left;path.AddArc(arcRect, 90, 90);path.CloseFigure();return path;}

 三、重写OnPaint事件,绘制填充圆角背景

Rectangle outRect = new Rectangle(0, 0, this.Width, this.Height);
using var outPath = GetRoundedRectPath(outRect, Radius);
this.Region = new Region(path);
using SolidBrush b = new SolidBrush(this.BackColor);
e.Graphics.FillPath(b, outPath);

 效果如下:

发现使用Region属性有锯齿,尽管开启高质量绘图也无用,我们去掉Region属性,但是新的问题出现,此控件的背景必须和父级窗体的背景一致,不然圆角效果就没有了。后续我们都是不设置Region属性,保持背景与父级控件背景一致就行。

四、在OnPaint事件,绘制圆角边框

var innerRect = Rectangle.Inflate(outRect, -(int)border, -(int)border);
using GraphicsPath innerPath = GetRoundedRectPath(innerRect, Radius - border);
using Pen pen = new Pen(ColorState switch
{ControlState.Hover => this.BorderHoverColor,ControlState.Pressed => this.BorderPressedColor,ControlState.DragEnter => this.BorderHoverColor,_ => this.BorderNormalColor,
}, border);
pen.DashStyle = BorderStyle;
e.Graphics.DrawPath(pen, innerPath);

效果如下:

四、在OnPaint事件,绘制上传图像以及文字


const int h = 5;
SizeF sizeF = SizeF.Empty;
if (!string.IsNullOrWhiteSpace(Text))sizeF = e.Graphics.MeasureString(Text, this.Font);
if (_image != null)
{int imageH = 0;if (sizeF != SizeF.Empty){imageH = (int)((this.Height - _image.Height - h - sizeF.Height) / 2);TextRenderer.DrawText(e.Graphics, Text, this.Font, new Point((int)((this.Width - sizeF.Width) / 2), imageH + _image.Height + h), this.ForeColor);}elseimageH = this.Height - _image.Height >> 1;e.Graphics.DrawImage(_image, this.Width - _image.Width >> 1, imageH);
}
else
{if (sizeF != SizeF.Empty){TextRenderer.DrawText(e.Graphics, Text, this.Font, new Point((int)((this.Width - sizeF.Width) / 2), (int)((this.Height - sizeF.Height) / 2)), this.ForeColor);}
}

效果如下:

五、我们定义一个枚举,用来实现鼠标移、出移入、点击、文件拖动让边框变色


public enum ControlState { Hover, Normal, Pressed, DragEnter }

 然后重写OnMouseEnter、OnMouseLeave、OnMouseDown、OnMouseUp事件,如下:

private ControlState ColorState { get; set; }= ControlState.Normal;
protected override void OnMouseEnter(EventArgs e)//鼠标进入时
{ColorState = ControlState.Hover;//Hoverthis.Invalidate();base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)//鼠标离开
{ColorState = ControlState.Normal;//正常this.Invalidate();base.OnMouseLeave(e);
}
protected override void OnMouseDown(MouseEventArgs e)//鼠标按下
{if (e.Button == MouseButtons.Left && e.Clicks == 1)//鼠标左键且点击次数为1{ColorState = ControlState.Pressed;//按下的状态this.Invalidate();using OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = "所有文件 (*.*)|*.*";if (openFileDialog.ShowDialog() == DialogResult.OK){FilesCallback?.Invoke(new string[] { openFileDialog.FileName });}}base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)//鼠标弹起
{if (e.Button == MouseButtons.Left && e.Clicks == 1){if (ClientRectangle.Contains(e.Location))//控件区域包含鼠标的位置{ColorState = ControlState.Hover;}else{ColorState = ControlState.Normal;}this.Invalidate();}base.OnMouseUp(e);
}

就是在OnPaint事件中笔的颜色代码:

ColorState switch
{ControlState.Hover => this.BorderHoverColor,ControlState.Pressed => this.BorderPressedColor,ControlState.DragEnter => this.BorderHoverColor,_ => this.BorderNormalColor,
}

当然我们在OnMouseDown事件中还实现了点击选择文件:

using OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "所有文件 (*.*)|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{FilesCallback?.Invoke(new string[] { openFileDialog.FileName });
}

其中FilesCallback是一个事件:


public event Action<string[]> FilesCallback;

六、实现文件拖动上传

protected override void OnDragEnter(DragEventArgs drgevent)
{base.OnDragEnter(drgevent);if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))drgevent.Effect = DragDropEffects.Copy;elsedrgevent.Effect = DragDropEffects.None;ColorState = ControlState.DragEnter;this.Invalidate();
}
protected override void OnDragLeave(EventArgs e)
{base.OnDragLeave(e);ColorState = ControlState.Normal;this.Invalidate();
}
protected override void OnDragDrop(DragEventArgs drgevent)
{base.OnDragDrop(drgevent);ColorState = ControlState.Normal;this.Invalidate();object? obj = drgevent.Data?.GetData(DataFormats.FileDrop);if (obj == null) return;FilesCallback?.Invoke((string[])obj);
}

同时需要在构造函数中开启AllowDrop:

this.AllowDrop = true;

其它代码未在这里展示详情请见:

https://gitee.com/feng-cai/Seal-Bubbles

相关文章:

C#/WinForm拖拽文件上传

一、首先创建一个上传文件的类&#xff0c;继承Control类&#xff0c;如下&#xff1a; public class UploadControl : Control{private Image _image;public UploadControl(){this.SetStyle(ControlStyles.UserPaint | //控件自行绘制&#xff0c;而不使用操作系统的绘制Cont…...

IT运维的365天--019 用php做一个简单的文件上传工具

前情提要&#xff1a;朋友的工作室&#xff0c;有几个网站分布在不同的服务器上&#xff0c;要经常进行更新&#xff0c;之前是手动复制压缩包到各个服务器去更新&#xff08;有写了自动更新的Shell脚本&#xff09;。但还是觉得太麻烦&#xff0c;每次还要手动传输压缩包到各个…...

详细的oracle rac维护命令集合

一、查看命令 所有实例和服务的状态 $srvctl status database -d orcl Instance orcl1 is running on node db1 Instance orcl2 is running on node db2 单个实例的状态 $ srvctl status instance -d orcl -i orcl2 Instance orcl2 is running on node db2 单个节点的应用程序…...

23 种设计模式详解

设计模式的分类 总体来说设计模式分为三大类&#xff1a; 创建型模式&#xff0c;共五种&#xff1a;单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。 结构型模式&#xff0c;共七种&#xff1a;适配器模式、装饰器模式、代理模式、外观模式、桥接模式、 组合模…...

Python毕业设计选题:基于django+vue的二手物品交易系统

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 店铺管理 二手物品管理 广告管理 留言反馈 订单…...

VMware 17虚拟Ubuntu 22.04设置共享目录

VMware 17虚拟Ubuntu 22.04设置共享目录 共享文件夹挂载命令&#xff01;&#xff01;&#xff01;<font colorred>配置启动自动挂载Chapter1 VMware 17虚拟Ubuntu 22.04设置共享目录一、卸载老版本二、安装open-vm-tools<font colorred>三、配置启动自动挂载四、添…...

Rust学习(五):泛型、trait

Rust学习&#xff08;五&#xff09;&#xff1a;泛型、trait 1、泛型&#xff1a; 相信小伙伴们一定还记得&#xff0c;之前我们实现了一个add函数&#xff0c;并指定了参数类型为&#xff1a;i32&#xff1a; fn add(x:i32, y:i32) ->i32 {x y }这里我们就会遇到一个问…...

智能零售柜商品识别

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…...

2024智能机器人与自动控制国际学术会议 (IRAC 2024)

主办&#xff0c;承办&#xff0c;支持单位 会议官网 www.icirac.org 大会时间&#xff1a;2024年11月29-12月1日 大会简介 2024智能机器人与自动控制国际学术会议 &#xff08;IRAC 2024&#xff09;由华南理工大学主办&#xff0c;会议将于2024年11月29日-12月1日在中国广…...

计算机组成原理:总线与微命令

实验四 总线与微命令实验 一、实验目的 1&#xff09; 理解总线的概念和作用。 2&#xff09; 连接运算器与存储器&#xff0c;熟悉计算机的数据通路。 3&#xff09; 理解微命令与微操作的概念。 二、实验要求 1&#xff09; 做好实验预习&#xff0c;在实验之前填写好…...

10月回顾 | Apache SeaTunnel社区动态与进展一览

各位热爱 Apache SeaTunnel 的小伙伴们&#xff0c;社区10月份月报来啦&#xff0c;请查收&#xff01; 这里将记录Apache SeaTunne社区每月动态和进展&#xff0c;欢迎关注。 月度Merge之星 感谢以下小伙伴上个月为 Apache SeaTunnel 所做的精彩贡献&#xff08;排名不分先…...

网络基础(4)传输层

既然是传输层首先就要明确实在层状结构的哪里,除开物理层之外分成了四层协议: 到这里上层(应用层)的使用已经没有问题&#xff0c;之前使用的套接字都是在应用层的。 再说端口号 到一个主机收到一个报文的时候&#xff0c;这个报文中一定存在这个报文需要到的主机的ip号。如果…...

计算机的错误计算(一百五十六)

摘要 探讨 MATLAB 中双曲反余切函数 acoth(x) 在 附近数的计算精度问题。 Acoth(x)函数的定义为 例1. 已知 计算 与 直接贴图吧&#xff1a; 另外&#xff0c;16位的正确值分别为 0.1110083774360105e2 与 -0.1110083774360105e2&#xff08;ISRealsoft 提供。通过计算…...

爬虫开发工具与环境搭建——开发工具介绍

第二章&#xff1a;爬虫开发工具与环境搭建 第一节 开发工具介绍 爬虫开发需要一些合适的工具和框架来高效地抓取网页数据。在这节中&#xff0c;我们将介绍常用的开发工具&#xff0c;帮助开发者快速搭建爬虫开发环境。 1. Python与爬虫框架选择 Python因其简洁、易学的语法…...

Oracle 19c PDB克隆后出现Warning: PDB altered with errors受限模式处理

在进行一次19c PDB克隆过程中&#xff0c;发现克隆结束&#xff0c;在打开后出现了报错&#xff0c;PDB变成受限模式&#xff0c;以下是分析处理过程 09:25:48 SQL> alter pluggable database test1113 open instancesall; Warning: PDB altered with errors. Elapsed: 0…...

阿里云ACK容器如何配置pod分散在集群的不同节点上

阿里云ACK容器如何配置pod分散在集群的不同节点上 1.核心原理 是使用pod间反亲和性&#xff08;podAntiAffinity&#xff09;&#xff0c;pod间反亲和性又分为软约束反亲和和硬约束反亲和。 2.软约束反亲和和硬约束反亲和区别&#xff1a; preferredDuringSchedulingIgnore…...

Qt信号和槽

信号和槽的概念 在Linux中我们也学过信号 Signal&#xff0c;这是进程间通信的一种方式&#xff0c;这里大致分为三个要素&#xff1a; 信号源&#xff1a;谁发送的信号&#xff08;用户进程&#xff0c;系统内核&#xff0c;终端或者作业控制&#xff0c;&#xff09; 信号的类…...

Python知识点精汇!字符串:定义、截取(索引)和其内置函数

目录 一、字符串的定义 二、字符串的截取 1.截取干啥的 2.怎么用截取 3.打印多次 4.两个字符串拼接在一起 三、字符串内置函数 1.查询函数&#xff1a; &#xff08;1&#xff09;find(str,start,end) &#xff08;2&#xff09;index&#xff08;str,start,end&#…...

【CV】头盔检测区域入侵项目

文章目录 🌕项目和数据下载🌙安全帽佩戴数据集🌕收集数据数据🌕wbem格式视频转avi或者mp4🌕跑通区域入侵🌙多边形标注工具下载🌙使用Python脚本打开视频获取一张用来标注的图片🌙打开labelme标注一个多边行🌙程序可以识别的标注json格式🌙修改代码读取Json…...

大数据应用开发——实时数据处理(一)

前言 大数据应用开发——实时数据采集 大数据应用开发——实时数据处理 Flink完成Kafka中的数据消费&#xff0c;将数据分发至Kafka的dwd层中 并在HBase中进行备份 大数据应用开发——数据可视化 hadoop&#xff0c;zookeeper&#xff0c;kafka&#xff0c;flink要开启 目…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...