diff --git a/SunnyUI/Controls/UIRadioButtonGroup.cs b/SunnyUI/Controls/UIRadioButtonGroup.cs
index 20e432e3..d8f70d91 100644
--- a/SunnyUI/Controls/UIRadioButtonGroup.cs
+++ b/SunnyUI/Controls/UIRadioButtonGroup.cs
@@ -23,6 +23,7 @@
* 2022-11-21: V3.2.9 修复未显示时切换节点文本为空的问题
* 2023-04-22: V3.3.5 设置选择项ForeColor
* 2023-06-27: V3.3.9 内置条目关联值由Tag改为TagString
+ * 2023-11-09: V3.5.2 重写UIRadioButtonGroup
******************************************************************************/
using System;
@@ -45,18 +46,38 @@ namespace Sunny.UI
public UIRadioButtonGroup()
{
items.CountChange += Items_CountChange;
+ ForeColor = UIStyles.Blue.CheckBoxForeColor;
+ checkBoxColor = UIStyles.Blue.CheckBoxColor;
+ hoverColor = UIStyles.Blue.ListItemHoverColor;
}
- protected override void OnFontChanged(EventArgs e)
- {
- base.OnFontChanged(e);
+ private Color checkBoxColor;
+ private Color hoverColor;
- if (DefaultFontSize < 0)
+ ///
+ /// 设置主题样式
+ ///
+ /// 主题样式
+ public override void SetStyleColor(UIBaseStyle uiColor)
+ {
+ base.SetStyleColor(uiColor);
+ checkBoxColor = uiColor.CheckBoxColor;
+ ForeColor = uiColor.CheckBoxForeColor;
+ hoverColor = uiColor.ListItemHoverColor;
+ }
+
+ ///
+ /// 填充颜色,当值为背景色或透明色或空值则不填充
+ ///
+ [Description("填充颜色"), Category("SunnyUI")]
+ [DefaultValue(typeof(Color), "80, 160, 255")]
+ public Color RadioButtonColor
+ {
+ get => checkBoxColor;
+ set
{
- foreach (var item in buttons)
- {
- item.Font = Font;
- }
+ checkBoxColor = value;
+ Invalidate();
}
}
@@ -65,28 +86,12 @@ namespace Sunny.UI
Invalidate();
}
- ~UIRadioButtonGroup()
- {
- ClearButtons();
- }
-
- private void ClearButtons()
- {
- foreach (var button in buttons)
- {
- button.Hide();
- button.Dispose();
- }
-
- buttons.Clear();
- }
-
public void Clear()
{
Items.Clear();
- ClearButtons();
SelectedIndex = -1;
Invalidate();
+ ValueChanged(this, -1, "");
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
@@ -98,42 +103,6 @@ namespace Sunny.UI
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;
- }
- }
-
///
/// 重载绘图
///
@@ -142,30 +111,124 @@ namespace Sunny.UI
{
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 startY = TitleTop + StartPos.Y;
+
for (int i = 0; i < Items.Count; i++)
{
- buttons[i].Text = Items[i].ToString();
-
+ string text = Items[i].ToString();
int rowIndex = 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 CheckStates = new Dictionary();
+ private Dictionary CheckBoxRects = new Dictionary();
+
+ int activeIndex = -1;
+ private int _imageSize = 16;
+
+ [DefaultValue(16)]
+ [Description("图标大小"), Category("SunnyUI")]
+ [Browsable(false)]
+ public int RadioButtonSize
{
- UIRadioButton button = (UIRadioButton)sender;
- if (value)
+ get => _imageSize;
+ 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;
set
{
- if (buttons.Count != Items.Count)
- {
- CreateBoxes();
- }
-
if (Items.Count == 0)
{
selectedIndex = -1;
@@ -191,28 +249,13 @@ namespace Sunny.UI
if (SelectedIndex != value)
{
- if (value >= 0 && value < buttons.Count)
- {
- selectedIndex = value;
- buttons[value].Checked = true;
- ValueChanged?.Invoke(this, value, buttons[value].Text);
- }
+ selectedIndex = value;
+ Invalidate();
+ ValueChanged?.Invoke(this, value, items.ContainsIndex(value) ? items[value].ToString() : "");
}
}
}
- public void SelectedNone()
- {
- foreach (var button in buttons)
- {
- button.Checked = false;
- }
-
- selectedIndex = -1;
- }
-
- private readonly List buttons = new List();
-
private int columnCount = 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")]
public Size ItemSize
{
@@ -255,9 +298,9 @@ namespace Sunny.UI
}
}
- public int columnInterval;
+ public int columnInterval = 6;
- [DefaultValue(0)]
+ [DefaultValue(6)]
[Description("显示列间隔"), Category("SunnyUI")]
public int ColumnInterval
{
@@ -269,9 +312,9 @@ namespace Sunny.UI
}
}
- private int rowInterval;
+ private int rowInterval = 2;
- [DefaultValue(0)]
+ [DefaultValue(2)]
[Description("显示行间隔"), Category("SunnyUI")]
public int RowInterval
{