* UIRadioButtonGroup: 重写UIRadioButtonGroup
This commit is contained in:
parent
0d86af2a23
commit
8ce0156d97
@ -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)
|
||||
/// <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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重载绘图
|
||||
/// </summary>
|
||||
@ -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<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;
|
||||
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<UIRadioButton> buttons = new List<UIRadioButton>();
|
||||
|
||||
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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user