* UIListBox: 增加滚动条颜色设置
This commit is contained in:
parent
1c97f500c6
commit
2ce63dfa9c
120
SunnyUI/Controls/UIImageListBox.resx
Normal file
120
SunnyUI/Controls/UIImageListBox.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
@ -28,6 +28,7 @@
|
|||||||
* 2022-02-23: V3.1.1 按键上下移动选择项目时,滚动条跟随
|
* 2022-02-23: V3.1.1 按键上下移动选择项目时,滚动条跟随
|
||||||
* 2022-03-08: V3.1.1 修复在选中某一项后,清除选中项需要两次操作
|
* 2022-03-08: V3.1.1 修复在选中某一项后,清除选中项需要两次操作
|
||||||
* 2022-03-19: V3.1.1 重构主题配色
|
* 2022-03-19: V3.1.1 重构主题配色
|
||||||
|
* 2022-05-15: V3.1.8 增加滚动条颜色设置
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -93,6 +94,44 @@ namespace Sunny.UI
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color scrollBarColor = Color.FromArgb(80, 160, 255);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 填充颜色,当值为背景色或透明色或空值则不填充
|
||||||
|
/// </summary>
|
||||||
|
[Description("填充颜色"), Category("SunnyUI")]
|
||||||
|
[DefaultValue(typeof(Color), "80, 160, 255")]
|
||||||
|
public Color ScrollBarColor
|
||||||
|
{
|
||||||
|
get => scrollBarColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
scrollBarColor = value;
|
||||||
|
bar.HoverColor = bar.PressColor = bar.ForeColor = value;
|
||||||
|
_style = UIStyle.Custom;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color scrollBarBackColor = Color.FromArgb(243, 249, 255);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 填充颜色,当值为背景色或透明色或空值则不填充
|
||||||
|
/// </summary>
|
||||||
|
[Description("填充颜色"), Category("SunnyUI")]
|
||||||
|
[DefaultValue(typeof(Color), "243, 249, 255")]
|
||||||
|
public Color ScrollBarBackColor
|
||||||
|
{
|
||||||
|
get => scrollBarBackColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
scrollBarBackColor = value;
|
||||||
|
bar.FillColor = value;
|
||||||
|
_style = UIStyle.Custom;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Listbox_DrawItem(object sender, DrawItemEventArgs e)
|
private void Listbox_DrawItem(object sender, DrawItemEventArgs e)
|
||||||
{
|
{
|
||||||
DrawItem?.Invoke(sender, e);
|
DrawItem?.Invoke(sender, e);
|
||||||
@ -393,12 +432,15 @@ namespace Sunny.UI
|
|||||||
public override void SetStyleColor(UIBaseStyle uiColor)
|
public override void SetStyleColor(UIBaseStyle uiColor)
|
||||||
{
|
{
|
||||||
base.SetStyleColor(uiColor);
|
base.SetStyleColor(uiColor);
|
||||||
|
|
||||||
if (bar != null)
|
if (bar != null)
|
||||||
{
|
{
|
||||||
bar.ForeColor = uiColor.ListBarForeColor;
|
bar.ForeColor = uiColor.PrimaryColor;
|
||||||
bar.HoverColor = uiColor.ButtonFillHoverColor;
|
bar.HoverColor = uiColor.ButtonFillHoverColor;
|
||||||
bar.PressColor = uiColor.ButtonFillPressColor;
|
bar.PressColor = uiColor.ButtonFillPressColor;
|
||||||
bar.FillColor = uiColor.ListBarFillColor;
|
bar.FillColor = uiColor.GridBarFillColor;
|
||||||
|
scrollBarColor = uiColor.PrimaryColor;
|
||||||
|
scrollBarBackColor = uiColor.GridBarFillColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
hoverColor = uiColor.ListItemHoverColor;
|
hoverColor = uiColor.ListItemHoverColor;
|
||||||
@ -600,405 +642,4 @@ namespace Sunny.UI
|
|||||||
return GetItemText(Items[index]);
|
return GetItemText(Items[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ListBox
|
|
||||||
/// </summary>
|
|
||||||
[ToolboxItem(false)]
|
|
||||||
public sealed class ListBoxEx : ListBox
|
|
||||||
{
|
|
||||||
private UIScrollBar bar;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tag字符串
|
|
||||||
/// </summary>
|
|
||||||
[DefaultValue(null)]
|
|
||||||
[Description("获取或设置包含有关控件的数据的对象字符串"), Category("SunnyUI")]
|
|
||||||
public string TagString { get; set; }
|
|
||||||
|
|
||||||
[Browsable(false), DefaultValue(false)]
|
|
||||||
public bool IsScaled { get; set; }
|
|
||||||
|
|
||||||
public void SetDPIScale()
|
|
||||||
{
|
|
||||||
if (!IsScaled)
|
|
||||||
{
|
|
||||||
this.SetDPIScaleFont();
|
|
||||||
IsScaled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIScrollBar Bar
|
|
||||||
{
|
|
||||||
get => bar;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
bar = value;
|
|
||||||
SetScrollInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count => Items.Count;
|
|
||||||
|
|
||||||
public ListBoxEx()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
||||||
SetStyle(ControlStyles.DoubleBuffer, true);
|
|
||||||
UpdateStyles();
|
|
||||||
this.DoubleBuffered();
|
|
||||||
|
|
||||||
BorderStyle = BorderStyle.None;
|
|
||||||
ForeColor = UIFontColor.Primary;
|
|
||||||
IntegralHeight = false;
|
|
||||||
Version = UIGlobal.Version;
|
|
||||||
SetScrollInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler ItemsClear;
|
|
||||||
public event EventHandler ItemsAdd;
|
|
||||||
public event EventHandler ItemsRemove;
|
|
||||||
public event EventHandler ItemsInsert;
|
|
||||||
|
|
||||||
protected override void WndProc(ref Message m)
|
|
||||||
{
|
|
||||||
if (IsDisposed || Disposing) return;
|
|
||||||
if (IsHandleCreated)
|
|
||||||
{
|
|
||||||
const int LB_ADDSTRING = 0x0180;
|
|
||||||
const int LB_INSERTSTRING = 0x0181;
|
|
||||||
const int LB_DELETESTRING = 0x0182;
|
|
||||||
const int LB_RESETCONTENT = 0x0184;
|
|
||||||
if (m.Msg == LB_RESETCONTENT)
|
|
||||||
{
|
|
||||||
ItemsClear?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.Msg == LB_DELETESTRING)
|
|
||||||
{
|
|
||||||
ItemsRemove?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.Msg == LB_ADDSTRING)
|
|
||||||
{
|
|
||||||
ItemsAdd?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.Msg == LB_INSERTSTRING)
|
|
||||||
{
|
|
||||||
ItemsInsert?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (m.Msg == Win32.User.WM_ERASEBKGND)
|
|
||||||
//{
|
|
||||||
// m.Result = IntPtr.Zero;
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
base.WndProc(ref m);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnSizeChanged(EventArgs e)
|
|
||||||
{
|
|
||||||
if (Bar != null && Bar.Visible)
|
|
||||||
{
|
|
||||||
if (Bar.Value != 0)
|
|
||||||
{
|
|
||||||
ScrollBarInfo.SetScrollValue(Handle, Bar.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//SetScrollInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnSelectedIndexChanged(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnSelectedIndexChanged(e);
|
|
||||||
SetScrollInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetScrollInfo()
|
|
||||||
{
|
|
||||||
if (Bar == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var si = ScrollBarInfo.GetInfo(Handle);
|
|
||||||
if (si.ScrollMax > 0)
|
|
||||||
{
|
|
||||||
Bar.Maximum = si.ScrollMax;
|
|
||||||
Bar.Visible = si.ScrollMax > 0 && si.nMax > 0 && si.nPage > 0;
|
|
||||||
Bar.Value = si.nPos;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Bar.Visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Version { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 自定义主题风格
|
|
||||||
/// </summary>
|
|
||||||
[DefaultValue(false)]
|
|
||||||
[Description("获取或设置可以自定义主题风格"), Category("SunnyUI")]
|
|
||||||
public bool StyleCustomMode { get; set; }
|
|
||||||
|
|
||||||
#region 组件设计器生成的代码
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设计器支持所需的方法 - 不要
|
|
||||||
/// 使用代码编辑器修改此方法的内容。
|
|
||||||
/// </summary>
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
SuspendLayout();
|
|
||||||
//
|
|
||||||
// UIListBox
|
|
||||||
//
|
|
||||||
BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
DrawMode = DrawMode.OwnerDrawFixed;
|
|
||||||
Font = UIFontColor.Font();
|
|
||||||
IntegralHeight = false;
|
|
||||||
ItemHeight = 25;
|
|
||||||
Size = new Size(150, 200);
|
|
||||||
ResumeLayout(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion 组件设计器生成的代码
|
|
||||||
|
|
||||||
private UIStyle _style = UIStyle.Blue;
|
|
||||||
private Color _itemSelectBackColor = UIColor.Blue;
|
|
||||||
private Color _itemSelectForeColor = Color.White;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 主题样式
|
|
||||||
/// </summary>
|
|
||||||
[DefaultValue(UIStyle.Blue), Description("主题样式"), Category("SunnyUI")]
|
|
||||||
public UIStyle Style
|
|
||||||
{
|
|
||||||
get => _style;
|
|
||||||
set => SetStyle(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMouseWheel(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMouseWheel(e);
|
|
||||||
|
|
||||||
if (Bar != null && Bar.Visible)
|
|
||||||
{
|
|
||||||
var si = ScrollBarInfo.GetInfo(Handle);
|
|
||||||
int temp = Math.Abs(e.Delta / 120);
|
|
||||||
if (e.Delta > 10)
|
|
||||||
{
|
|
||||||
int nposnum = si.nPos - temp * SystemInformation.MouseWheelScrollLines;
|
|
||||||
ScrollBarInfo.SetScrollValue(Handle, nposnum >= si.nMin ? nposnum : 0);
|
|
||||||
}
|
|
||||||
else if (e.Delta < -10)
|
|
||||||
{
|
|
||||||
int nposnum = si.nPos + temp * SystemInformation.MouseWheelScrollLines;
|
|
||||||
ScrollBarInfo.SetScrollValue(Handle, nposnum <= si.ScrollMax ? nposnum : si.ScrollMax);
|
|
||||||
}
|
|
||||||
SetScrollInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetStyle(UIStyle style)
|
|
||||||
{
|
|
||||||
if (!style.IsCustom())
|
|
||||||
{
|
|
||||||
SetStyleColor(style.Colors());
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
_style = style;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetStyleColor(UIBaseStyle uiColor)
|
|
||||||
{
|
|
||||||
ItemSelectBackColor = uiColor.ListItemSelectBackColor;
|
|
||||||
ItemSelectForeColor = uiColor.ListItemSelectForeColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Category("SunnyUI"), Description("The border color used to paint the control.")]
|
|
||||||
public Color ItemSelectBackColor
|
|
||||||
{
|
|
||||||
get => _itemSelectBackColor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_itemSelectBackColor != value)
|
|
||||||
{
|
|
||||||
_itemSelectBackColor = value;
|
|
||||||
_style = UIStyle.Custom;
|
|
||||||
if (DesignMode)
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Category("SunnyUI"), Description("The border color used to paint the control.")]
|
|
||||||
public Color ItemSelectForeColor
|
|
||||||
{
|
|
||||||
get => _itemSelectForeColor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_itemSelectForeColor != value)
|
|
||||||
{
|
|
||||||
_itemSelectForeColor = value;
|
|
||||||
_style = UIStyle.Custom;
|
|
||||||
if (DesignMode)
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void OnBeforeDrawItem(object sender, ObjectCollection items, DrawItemEventArgs e);
|
|
||||||
|
|
||||||
public event OnBeforeDrawItem BeforeDrawItem;
|
|
||||||
|
|
||||||
public event OnBeforeDrawItem AfterDrawItem;
|
|
||||||
|
|
||||||
private StringAlignment textAlignment = StringAlignment.Near;
|
|
||||||
|
|
||||||
public StringAlignment TextAlignment
|
|
||||||
{
|
|
||||||
get => textAlignment;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
textAlignment = value;
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDrawItem(DrawItemEventArgs e)
|
|
||||||
{
|
|
||||||
BeforeDrawItem?.Invoke(this, Items, e);
|
|
||||||
if (Items.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool otherState = e.State == DrawItemState.Grayed || e.State == DrawItemState.HotLight;
|
|
||||||
if (!otherState)
|
|
||||||
{
|
|
||||||
e.DrawBackground();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Index < 0 || e.Index >= Items.Count)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringFormat sStringFormat = new StringFormat();
|
|
||||||
sStringFormat.LineAlignment = StringAlignment.Center;
|
|
||||||
sStringFormat.Alignment = textAlignment;
|
|
||||||
|
|
||||||
bool isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
|
|
||||||
Color backColor = isSelected ? ItemSelectBackColor : BackColor;
|
|
||||||
Color foreColor = isSelected ? ItemSelectForeColor : ForeColor;
|
|
||||||
|
|
||||||
Rectangle rect = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1);
|
|
||||||
string showText = DisplayMember.IsNullOrEmpty() ? Items[e.Index].ToString() : GetItemText(Items[e.Index]);
|
|
||||||
|
|
||||||
if (!otherState)
|
|
||||||
{
|
|
||||||
e.Graphics.FillRectangle(BackColor, e.Bounds);
|
|
||||||
e.Graphics.FillRectangle(backColor, rect);
|
|
||||||
e.Graphics.DrawString(showText, e.Font, foreColor, e.Bounds, sStringFormat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (e.State == DrawItemState.Grayed)
|
|
||||||
{
|
|
||||||
backColor = BackColor;
|
|
||||||
foreColor = ForeColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.State == DrawItemState.HotLight)
|
|
||||||
{
|
|
||||||
backColor = HoverColor;
|
|
||||||
foreColor = ForeColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Graphics.FillRectangle(BackColor, e.Bounds);
|
|
||||||
e.Graphics.FillRectangle(backColor, rect);
|
|
||||||
e.Graphics.DrawString(showText, e.Font, foreColor, e.Bounds, sStringFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
AfterDrawItem?.Invoke(this, Items, e);
|
|
||||||
|
|
||||||
base.OnDrawItem(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color hoverColor = Color.FromArgb(155, 200, 255);
|
|
||||||
|
|
||||||
[DefaultValue(typeof(Color), "155, 200, 255")]
|
|
||||||
public Color HoverColor
|
|
||||||
{
|
|
||||||
get => hoverColor;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
hoverColor = value;
|
|
||||||
_style = UIStyle.Custom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMeasureItem(MeasureItemEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMeasureItem(e);
|
|
||||||
e.ItemHeight += ItemHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SelectedFirst()
|
|
||||||
{
|
|
||||||
if (Items.Count > 0 && SelectedIndex < 0)
|
|
||||||
{
|
|
||||||
SelectedIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int lastIndex = -1;
|
|
||||||
private int mouseIndex = -1;
|
|
||||||
|
|
||||||
[Browsable(false)]
|
|
||||||
public int MouseIndex
|
|
||||||
{
|
|
||||||
get => mouseIndex;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (mouseIndex != value)
|
|
||||||
{
|
|
||||||
if (lastIndex >= 0 && lastIndex >= 0 && lastIndex < Items.Count && lastIndex != SelectedIndex)
|
|
||||||
{
|
|
||||||
OnDrawItem(new DrawItemEventArgs(CreateGraphics(), Font, GetItemRectangle(lastIndex), lastIndex, DrawItemState.Grayed));
|
|
||||||
}
|
|
||||||
|
|
||||||
mouseIndex = value;
|
|
||||||
if (mouseIndex >= 0 && mouseIndex >= 0 && mouseIndex < Items.Count && mouseIndex != SelectedIndex)
|
|
||||||
{
|
|
||||||
OnDrawItem(new DrawItemEventArgs(CreateGraphics(), Font, GetItemRectangle(value), value, DrawItemState.HotLight));
|
|
||||||
}
|
|
||||||
|
|
||||||
lastIndex = mouseIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMouseMove(e);
|
|
||||||
if (SelectionMode != SelectionMode.One) return;
|
|
||||||
MouseIndex = IndexFromPoint(e.Location);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMouseLeave(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMouseLeave(e);
|
|
||||||
if (SelectionMode != SelectionMode.One) return;
|
|
||||||
MouseIndex = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
408
SunnyUI/Controls/UIListBoxEx.cs
Normal file
408
SunnyUI/Controls/UIListBoxEx.cs
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Sunny.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ListBox
|
||||||
|
/// </summary>
|
||||||
|
[ToolboxItem(false)]
|
||||||
|
internal sealed class ListBoxEx : ListBox
|
||||||
|
{
|
||||||
|
private UIScrollBar bar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tag字符串
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(null)]
|
||||||
|
[Description("获取或设置包含有关控件的数据的对象字符串"), Category("SunnyUI")]
|
||||||
|
public string TagString { get; set; }
|
||||||
|
|
||||||
|
[Browsable(false), DefaultValue(false)]
|
||||||
|
public bool IsScaled { get; set; }
|
||||||
|
|
||||||
|
public void SetDPIScale()
|
||||||
|
{
|
||||||
|
if (!IsScaled)
|
||||||
|
{
|
||||||
|
this.SetDPIScaleFont();
|
||||||
|
IsScaled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIScrollBar Bar
|
||||||
|
{
|
||||||
|
get => bar;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
bar = value;
|
||||||
|
SetScrollInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count => Items.Count;
|
||||||
|
|
||||||
|
public ListBoxEx()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||||
|
SetStyle(ControlStyles.DoubleBuffer, true);
|
||||||
|
UpdateStyles();
|
||||||
|
this.DoubleBuffered();
|
||||||
|
|
||||||
|
BorderStyle = BorderStyle.None;
|
||||||
|
ForeColor = UIFontColor.Primary;
|
||||||
|
IntegralHeight = false;
|
||||||
|
Version = UIGlobal.Version;
|
||||||
|
SetScrollInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler ItemsClear;
|
||||||
|
public event EventHandler ItemsAdd;
|
||||||
|
public event EventHandler ItemsRemove;
|
||||||
|
public event EventHandler ItemsInsert;
|
||||||
|
|
||||||
|
protected override void WndProc(ref Message m)
|
||||||
|
{
|
||||||
|
if (IsDisposed || Disposing) return;
|
||||||
|
if (IsHandleCreated)
|
||||||
|
{
|
||||||
|
const int LB_ADDSTRING = 0x0180;
|
||||||
|
const int LB_INSERTSTRING = 0x0181;
|
||||||
|
const int LB_DELETESTRING = 0x0182;
|
||||||
|
const int LB_RESETCONTENT = 0x0184;
|
||||||
|
if (m.Msg == LB_RESETCONTENT)
|
||||||
|
{
|
||||||
|
ItemsClear?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.Msg == LB_DELETESTRING)
|
||||||
|
{
|
||||||
|
ItemsRemove?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.Msg == LB_ADDSTRING)
|
||||||
|
{
|
||||||
|
ItemsAdd?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.Msg == LB_INSERTSTRING)
|
||||||
|
{
|
||||||
|
ItemsInsert?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (m.Msg == Win32.User.WM_ERASEBKGND)
|
||||||
|
//{
|
||||||
|
// m.Result = IntPtr.Zero;
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.WndProc(ref m);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSizeChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
if (Bar != null && Bar.Visible)
|
||||||
|
{
|
||||||
|
if (Bar.Value != 0)
|
||||||
|
{
|
||||||
|
ScrollBarInfo.SetScrollValue(Handle, Bar.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SetScrollInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSelectedIndexChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnSelectedIndexChanged(e);
|
||||||
|
SetScrollInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetScrollInfo()
|
||||||
|
{
|
||||||
|
if (Bar == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var si = ScrollBarInfo.GetInfo(Handle);
|
||||||
|
if (si.ScrollMax > 0)
|
||||||
|
{
|
||||||
|
Bar.Maximum = si.ScrollMax;
|
||||||
|
Bar.Visible = si.ScrollMax > 0 && si.nMax > 0 && si.nPage > 0;
|
||||||
|
Bar.Value = si.nPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bar.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Version { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义主题风格
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(false)]
|
||||||
|
[Description("获取或设置可以自定义主题风格"), Category("SunnyUI")]
|
||||||
|
public bool StyleCustomMode { get; set; }
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// UIListBox
|
||||||
|
//
|
||||||
|
BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
DrawMode = DrawMode.OwnerDrawFixed;
|
||||||
|
Font = UIFontColor.Font();
|
||||||
|
IntegralHeight = false;
|
||||||
|
ItemHeight = 25;
|
||||||
|
Size = new Size(150, 200);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion 组件设计器生成的代码
|
||||||
|
|
||||||
|
private UIStyle _style = UIStyle.Blue;
|
||||||
|
private Color _itemSelectBackColor = UIColor.Blue;
|
||||||
|
private Color _itemSelectForeColor = Color.White;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主题样式
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(UIStyle.Blue), Description("主题样式"), Category("SunnyUI")]
|
||||||
|
public UIStyle Style
|
||||||
|
{
|
||||||
|
get => _style;
|
||||||
|
set => SetStyle(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseWheel(MouseEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseWheel(e);
|
||||||
|
|
||||||
|
if (Bar != null && Bar.Visible)
|
||||||
|
{
|
||||||
|
var si = ScrollBarInfo.GetInfo(Handle);
|
||||||
|
int temp = Math.Abs(e.Delta / 120);
|
||||||
|
if (e.Delta > 10)
|
||||||
|
{
|
||||||
|
int nposnum = si.nPos - temp * SystemInformation.MouseWheelScrollLines;
|
||||||
|
ScrollBarInfo.SetScrollValue(Handle, nposnum >= si.nMin ? nposnum : 0);
|
||||||
|
}
|
||||||
|
else if (e.Delta < -10)
|
||||||
|
{
|
||||||
|
int nposnum = si.nPos + temp * SystemInformation.MouseWheelScrollLines;
|
||||||
|
ScrollBarInfo.SetScrollValue(Handle, nposnum <= si.ScrollMax ? nposnum : si.ScrollMax);
|
||||||
|
}
|
||||||
|
SetScrollInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStyle(UIStyle style)
|
||||||
|
{
|
||||||
|
if (!style.IsCustom())
|
||||||
|
{
|
||||||
|
SetStyleColor(style.Colors());
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_style = style;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStyleColor(UIBaseStyle uiColor)
|
||||||
|
{
|
||||||
|
ItemSelectBackColor = uiColor.ListItemSelectBackColor;
|
||||||
|
ItemSelectForeColor = uiColor.ListItemSelectForeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("SunnyUI"), Description("The border color used to paint the control.")]
|
||||||
|
public Color ItemSelectBackColor
|
||||||
|
{
|
||||||
|
get => _itemSelectBackColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_itemSelectBackColor != value)
|
||||||
|
{
|
||||||
|
_itemSelectBackColor = value;
|
||||||
|
_style = UIStyle.Custom;
|
||||||
|
if (DesignMode)
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("SunnyUI"), Description("The border color used to paint the control.")]
|
||||||
|
public Color ItemSelectForeColor
|
||||||
|
{
|
||||||
|
get => _itemSelectForeColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_itemSelectForeColor != value)
|
||||||
|
{
|
||||||
|
_itemSelectForeColor = value;
|
||||||
|
_style = UIStyle.Custom;
|
||||||
|
if (DesignMode)
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void OnBeforeDrawItem(object sender, ObjectCollection items, DrawItemEventArgs e);
|
||||||
|
|
||||||
|
public event OnBeforeDrawItem BeforeDrawItem;
|
||||||
|
|
||||||
|
public event OnBeforeDrawItem AfterDrawItem;
|
||||||
|
|
||||||
|
private StringAlignment textAlignment = StringAlignment.Near;
|
||||||
|
|
||||||
|
public StringAlignment TextAlignment
|
||||||
|
{
|
||||||
|
get => textAlignment;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
textAlignment = value;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDrawItem(DrawItemEventArgs e)
|
||||||
|
{
|
||||||
|
BeforeDrawItem?.Invoke(this, Items, e);
|
||||||
|
if (Items.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool otherState = e.State == DrawItemState.Grayed || e.State == DrawItemState.HotLight;
|
||||||
|
if (!otherState)
|
||||||
|
{
|
||||||
|
e.DrawBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Index < 0 || e.Index >= Items.Count)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringFormat sStringFormat = new StringFormat();
|
||||||
|
sStringFormat.LineAlignment = StringAlignment.Center;
|
||||||
|
sStringFormat.Alignment = textAlignment;
|
||||||
|
|
||||||
|
bool isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
|
||||||
|
Color backColor = isSelected ? ItemSelectBackColor : BackColor;
|
||||||
|
Color foreColor = isSelected ? ItemSelectForeColor : ForeColor;
|
||||||
|
|
||||||
|
Rectangle rect = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1);
|
||||||
|
string showText = DisplayMember.IsNullOrEmpty() ? Items[e.Index].ToString() : GetItemText(Items[e.Index]);
|
||||||
|
|
||||||
|
if (!otherState)
|
||||||
|
{
|
||||||
|
e.Graphics.FillRectangle(BackColor, e.Bounds);
|
||||||
|
e.Graphics.FillRectangle(backColor, rect);
|
||||||
|
e.Graphics.DrawString(showText, e.Font, foreColor, e.Bounds, sStringFormat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (e.State == DrawItemState.Grayed)
|
||||||
|
{
|
||||||
|
backColor = BackColor;
|
||||||
|
foreColor = ForeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.State == DrawItemState.HotLight)
|
||||||
|
{
|
||||||
|
backColor = HoverColor;
|
||||||
|
foreColor = ForeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Graphics.FillRectangle(BackColor, e.Bounds);
|
||||||
|
e.Graphics.FillRectangle(backColor, rect);
|
||||||
|
e.Graphics.DrawString(showText, e.Font, foreColor, e.Bounds, sStringFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
AfterDrawItem?.Invoke(this, Items, e);
|
||||||
|
|
||||||
|
base.OnDrawItem(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color hoverColor = Color.FromArgb(155, 200, 255);
|
||||||
|
|
||||||
|
[DefaultValue(typeof(Color), "155, 200, 255")]
|
||||||
|
public Color HoverColor
|
||||||
|
{
|
||||||
|
get => hoverColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
hoverColor = value;
|
||||||
|
_style = UIStyle.Custom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMeasureItem(MeasureItemEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMeasureItem(e);
|
||||||
|
e.ItemHeight += ItemHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectedFirst()
|
||||||
|
{
|
||||||
|
if (Items.Count > 0 && SelectedIndex < 0)
|
||||||
|
{
|
||||||
|
SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int lastIndex = -1;
|
||||||
|
private int mouseIndex = -1;
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
|
public int MouseIndex
|
||||||
|
{
|
||||||
|
get => mouseIndex;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (mouseIndex != value)
|
||||||
|
{
|
||||||
|
if (lastIndex >= 0 && lastIndex >= 0 && lastIndex < Items.Count && lastIndex != SelectedIndex)
|
||||||
|
{
|
||||||
|
OnDrawItem(new DrawItemEventArgs(CreateGraphics(), Font, GetItemRectangle(lastIndex), lastIndex, DrawItemState.Grayed));
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseIndex = value;
|
||||||
|
if (mouseIndex >= 0 && mouseIndex >= 0 && mouseIndex < Items.Count && mouseIndex != SelectedIndex)
|
||||||
|
{
|
||||||
|
OnDrawItem(new DrawItemEventArgs(CreateGraphics(), Font, GetItemRectangle(value), value, DrawItemState.HotLight));
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIndex = mouseIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseMove(MouseEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseMove(e);
|
||||||
|
if (SelectionMode != SelectionMode.One) return;
|
||||||
|
MouseIndex = IndexFromPoint(e.Location);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseLeave(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseLeave(e);
|
||||||
|
if (SelectionMode != SelectionMode.One) return;
|
||||||
|
MouseIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user