gpt4 book ai didi

c# - 带文字的半透明圆形控件

转载 作者:太空狗 更新时间:2023-10-30 00:37:26 24 4
gpt4 key购买 nike

我正在做一个项目,其中我需要添加一个形状为圆形的控件,中间有一些文本。
我的问题是圆圈太小,当我调整它的大小时,它会与其他控件重叠。我想绘制与正方形宽度相同的圆。
否则。如何使控件的背景透明?

enter image description here

我正在使用下面的代码:

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);

using (SolidBrush brush = new SolidBrush(this._FillColor))
{
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
}

Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);

graphics.Dispose();
bitmap.Dispose();
}
}
}

最佳答案

这是一个派生自Control的自定义控件,可以做成半透明的。
界面是一个彩色圆圈,可以包含几个数字。

控件公开了这些自定义属性:

Opacity:控件BackGround的不透明度级别 [0, 255]
InnerPadding:内部矩形之间的距离,它定义了圆边界和控件边界。
FontPadding:文本与内矩形之间的距离。

透明度是通过覆盖 CreateParams 获得的, 然后设置 ExStyle |= WS_EX_TRANSPARENT;

Control.SetStyle()方法用于修改控件行为,添加这些 ControlStyles :

ControlStyles.Opaque:防止绘制控件的背景,因此不受系统管理。结合CreateParams设置Control的Extended Style为WS_EX_TRANSPARENT,Control变得完全透明。

ControlStyles.SupportsTransparentBackColor 控件接受其 BackGround 颜色的 Alpha 值。如果不同时设置 ControlStyles.UserPaint,它将不会用于模拟透明度。我们自己正在通过其他方式做到这一点。


要在工作中查看它,请创建一个新的类文件,用此代码替换其中的所有代码保留 namespace 并构建项目/解决方案。
新的自定义控件将出现在工具箱中。将其放在表单上。根据需要修改其自定义属性。

控件的可视化表示:

WinForms Translucent Label

注意事项及免责声明:

  • 这是一个原型(prototype)控件,缺少自定义设计器(不能在这里发布,代码太多,还连接到一个框架)。
    如此处所示,它可用于完全重叠表单或其他容器中的其他控件。在此简化的实现中不处理部分重叠。
  • 该字体被硬编码到 Segoe UI,因为该字体有一个基线,可以简化文本在圆形区域中间的位置。
    其他字体有不同的基线,这需要更复杂的处理。
    请参阅:TextBox with dotted lines for typing基础数学。

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

[DesignerCategory("Code")]
public class RoundCenterLabel : Label, INotifyPropertyChanged, ISupportInitialize
{
private const int WS_EX_TRANSPARENT = 0x00000020;
private bool IsInitializing = false;
private Point MouseDownLocation = Point.Empty;
private readonly int fontPadding = 4;
private Font m_CustomFont = null;
private Color m_BackGroundColor;
private int m_InnerPadding = 0;
private int m_FontPadding = 25;
private int m_Opacity = 128;

public event PropertyChangedEventHandler PropertyChanged;

public RoundCenterLabel() => InitializeComponent();

private void InitializeComponent()
{
SetStyle(ControlStyles.Opaque |
ControlStyles.SupportsTransparentBackColor |
ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
m_CustomFont = new Font("Segoe UI", 50, FontStyle.Regular, GraphicsUnit.Pixel);
BackColor = Color.LimeGreen;
ForeColor = Color.White;
}

protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= WS_EX_TRANSPARENT;
return cp;
}
}

public new Font Font
{
get => m_CustomFont;
set {
m_CustomFont = value;
if (IsInitializing) return;
FontAdapter(value, DeviceDpi);
NotifyPropertyChanged();
}
}

public override string Text {
get => base.Text;
set { base.Text = value;
NotifyPropertyChanged();
}
}

public int InnerPadding {
get => m_InnerPadding;
set {
if (IsInitializing) return;
m_InnerPadding = ValidateRange(value, 0, ClientRectangle.Height - 10);
NotifyPropertyChanged(); }
}

public int FontPadding {
get => m_FontPadding;
set {
if (IsInitializing) return;
m_FontPadding = ValidateRange(value, 0, ClientRectangle.Height - 10);
NotifyPropertyChanged();
}
}

public int Opacity {
get => m_Opacity;
set { m_Opacity = ValidateRange(value, 0, 255);
UpdateBackColor(m_BackGroundColor);
NotifyPropertyChanged();
}
}

public override Color BackColor {
get => m_BackGroundColor;
set { UpdateBackColor(value);
NotifyPropertyChanged();
}
}

protected override void OnLayout(LayoutEventArgs e)
{
base.OnLayout(e);
base.AutoSize = false;
}

private void NotifyPropertyChanged([CallerMemberName] string PropertyName = null)
{
InvalidateParent();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}

protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
MouseDownLocation = e.Location;
}

protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left) {
var loc = new Point(Left + (e.X - MouseDownLocation.X), Top + (e.Y - MouseDownLocation.Y));
InvalidateParent();
BeginInvoke(new Action(() => Location = loc));
}
}

private void InvalidateParent()
{
Parent?.Invalidate(Bounds, true);
Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
using (var format = new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoWrap, CultureInfo.CurrentUICulture.LCID))
{
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

using (var circleBrush = new SolidBrush(m_BackGroundColor))
using (var foreBrush = new SolidBrush(ForeColor))
{
FontAdapter(m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(circleBrush, rect);
e.Graphics.DrawString(Text, m_CustomFont, foreBrush, rect, format);
};
};
}

public void BeginInit() => IsInitializing = true;

public void EndInit()
{
IsInitializing = false;
Font = new Font("Segoe UI", 50, FontStyle.Regular, GraphicsUnit.Pixel);
FontPadding = m_FontPadding;
InnerPadding = m_InnerPadding;
}

private RectangleF InnerRectangle()
{
(float Min, _) = GetMinMax(ClientRectangle.Height, ClientRectangle.Width);
var size = new SizeF(Min - (m_InnerPadding / 2), Min - (m_InnerPadding / 2));
var position = new PointF((ClientRectangle.Width - size.Width) / 2,
(ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
}

private void FontAdapter(Font font, float dpi)
{
RectangleF rect = InnerRectangle();
float fontSize = ValidateRange(
(int)(rect.Height - m_FontPadding), 6,
(int)(rect.Height - m_FontPadding)) / (dpi / 72.0F) - fontPadding;

m_CustomFont.Dispose();
m_CustomFont = new Font(font.FontFamily, fontSize, font.Style, GraphicsUnit.Pixel);
}

private void UpdateBackColor(Color color)
{
m_BackGroundColor = Color.FromArgb(m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = m_BackGroundColor;
}

private int ValidateRange(int Value, int Min, int Max)
=> Math.Max(Math.Min(Value, Max), Min); // (Value < Min) ? Min : ((Value > Max) ? Max : Value);

private (float, float) GetMinMax(float Value1, float Value2)
=> (Math.Min(Value1, Value2), Math.Max(Value1, Value2));
}

关于c# - 带文字的半透明圆形控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51396681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com