2025-10-13
C#
00

概述

CustomScrollListView 是一个基于 C# 和 GDI+ 的自定义控件,继承自 Control 类,能够实现具有列头和项目的滚动列表视图。此控件支持多列展示,并可以通过定时器实现自动滚动效果,使得用户可以流畅地查看列表内容。


主要特性

  • 列头支持:允许用户添加和自定义列头的文本、宽度以及背景和前景颜色。
  • 项目管理:每列可以向其添加项目,并支持动态更新。
  • 滚动效果:通过定时器控制滚动速度,实现流畅的滾动效果。
  • 可见项目数控制:用户可以设置可见的项目数量,自动调整控件的尺寸以适应。
2025-10-13
C#
00

在 Windows Forms 应用程序开发中,有时我们需要创建更加美观、灵活的界面控件。这篇文章将深入解析一个自定义的 CustomPanel 控件,它不仅继承了标准 Panel 的功能,还增加了 Bootstrap 风格的颜色主题和丰富的定制选项。

项目准备

  1. 创建一个新的 C# Windows Forms 应用程序项目。
  2. 添加一个新的类文件,命名为 CustomPanel.cs

实现自定义 Panel 控件

首先,在 CustomPanel.cs 文件中,引用必要的命名空间并创建 CustomPanel 类:

