CustomScrollListView 是一个基于 C# 和 GDI+ 的自定义控件,继承自 Control 类,能够实现具有列头和项目的滚动列表视图。此控件支持多列展示,并可以通过定时器实现自动滚动效果,使得用户可以流畅地查看列表内容。
在 Windows Forms 应用程序开发中,有时我们需要创建更加美观、灵活的界面控件。这篇文章将深入解析一个自定义的 CustomPanel 控件,它不仅继承了标准 Panel 的功能,还增加了 Bootstrap 风格的颜色主题和丰富的定制选项。
CustomPanel.cs。首先,在 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));
}
}
}
}

在 C# 的多线程编程中,线程可以分为前台线程(Foreground Thread)和后台线程(Background Thread)。这两种线程在创建、使用和资源管理方面有着各自的特点。本文将详细介绍前台线程和后台线程的特点、应用场景以及具体示例,帮助开发者更好地理解这两个概念。
以下是创建前台线程和后台线程的基本用法示例:
C#using System.Threading;
Thread foregroundThread = new Thread(new ThreadStart(SomeMethod)); // 创建前台线程
foregroundThread.Start(); // 启动线程
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);
}
}
}

在 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("所有任务已完成。");
}
}
