RaUI/Source/ryControls/Controls/List/IconViewEx.cs
鑫Intel 7a89ce0821 ### 2020-12-29 dev更新
------
#### ryControls    V2.1.2012.2901
- *.[新增]IconViewEx控件支持角标设置。
2020-12-29 18:29:39 +08:00

333 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ryControls
{
/// <summary>
/// 图标列表控件
/// </summary>
public class IconViewEx : ListView
{
private ColumnHeader columnHeader1;
/// <summary>
/// 图标列表控件
/// </summary>
public IconViewEx() :
base()
{
// 开启双缓冲
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.OwnerDraw = true;//用于启用重绘
this.View = View.Tile;
this.TileSize = new Size(100,100);
this.MultiSelect = false;
}
private int iconsize = 64;
/// <summary>
/// 图标大小
/// </summary>
[Description("图标大小")]
public int IconSize {
get { return iconsize; }
set
{
if(value>14 && value<=512)
{
iconsize = value;
}
else { iconsize = 64; }
}
}
private int textheight = 20;
/// <summary>
/// 文本显示高度(从底部算起)
/// </summary>
[Description("文本显示高度(从底部算起)")]
public int TextHeight
{
get { return textheight; }
set
{
if (value > 5 && value <= 100)
{
textheight = value;
}
else { textheight = 20; }
}
}
/// <summary>
/// 默认图标
/// </summary>
[Description("默认图标")]
public Image Icon { get; set; }
/// <summary>
/// 是否显示图标
/// </summary>
[Description("是否显示图标")]
public bool IsDrawIcon { get; set; } = true;
/// <summary>
/// 是否显示网格线
/// </summary>
[Description("是否显示网格线")]
public bool IsDrawGridLines { get; set; }
/// <summary>
/// 角标图标合集
/// </summary>
public List<Image> BadgeListImage { get; set; } = new List<Image>();
/// <summary>
/// 画项
/// </summary>
/// <param name="e"></param>
protected override void OnDrawItem(DrawListViewItemEventArgs e)
{
Rectangle r = e.Bounds;
Graphics g = e.Graphics;
DrawSelectedBackground(e, g, r);
int paddingHeight = 0;
if (IsDrawIcon)
{
var soft = (Interface.IItemInfo)e.Item.Tag;
if (soft == null || soft.Image == null)
{ paddingHeight = this.DrawIcon(g, r, this.Icon, e.Item.BackColor,-1).Height; }
else
{
paddingHeight = this.DrawIcon(g, r, soft.Image, e.Item.BackColor, soft.BadgeImageIndex).Height;
}
}
//if (IsDrawGridLines)
//{
// using (Pen pen = new Pen(Color.Gray))
// {
// g.DrawRectangle(pen, r.X, r.Y, r.Width, r.Height + 1);//高度加1使横向线条重叠
// }
//}
if (!string.IsNullOrEmpty(e.Item.Text))
{
this.DrawText(e, g, r, paddingHeight);
}
}
private Color _SelectedStartBackColor = Color.FromArgb(255, 251, 237);
/// <summary>
/// 选择项的背景开始颜色
/// </summary>
[Description("选择项的背景开始颜色")]
public Color SelectedStartBackColor
{
get
{
return _SelectedStartBackColor;
}
set
{
_SelectedStartBackColor = value;
this.Refresh();
}
}
private Color _SelectedEndBackColor = Color.FromArgb(255, 236, 181);
/// <summary>
/// 选择项的背景结束颜色
/// </summary>
[Description("选择项的背景结束颜色")]
public Color SelectedEndBackColor
{
get
{
return _SelectedEndBackColor;
}
set
{
_SelectedEndBackColor = value;
this.Refresh();
}
}
private Color _SelectedBorderColor = Color.FromArgb(229, 195, 101);
/// <summary>
/// 选择项的边框颜色
/// </summary>
[Description("选择项的边框颜色")]
public Color SelectedBorderColor
{
get
{
return _SelectedBorderColor;
}
set
{
_SelectedBorderColor = value;
this.Refresh();
}
}
private Color _SelectedForeColor = Color.Black;
/// <summary>
/// 选择项的字体颜色
/// </summary>
[Description("选择项的字体颜色")]
public Color SelectedForeColor
{
get
{
return _SelectedForeColor;
}
set
{
_SelectedForeColor = value;
this.Refresh();
}
}
/// <summary>
/// 重绘选中时背景
/// </summary>
private void DrawSelectedBackground(DrawListViewItemEventArgs e, Graphics g, Rectangle r)
{
if (e.Item.Selected)
{
//渐变画刷
LinearGradientBrush brush = new LinearGradientBrush(e.Bounds, _SelectedStartBackColor,
_SelectedEndBackColor, LinearGradientMode.Vertical);
//填充区域
//Rectangle borderRect = new Rectangle(r, e.Bounds.Y, e.Bounds.Width - 5, e.Bounds.Height - 2);
e.Graphics.FillRectangle(brush, r);
brush.Dispose();
////画边框
Pen pen = new Pen(_SelectedBorderColor);
Rectangle borderRect = r;
borderRect.Width--;
borderRect.Height--;
e.Graphics.DrawRectangle(pen, borderRect);
pen.Dispose();
//using (SolidBrush brush = new SolidBrush(_SelectedBackColor))
//{
// g.FillRectangle(brush, r);
//}
}
}
/// <summary>
/// 重绘图标
/// </summary>
/// <param name="g"></param>
/// <param name="r">区域大小</param>
/// <param name="image"></param>
/// <param name="backColor"></param>
/// <returns></returns>
private Size DrawIcon(Graphics g, Rectangle r, Image image, Color backColor,int BadgeImageIndex)
{
var x = r.X + ((r.Width - iconsize) / 2);
var y = r.Y + ((r.Height - textheight - iconsize) / 2);
Rectangle imageBounds = new Rectangle(new Point(x,y), new Size(iconsize, iconsize));
if (image.Width > image.Height)
{
imageBounds.Height =(int)((image.Height/(double)image.Width)* imageBounds.Width);
y += ((iconsize - imageBounds.Height) / 2);
}
else
{
x += ((iconsize - imageBounds.Width) / 2);
imageBounds.Width = (int)((image.Width / (double)image.Height) * imageBounds.Height);
}
imageBounds.X = x;
imageBounds.Y = y;
//imageBounds.X = r.X + (r.Width - imageBounds.Width) / 2;
//使图标不会紧贴着每一列的左上角
//imageBounds.X += 1;
//imageBounds.Y += 1;
//如果有角标,则显示角标
g.DrawImage(image, imageBounds);
if (BadgeImageIndex >= 0 && BadgeImageIndex < BadgeListImage.Count)
{
var badge = BadgeListImage[BadgeImageIndex];
if (badge != null)
{
var size = imageBounds.Width / 5;
var badge_rect = new Rectangle(imageBounds.Left + size * 4, imageBounds.Top, size, size);
g.DrawImage(badge, badge_rect);
}
}
return imageBounds.Size;
}
/// <summary>
/// 重绘文本
/// </summary>
private void DrawText(DrawListViewItemEventArgs e, Graphics g, Rectangle r, int paddingHeight)
{
TextFormatFlags flags = GetFormatFlags(HorizontalAlignment.Center);
var r1 = new Rectangle(r.Location, r.Size)
{
Y = r.Y + r.Height- textheight,//重绘图标时,文本右移
Height = textheight
};
TextRenderer.DrawText(
g,
e.Item.Text,
e.Item.Font,
r1,
e.Item.Selected ? SelectedForeColor : e.Item.ForeColor,
flags);
}
/// <summary>
/// 获取文本对齐
/// </summary>
private TextFormatFlags GetFormatFlags(
HorizontalAlignment align)
{
TextFormatFlags flags =
TextFormatFlags.EndEllipsis |
TextFormatFlags.VerticalCenter;
switch (align)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.HorizontalCenter;
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.Right;
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.Left;
break;
}
return flags;
}
const int WM_HSCROLL = 0x0114;
const int WM_VSCROLL = 0x0115;
/// <summary>
/// 水平滚动条滚动事件
/// </summary>
[Description("水平滚动条滚动事件")]
public event EventHandler HScroll;
/// <summary>
/// 垂直滚动条滚动事件
/// </summary>
[Description("垂直滚动条滚动事件")]
public event EventHandler VScroll;
/// <summary>
///
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_HSCROLL)
{
HScroll?.Invoke(this, new EventArgs());
}
else if (m.Msg == WM_VSCROLL)
{
VScroll?.Invoke(this, new EventArgs());
}
base.WndProc(ref m);
}
}
}