
[ToolboxBitmap(typeof(Label))] publicpartialclassImageLabel : Label { private Image _image; privateint _imageWidth 32; privateint _imageHeight 32; privateint _imageTextSpacing 5; private ContentAlignment _imageAlign ContentAlignment.MiddleLeft; // 默认图片左中对齐 publicImageLabel() { this.DoubleClick ImageLabel_DoubleClick; // 确保控件支持透明背景如果需要 this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.ResizeRedraw, true); } #region Public Properties [Category(Appearance)] [Description(The image displayed.)] public Image Image { get { return _image; } set { _image value; Invalidate(); OnImageChanged(EventArgs.Empty); } } [Category(Appearance)] [DefaultValue(32)] publicint ImageWidth { get { return _imageWidth; } set { _imageWidth value; Invalidate(); } } [Category(Appearance)] [DefaultValue(32)] publicint ImageHeight { get { return _imageHeight; } set { _imageHeight value; Invalidate(); } } [Category(Appearance)] [DefaultValue(5)] publicint ImageTextSpacing { get { return _imageTextSpacing; } set { _imageTextSpacing value; Invalidate(); } } [Category(Appearance)] [Description(Determines the alignment of the image within the control.)] [DefaultValue(ContentAlignment.MiddleLeft)] public ContentAlignment ImageAlign { get { return _imageAlign; } set { _imageAlign value; Invalidate(); } } #endregion #region Events [Category(Property Changed)] [Description(Occurs when the Image property value changes.)] publicevent EventHandler ImageChanged; protectedvirtualvoidOnImageChanged(EventArgs e) { ImageChanged?.Invoke(this, e); } #endregion #region Overridden Methods protectedoverridevoidOnPaint(PaintEventArgs e) { // 计算图片矩形根据 ImageAlign 对齐 Rectangle imageRect GetImageRectangle(); // 计算文字矩形自动避开图片区域 Rectangle textRect GetTextRectangle(imageRect); // 绘制图片 if (Image ! null) { e.Graphics.DrawImage(Image, imageRect); } // 绘制文字 TextFormatFlags flags TextFormatFlags.WordBreak | TextFormatFlags.VerticalCenter; // 根据文字对齐方式调整 flags可选这里简单使用左对齐 flags | TextFormatFlags.Left; TextRenderer.DrawText(e.Graphics, this.Text, this.Font, textRect, this.ForeColor, flags); } #endregion #region Private Layout Methods ///summary /// 根据 ImageAlign 计算图片的绘制位置 ////summary private Rectangle GetImageRectangle() { int x 0, y 0; int clientWidth this.ClientSize.Width; int clientHeight this.ClientSize.Height; // 水平对齐 switch (ImageAlign) { case ContentAlignment.TopLeft: case ContentAlignment.MiddleLeft: case ContentAlignment.BottomLeft: x Padding.Left; break; case ContentAlignment.TopCenter: case ContentAlignment.MiddleCenter: case ContentAlignment.BottomCenter: x (clientWidth - ImageWidth) / 2; break; case ContentAlignment.TopRight: case ContentAlignment.MiddleRight: case ContentAlignment.BottomRight: x clientWidth - Padding.Right - ImageWidth; break; } // 垂直对齐 switch (ImageAlign) { case ContentAlignment.TopLeft: case ContentAlignment.TopCenter: case ContentAlignment.TopRight: y Padding.Top; break; case ContentAlignment.MiddleLeft: case ContentAlignment.MiddleCenter: case ContentAlignment.MiddleRight: y (clientHeight - ImageHeight) / 2; break; case ContentAlignment.BottomLeft: case ContentAlignment.BottomCenter: case ContentAlignment.BottomRight: y clientHeight - Padding.Bottom - ImageHeight; break; } // 边界检查确保不超出控件范围 x Math.Max(Padding.Left, Math.Min(x, clientWidth - Padding.Right - ImageWidth)); y Math.Max(Padding.Top, Math.Min(y, clientHeight - Padding.Bottom - ImageHeight)); returnnew Rectangle(x, y, ImageWidth, ImageHeight); } ///summary /// 计算文字区域自动避开图片区域 ////summary private Rectangle GetTextRectangle(Rectangle imageRect) { Rectangle textRect new Rectangle(Padding.Left, Padding.Top, this.ClientSize.Width - Padding.Left - Padding.Right, this.ClientSize.Height - Padding.Top - Padding.Bottom); // 如果图片为空直接返回全区域 if (Image null) return textRect; // 根据图片对齐方式判断文字应该放在图片的哪一侧 // 简单策略如果图片在左边文字放在右边图片在右边文字放在左边图片在顶部/底部则文字放在剩余区域 // 更完善的方案可以自由组合这里演示最常见的几种 bool imageLeft (ImageAlign ContentAlignment.MiddleLeft || ImageAlign ContentAlignment.TopLeft || ImageAlign ContentAlignment.BottomLeft); bool imageRight (ImageAlign ContentAlignment.MiddleRight || ImageAlign ContentAlignment.TopRight || ImageAlign ContentAlignment.BottomRight); bool imageTop (ImageAlign ContentAlignment.TopCenter || ImageAlign ContentAlignment.TopLeft || ImageAlign ContentAlignment.TopRight); bool imageBottom (ImageAlign ContentAlignment.BottomCenter || ImageAlign ContentAlignment.BottomLeft || ImageAlign ContentAlignment.BottomRight); if (imageLeft) { int textLeft imageRect.Right ImageTextSpacing; textRect new Rectangle(textLeft, textRect.Y, this.ClientSize.Width - textLeft - Padding.Right, textRect.Height); } elseif (imageRight) { int textRight imageRect.Left - ImageTextSpacing; textRect new Rectangle(Padding.Left, textRect.Y, Math.Max(0, textRight - Padding.Left), textRect.Height); } elseif (imageTop) { int textTop imageRect.Bottom ImageTextSpacing; textRect new Rectangle(textRect.X, textTop, textRect.Width, this.ClientSize.Height - textTop - Padding.Bottom); } elseif (imageBottom) { int textBottom imageRect.Top - ImageTextSpacing; textRect new Rectangle(textRect.X, Padding.Top, textRect.Width, Math.Max(0, textBottom - Padding.Top)); } else// 居中情况文字覆盖图片区域或简单放在下方 { // 如果图片居中文字默认放在图片下方 int textTop imageRect.Bottom ImageTextSpacing; textRect new Rectangle(textRect.X, textTop, textRect.Width, this.ClientSize.Height - textTop - Padding.Bottom); } // 确保文字矩形有效 if (textRect.Width 0) textRect.Width 0; if (textRect.Height 0) textRect.Height 0; return textRect; } #endregion #region Double-click to upload image privatevoidImageLabel_DoubleClick(object sender, EventArgs e) { using (OpenFileDialog openFileDialog new OpenFileDialog()) { openFileDialog.Title 请选择一张图片; openFileDialog.Filter 图像文件|*.jpg;*.jpeg;*.png;*.gif;*.bmp; if (openFileDialog.ShowDialog() DialogResult.OK) { this.Image Image.FromFile(openFileDialog.FileName); } } } #endregion