You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.5 KiB
C#

1 month ago
using System;
using System.Drawing;
using System.Windows.Forms;
namespace GeoSigma.SigmaDrawerStyle
{
/// <summary>
/// 线型
/// </summary>
public class SymbolListBox : ListBox
{
private int padding = 1;
private int itemHeight = 20;
private ISymbolListBoxProvider provider;
public event Action<string> SymbolSelected;
/// <summary>
/// Initializes a new instance of the <see cref="SymbolListBox"/> class.
/// </summary>
/// <param name="provider">provider</param>
public SymbolListBox(ISymbolListBoxProvider provider)
{
this.DrawMode = DrawMode.OwnerDrawFixed;
this.ItemHeight = itemHeight;
this.provider = provider;
string[] names = this.provider.GetNames();
this.Items.AddRange(names);
}
/// <inheritdoc/>
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
if (SelectedIndex >= 0 && SelectedIndex < Items.Count)
{
SymbolSelected?.Invoke(SelectedItem.ToString());
}
}
/// <inheritdoc/>
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (e.Index < 0 || e.Index >= Items.Count)
{
return;
}
string name = Items[e.Index].ToString();
Rectangle bounds = e.Bounds;
e.DrawBackground();
// 图像区域
int imageSize = bounds.Height - (2 * padding);
Rectangle imageRect = new Rectangle(
bounds.Left + padding,
bounds.Top + padding,
(bounds.Width - (2 * padding)) / 2,
imageSize);
// 获取并绘制图像
if (!string.IsNullOrWhiteSpace(name))
{
using (Bitmap bitmap = GetBitmap(name, imageRect.Width, imageRect.Height))
{
if (bitmap != null)
{
e.Graphics.DrawImage(bitmap, imageRect);
}
}
}
// 文字区域(图像右边,预留间距)
int textX = imageRect.Right + padding;
Rectangle textRect = new Rectangle(
textX,
bounds.Top,
bounds.Right - textX,
bounds.Height);
TextRenderer.DrawText(
e.Graphics,
name,
this.Font,
textRect,
(e.State & DrawItemState.Selected) != 0 ? SystemColors.HighlightText : this.ForeColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left);
e.DrawFocusRectangle();
}
private Bitmap GetBitmap(string name, int width, int height)
{
Bitmap bitmap = new Bitmap(width, height);
using (Graphics image = Graphics.FromImage(bitmap))
{
IntPtr hdc = image.GetHdc();
bool success = false;
try
{
success = this.provider.Draw(name, hdc, width, height);
}
finally
{
image.ReleaseHdc(hdc);
}
if (!success)
{
bitmap.Dispose();
return null;
}
}
return bitmap;
}
}
}