C#
using System; using System.Drawing; using System.Windows.Forms; namespace AppControls { // 定义 Bootstrap 颜色枚举 public enum BootstrapColors { Primary, Secondary, Success, Danger, Warning, Info, Light, Dark, White, Black } public class CustomPanel : Panel { // 标题属性 public string Title { get; set; } = "默认标题"; // 背景颜色属性(使用颜色枚举) private BootstrapColors _backgroundColor = BootstrapColors.Light; public BootstrapColors BackgroundColor { get => _backgroundColor; set { _backgroundColor = value; Invalidate(); // 触发重绘 } } // 实际的背景颜色 private Color ActualBackgroundColor => GetBootstrapColor(_backgroundColor); // 图标颜色属性 public Color IconColor { get; set; } = Color.White; // 标题字体属性 public Font TitleFont { get; set; } = new Font("Arial", 16, FontStyle.Bold); // 标题字体大小属性 public float TitleFontSize { get => TitleFont.Size; set => TitleFont = new Font(TitleFont.FontFamily, value, TitleFont.Style); } // 新增图标属性 private Image _panelIcon; public Image PanelIcon { get => _panelIcon; set { _panelIcon = value; Invalidate(); // 触发重绘 } } // 图标是否可见 public bool ShowIcon { get; set; } = false; // 获取对应的 Bootstrap 颜色 private Color GetBootstrapColor(BootstrapColors color) { return color switch { BootstrapColors.Primary => Color.FromArgb(0, 123, 255), BootstrapColors.Secondary => Color.FromArgb(108, 117, 125), BootstrapColors.Success => Color.FromArgb(40, 167, 69), BootstrapColors.Danger => Color.FromArgb(255, 7, 2), BootstrapColors.Warning => Color.FromArgb(255, 193, 7), BootstrapColors.Info => Color.FromArgb(23, 162, 184), BootstrapColors.Light => Color.FromArgb(248, 249, 250), BootstrapColors.Dark => Color.FromArgb(52, 58, 64), BootstrapColors.White => Color.FromArgb(255, 255, 255), BootstrapColors.Black => Color.FromArgb(0, 0, 0), _ => Color.LightBlue, // 默认颜色 }; } // 重写 OnPaint 方法以自定义绘制 protected override void OnPaint(PaintEventArgs e) { // 设置高质量绘制 e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; base.OnPaint(e); // 绘制背景 using (SolidBrush brush = new SolidBrush(ActualBackgroundColor)) { e.Graphics.FillRectangle(brush, e.ClipRectangle); } // 绘制图标(竖线) using (Pen pen = new Pen(IconColor, 3)) // 设置颜色和宽度 { e.Graphics.DrawLine(pen, new Point(5, 5), new Point(5, 25)); // 绘制竖线 } // 计算标题的高度和居中 Y 坐标 SizeF titleSize = e.Graphics.MeasureString(Title, TitleFont); // 获取标题的尺寸 float titleY = (25 - titleSize.Height) / 2 + 5; // 计算标题的 Y 坐标,使其居中 // 绘制标题 using (SolidBrush textBrush = new SolidBrush(Color.White)) { e.Graphics.DrawString(Title, TitleFont, textBrush, new PointF(20, titleY)); // 绘制标题 } // 绘制右侧图标 if (ShowIcon && PanelIcon != null) { // 计算图标的位置(右侧居中) int iconSize = 64; int iconX = Width - iconSize - 10; // 距离右边缘10像素 int iconY = (Height - iconSize) / 2; // 绘制图标 e.Graphics.DrawImage(PanelIcon, new Rectangle(iconX, iconY, iconSize, iconSize)); } } } }

image.png

适用场景

2025-10-13
C#
00

在 C# 的多线程编程中,线程可以分为前台线程(Foreground Thread)和后台线程(Background Thread)。这两种线程在创建、使用和资源管理方面有着各自的特点。本文将详细介绍前台线程和后台线程的特点、应用场景以及具体示例,帮助开发者更好地理解这两个概念。

前台线程的特点

  • 阻止应用程序退出:前台线程会阻止应用程序的退出,直到所有前台线程完成运行。也就是说,主线程会等待所有前台线程结束之后才能关闭。
  • 优先级和性能:前台线程通常拥有较高的优先级,适合执行重要且需要持久执行的操作。
  • 资源占用:前台线程在运行时占用更多的系统资源,适合用于确保执行任务的重要场合。

后台线程的特点

  • 不阻止应用程序退出:后台线程在没有前台线程运行时会自动终止,无论其是否完成。这使得后台线程适合于做一些不太重要的清理或监听工作。
  • 较低的优先级:后台线程的优先级通常较低,适合用于不需要长时间运行的任务或短期操作。
  • 资源管理:后台线程的资源管理更加灵活,系统会在应用程序退出时自动清理后台线程的资源。

创建前台线程和后台线程的基本语法

以下是创建前台线程和后台线程的基本用法示例:

创建前台线程

C#
using System.Threading; Thread foregroundThread = new Thread(new ThreadStart(SomeMethod)); // 创建前台线程 foregroundThread.Start(); // 启动线程
2025-10-13
C#
00

电源管理概述

Windows 电源管理是现代应用程序中非常重要的功能,它可以帮助开发者控制系统电源状态,优化应用程序的能耗和性能。在 C# 中,我们可以通过 Microsoft.Win32 命名空间和 System.Windows.Forms 中的相关类来实现电源管理功能。

电源状态管理

电源状态监控

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppPower { public class PowerStatusMonitor { /// <summary> /// 获取当前电池状态 /// </summary> public (float,string,int) MonitorBatteryStatus() { PowerStatus powerStatus = SystemInformation.PowerStatus; // 电池电量百分比 float batteryPercentage = powerStatus.BatteryLifePercent * 100; // 电池充电状态 string chargeStatus = powerStatus.BatteryChargeStatus.ToString(); // 剩余电池时间 int remainingMinutes = powerStatus.BatteryLifeRemaining; return (batteryPercentage, chargeStatus, remainingMinutes); } } }

image.png

2025-10-11
C#
00

在 C# 的多线程编程中,Task 类是处理异步操作的重要赋能,而 Task.WaitAll 方法则用于等待一组任务的完成。这在处理多个并行任务时非常有用,特别是在需要确保所有并发操作完成之前继续执行的场景中。本文将详细介绍 Task.WaitAll 的特点、用法,并提供多个示例以展示其应用。

这是个好玩意,以前thread中要同步这个费了事。

Task.WaitAll 的特点

  • 等待所有任务完成Task.WaitAll 方法接收一个任务数组,并阻塞当前线程,直到所有任务完成。
  • 简单易用:提供直接的方式来等待多个任务,可以通过简单的调用来确保所有任务都已完成。
  • 返回状态:如果所有任务完成,它会正常返回。如果任何任务引发异常,WaitAll 将会抛出相应的异常。
  • 适用于处理多个并行任务的结果:可以用在需要处理多个异步操作的结果时,方便地跟踪和管理任务的状态。

使用 Task.WaitAll 的基本语法

以下是 Task.WaitAll 的基本用法示例:

C#
using System.Threading.Tasks; Task[] tasks = new Task[3]; // 创建任务 Task.WaitAll(tasks); // 等待所有任务完成

示例:使用 Task.WaitAll 等待多个任务完成

以下示例展示了如何创建多个任务,并使用 Task.WaitAll 等待所有任务完成。

C#
using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task[] tasks = new Task[3]; // 创建并启动多个任务 for (int i = 0; i < tasks.Length; i++) { int taskId = i + 1; // 为任务分配ID tasks[i] = Task.Run(() => { int delay = new Random().Next(1000, 5000); // 随机延迟 Thread.Sleep(delay); // 模拟耗时操作 Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒"); }); } // 等待所有任务完成 Task.WaitAll(tasks); Console.WriteLine("所有任务已完成。"); } }

image.png