* UIRadioButtonGroup: 重写UIRadioButtonGroup

This commit is contained in:
Sunny 2023-11-09 13:52:19 +08:00
parent 0d86af2a23
commit 8ce0156d97

View File

@ -23,6 +23,7 @@
* 2022-11-21: V3.2.9 * 2022-11-21: V3.2.9
* 2023-04-22: V3.3.5 ForeColor * 2023-04-22: V3.3.5 ForeColor
* 2023-06-27: V3.3.9 Tag改为TagString * 2023-06-27: V3.3.9 Tag改为TagString
* 2023-11-09: V3.5.2 UIRadioButtonGroup
******************************************************************************/ ******************************************************************************/
using System; using System;
@ -45,18 +46,38 @@ namespace Sunny.UI
public UIRadioButtonGroup() public UIRadioButtonGroup()
{ {
items.CountChange += Items_CountChange; items.CountChange += Items_CountChange;
ForeColor = UIStyles.Blue.CheckBoxForeColor;
checkBoxColor = UIStyles.Blue.CheckBoxColor;
hoverColor = UIStyles.Blue.ListItemHoverColor;
} }
protected override void OnFontChanged(EventArgs e) private Color checkBoxColor;
{ private Color hoverColor;
base.OnFontChanged(e);
if (DefaultFontSize < 0) /// <summary>
/// 设置主题样式
/// </summary>
/// <param name="uiColor">主题样式</param>
public override void SetStyleColor(UIBaseStyle uiColor)
{
base.SetStyleColor(uiColor);
checkBoxColor = uiColor.CheckBoxColor;
ForeColor = uiColor.CheckBoxForeColor;
hoverColor = uiColor.ListItemHoverColor;
}
/// <summary>
/// 填充颜色,当值为背景色或透明色或空值则不填充
/// </summary>
[Description("填充颜色"), Category("SunnyUI")]
[DefaultValue(typeof(Color), "80, 160, 255")]
public Color RadioButtonColor
{
get => checkBoxColor;
set
{ {
foreach (var item in buttons) checkBoxColor = value;
{ Invalidate();
item.Font = Font;
}
} }
} }
@ -65,28 +86,12 @@ namespace Sunny.UI
Invalidate(); Invalidate();
} }
~UIRadioButtonGroup()
{
ClearButtons();
}
private void ClearButtons()
{
foreach (var button in buttons)
{
button.Hide();
button.Dispose();
}
buttons.Clear();
}
public void Clear() public void Clear()
{ {
Items.Clear(); Items.Clear();
ClearButtons();
SelectedIndex = -1; SelectedIndex = -1;
Invalidate(); Invalidate();
ValueChanged(this, -1, "");
} }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
@ -98,42 +103,6 @@ namespace Sunny.UI
private readonly UIObjectCollection items = new UIObjectCollection(); private readonly UIObjectCollection items = new UIObjectCollection();
private void CreateBoxes()
{
if (Items.Count == 0) return;
if (Items.Count != buttons.Count)
{
ClearButtons();
for (int i = 0; i < Items.Count; i++)
{
UIRadioButton button = new UIRadioButton
{
BackColor = Color.Transparent,
Font = Font,
Parent = this,
TagString = i.ToString(),
Style = Style,
Text = Items[i]?.ToString(),
StyleCustomMode = StyleCustomMode,
ForeColor = ForeColor
};
button.ValueChanged += Button_ValueChanged;
buttons.Add(button);
}
}
}
protected override void AfterSetForeColor(Color color)
{
base.AfterSetForeColor(color);
foreach (var item in buttons)
{
item.ForeColor = color;
}
}
/// <summary> /// <summary>
/// 重载绘图 /// 重载绘图
/// </summary> /// </summary>
@ -142,30 +111,124 @@ namespace Sunny.UI
{ {
base.OnPaint(e); base.OnPaint(e);
CreateBoxes(); if (Items.Count == 0) return;
if (activeIndex >= 0 && CheckBoxRects.ContainsKey(activeIndex))
{
e.Graphics.FillRectangle(hoverColor, CheckBoxRects[activeIndex]);
}
int startX = StartPos.X; int startX = StartPos.X;
int startY = TitleTop + StartPos.Y; int startY = TitleTop + StartPos.Y;
for (int i = 0; i < Items.Count; i++) for (int i = 0; i < Items.Count; i++)
{ {
buttons[i].Text = Items[i].ToString(); string text = Items[i].ToString();
int rowIndex = i / ColumnCount; int rowIndex = i / ColumnCount;
int columnIndex = i % ColumnCount; int columnIndex = i % ColumnCount;
int left = startX + ItemSize.Width * columnIndex + ColumnInterval * columnIndex;
int top = startY + ItemSize.Height * rowIndex + RowInterval * rowIndex;
Rectangle rect = new Rectangle(left, top, ItemSize.Width, ItemSize.Height);
if (CheckBoxRects.NotContainsKey(i))
CheckBoxRects.Add(i, rect);
else
CheckBoxRects[i] = rect;
int ImageSize = RadioButtonSize;
//图标
top = rect.Top + (rect.Height - ImageSize) / 2;
left = rect.Left + 6;
Color color = Enabled ? checkBoxColor : foreDisableColor;
if (SelectedIndex == i)
{
e.Graphics.FillEllipse(color, left, top, ImageSize, ImageSize);
float pointSize = ImageSize - 4;
e.Graphics.FillEllipse(BackColor.IsValid() ? BackColor : Color.White,
left + ImageSize / 2.0f - pointSize / 2.0f,
top + ImageSize / 2.0f - pointSize / 2.0f,
pointSize, pointSize);
pointSize = ImageSize - 8;
e.Graphics.FillEllipse(color,
left + ImageSize / 2.0f - pointSize / 2.0f,
top + ImageSize / 2.0f - pointSize / 2.0f,
pointSize, pointSize);
}
else
{
using Pen pn = new Pen(color, 2);
e.Graphics.SetHighQuality();
e.Graphics.DrawEllipse(pn, left + 1, top + 1, ImageSize - 2, ImageSize - 2);
e.Graphics.SetDefaultQuality();
}
e.Graphics.DrawString(text, Font, ForeColor, rect, ContentAlignment.MiddleLeft, ImageSize + 10, 0);
buttons[i].Left = startX + ItemSize.Width * columnIndex + ColumnInterval * columnIndex;
buttons[i].Top = startY + ItemSize.Height * rowIndex + RowInterval * rowIndex;
buttons[i].Size = ItemSize;
buttons[i].Show();
} }
} }
private void Button_ValueChanged(object sender, bool value) private Dictionary<int, bool> CheckStates = new Dictionary<int, bool>();
private Dictionary<int, Rectangle> CheckBoxRects = new Dictionary<int, Rectangle>();
int activeIndex = -1;
private int _imageSize = 16;
[DefaultValue(16)]
[Description("图标大小"), Category("SunnyUI")]
[Browsable(false)]
public int RadioButtonSize
{ {
UIRadioButton button = (UIRadioButton)sender; get => _imageSize;
if (value) set
{ {
SelectedIndex = button.TagString.ToInt(); _imageSize = Math.Max(value, 16);
_imageSize = Math.Min(value, 64);
Invalidate();
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
int index = -1;
foreach (var item in CheckBoxRects)
{
if (e.Location.InRect(item.Value))
{
index = item.Key;
break;
}
}
if (activeIndex != index)
{
activeIndex = index;
Invalidate();
}
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
activeIndex = -1;
Invalidate();
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
foreach (var pair in CheckBoxRects)
{
if (e.Location.InRect(pair.Value) && pair.Key >= 0 && pair.Key < items.Count)
{
SelectedIndex = pair.Key;
Invalidate();
}
} }
} }
@ -178,11 +241,6 @@ namespace Sunny.UI
get => selectedIndex; get => selectedIndex;
set set
{ {
if (buttons.Count != Items.Count)
{
CreateBoxes();
}
if (Items.Count == 0) if (Items.Count == 0)
{ {
selectedIndex = -1; selectedIndex = -1;
@ -191,28 +249,13 @@ namespace Sunny.UI
if (SelectedIndex != value) if (SelectedIndex != value)
{ {
if (value >= 0 && value < buttons.Count) selectedIndex = value;
{ Invalidate();
selectedIndex = value; ValueChanged?.Invoke(this, value, items.ContainsIndex(value) ? items[value].ToString() : "");
buttons[value].Checked = true;
ValueChanged?.Invoke(this, value, buttons[value].Text);
}
} }
} }
} }
public void SelectedNone()
{
foreach (var button in buttons)
{
button.Checked = false;
}
selectedIndex = -1;
}
private readonly List<UIRadioButton> buttons = new List<UIRadioButton>();
private int columnCount = 1; private int columnCount = 1;
[DefaultValue(1)] [DefaultValue(1)]
@ -227,9 +270,9 @@ namespace Sunny.UI
} }
} }
private Size itemSize = new Size(150, 35); private Size itemSize = new Size(150, 29);
[DefaultValue(typeof(Size), "150, 35")] [DefaultValue(typeof(Size), "150, 29")]
[Description("列表项大小"), Category("SunnyUI")] [Description("列表项大小"), Category("SunnyUI")]
public Size ItemSize public Size ItemSize
{ {
@ -255,9 +298,9 @@ namespace Sunny.UI
} }
} }
public int columnInterval; public int columnInterval = 6;
[DefaultValue(0)] [DefaultValue(6)]
[Description("显示列间隔"), Category("SunnyUI")] [Description("显示列间隔"), Category("SunnyUI")]
public int ColumnInterval public int ColumnInterval
{ {
@ -269,9 +312,9 @@ namespace Sunny.UI
} }
} }
private int rowInterval; private int rowInterval = 2;
[DefaultValue(0)] [DefaultValue(2)]
[Description("显示行间隔"), Category("SunnyUI")] [Description("显示行间隔"), Category("SunnyUI")]
public int RowInterval public int RowInterval
{ {