Files
StandardSence/StandardScene.Core/ExtendDevice/ButtonBox/ButtonBoxManager.cs
T
2026-06-14 11:19:15 +08:00

1001 lines
37 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using StandardScene.Utils;
namespace StandardScene.ExtendDevice.ButtonBox
{
public partial class ButtonBoxManager : Form
{
private static ButtonBoxManager _instance = null;
private static readonly object _lock = new object();
private const string DataFileName = "ButtonBoxConfig.json";
private string _dataFilePath;
private List<ButtonBoxModel> _buttonBoxes = new List<ButtonBoxModel>();
private ButtonBoxModel _currentButtonBox = null;
private ButtonModel _currentButton = null;
/// <summary>
/// 获取单例实例
/// </summary>
public static ButtonBoxManager Instance
{
get
{
if (_instance == null || _instance.IsDisposed)
{
lock (_lock)
{
if (_instance == null || _instance.IsDisposed)
{
_instance = new ButtonBoxManager();
}
}
}
return _instance;
}
}
/// <summary>
/// 私有构造函数,确保单例模式
/// </summary>
private ButtonBoxManager()
{
InitializeComponent();
// 设置数据文件路径
_dataFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DataFileName);
}
private void ButtonBoxManager_Load(object sender, EventArgs e)
{
// 设置ListView的视觉样式
SetupListViewStyles();
// 设置按钮的鼠标悬停效果
SetupButtonHoverEffects();
// 初始化类型下拉框
InitializeTypeComboBox();
// 初始化触发状态下拉框
InitializeTriggerStateComboBox();
LoadData();
RefreshButtonBoxList();
}
/// <summary>
/// 初始化触发状态下拉框
/// </summary>
private void InitializeTriggerStateComboBox()
{
comboBoxTriggerState.Items.Clear();
// 添加ButtonState枚举的所有值
foreach (ButtonState state in Enum.GetValues(typeof(ButtonState)))
{
comboBoxTriggerState.Items.Add(state.ToString());
}
// 如果没有选中项,默认选择第一个
if (comboBoxTriggerState.Items.Count > 0 && comboBoxTriggerState.SelectedIndex == -1)
{
comboBoxTriggerState.SelectedIndex = 0;
}
}
/// <summary>
/// 初始化类型下拉框
/// </summary>
private void InitializeTypeComboBox()
{
comboBoxType.Items.Clear();
try
{
// 获取当前命名空间下所有继承自BasicButtonBox的类
// 跨程序集发现:按钮盒具体类型可能位于卫星插件 dllStandardScene.Devices.ButtonBox),
// 用内核同款全域类型发现替代仅扫当前程序集的 GetExecutingAssembly。
var buttonBoxTypes = SimpleLite.Utils.UiTypeDiscovery.AllTypes()
.Where(t => t.IsClass
&& !t.IsAbstract
&& t.Namespace == typeof(BasicButtonBox).Namespace
&& t.IsSubclassOf(typeof(BasicButtonBox)))
.OrderBy(t => t.Name)
.ToList();
foreach (var type in buttonBoxTypes)
{
comboBoxType.Items.Add(type.Name);
}
// 如果没有找到任何类型,添加默认选项
if (comboBoxType.Items.Count == 0)
{
comboBoxType.Items.Add("BasicButtonBox");
}
}
catch (Exception ex)
{
MessageBox.Show($"Failed to init type dropdown: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
comboBoxType.Items.Add("BasicButtonBox");
}
}
private int _buttonBoxHoverIndex = -1;
private int _buttonHoverIndex = -1;
/// <summary>
/// 设置ListView的视觉样式
/// </summary>
private void SetupListViewStyles()
{
SetupListView(buttonBoxListView,
ButtonBoxListView_DrawItem,
ButtonBoxListView_DrawSubItem,
ButtonBoxListView_DrawColumnHeader,
ButtonBoxListView_MouseMove,
ButtonBoxListView_MouseLeave);
SetupListView(buttonListView,
ButtonListView_DrawItem,
ButtonListView_DrawSubItem,
ButtonListView_DrawColumnHeader,
ButtonListView_MouseMove,
ButtonListView_MouseLeave);
}
private void SetupListView(ListView listView,
DrawListViewItemEventHandler itemHandler,
DrawListViewSubItemEventHandler subItemHandler,
DrawListViewColumnHeaderEventHandler headerHandler,
MouseEventHandler mouseMoveHandler,
EventHandler mouseLeaveHandler)
{
listView.OwnerDraw = true;
listView.BackColor = Color.White;
listView.DrawItem += itemHandler;
listView.DrawSubItem += subItemHandler;
listView.DrawColumnHeader += headerHandler;
listView.MouseMove += mouseMoveHandler;
listView.MouseLeave += mouseLeaveHandler;
// 启用双缓冲,防止重绘时的灰色覆盖
typeof(Control)?.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic)?
.SetValue(listView, true, null);
}
private static readonly Color RowEvenColor = Color.FromArgb(250, 250, 252);
private static readonly Color RowOddColor = Color.White;
private static readonly Color RowHighlightColor = Color.FromArgb(230, 240, 255);
private static readonly Color TextRegularColor = Color.FromArgb(68, 68, 68);
private static readonly Color TextHighlightColor = Color.FromArgb(51, 51, 51);
private void ButtonBoxListView_MouseMove(object sender, MouseEventArgs e)
{
UpdateHoverIndex(buttonBoxListView, e, true);
}
private void ButtonBoxListView_MouseLeave(object sender, EventArgs e)
{
ResetHoverIndex(buttonBoxListView, true);
}
private void ButtonListView_MouseMove(object sender, MouseEventArgs e)
{
UpdateHoverIndex(buttonListView, e, false);
}
private void ButtonListView_MouseLeave(object sender, EventArgs e)
{
ResetHoverIndex(buttonListView, false);
}
private void UpdateHoverIndex(ListView listView, MouseEventArgs e, bool isButtonBoxList)
{
var hoveredItem = listView.GetItemAt(e.X, e.Y);
int newIndex = hoveredItem?.Index ?? -1;
if (isButtonBoxList)
{
if (_buttonBoxHoverIndex != newIndex)
{
_buttonBoxHoverIndex = newIndex;
listView.Invalidate();
}
}
else
{
if (_buttonHoverIndex != newIndex)
{
_buttonHoverIndex = newIndex;
listView.Invalidate();
}
}
}
private void ResetHoverIndex(ListView listView, bool isButtonBoxList)
{
if (isButtonBoxList)
{
if (_buttonBoxHoverIndex != -1)
{
_buttonBoxHoverIndex = -1;
listView.Invalidate();
}
}
else
{
if (_buttonHoverIndex != -1)
{
_buttonHoverIndex = -1;
listView.Invalidate();
}
}
}
/// <summary>
/// 按钮盒ListView绘制项
/// </summary>
private void ButtonBoxListView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
var isHighlighted = e.Item.Selected
|| e.ItemIndex == _buttonBoxHoverIndex
|| (e.State & ListViewItemStates.Focused) != 0;
var backColor = isHighlighted
? RowHighlightColor
: (e.ItemIndex % 2 == 0 ? RowEvenColor : RowOddColor);
using (var brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Bounds);
}
var textColor = isHighlighted ? TextHighlightColor : TextRegularColor;
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, e.Bounds,
textColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis);
e.DrawFocusRectangle();
}
/// <summary>
/// 按钮盒ListView绘制子项
/// </summary>
private void ButtonBoxListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
var isHighlighted = e.Item.Selected
|| e.ItemIndex == _buttonBoxHoverIndex
|| (e.ItemState & ListViewItemStates.Focused) != 0;
var backColor = isHighlighted
? RowHighlightColor
: (e.ItemIndex % 2 == 0 ? RowEvenColor : RowOddColor);
using (var brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Bounds);
}
var textColor = isHighlighted ? TextHighlightColor : TextRegularColor;
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.SubItem.Font, e.Bounds,
textColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis);
}
/// <summary>
/// 按钮盒ListView绘制列标题
/// </summary>
private void ButtonBoxListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
// 绘制列标题背景
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(245, 247, 250)), e.Bounds);
// 绘制边框
e.Graphics.DrawLine(new Pen(Color.FromArgb(220, 220, 220)),
e.Bounds.Left, e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1);
// 绘制文本
TextRenderer.DrawText(e.Graphics, e.Header.Text,
new Font("微软雅黑", 10.5F, FontStyle.Bold),
e.Bounds, Color.FromArgb(68, 68, 68),
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.HorizontalCenter);
}
/// <summary>
/// 按钮ListView绘制项
/// </summary>
private void ButtonListView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
var isHighlighted = e.Item.Selected
|| e.ItemIndex == _buttonHoverIndex
|| (e.State & ListViewItemStates.Focused) != 0;
var backColor = isHighlighted
? RowHighlightColor
: (e.ItemIndex % 2 == 0 ? RowEvenColor : RowOddColor);
using (var brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Bounds);
}
var textColor = isHighlighted ? TextHighlightColor : TextRegularColor;
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, e.Bounds,
textColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis);
e.DrawFocusRectangle();
}
/// <summary>
/// 按钮ListView绘制子项
/// </summary>
private void ButtonListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
var isHighlighted = e.Item.Selected
|| e.ItemIndex == _buttonHoverIndex
|| (e.ItemState & ListViewItemStates.Focused) != 0;
var backColor = isHighlighted
? RowHighlightColor
: (e.ItemIndex % 2 == 0 ? RowEvenColor : RowOddColor);
using (var brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Bounds);
}
var textColor = isHighlighted ? TextHighlightColor : TextRegularColor;
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.SubItem.Font, e.Bounds,
textColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis);
}
/// <summary>
/// 按钮ListView绘制列标题
/// </summary>
private void ButtonListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
// 绘制列标题背景
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(245, 247, 250)), e.Bounds);
// 绘制边框
e.Graphics.DrawLine(new Pen(Color.FromArgb(220, 220, 220)),
e.Bounds.Left, e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1);
// 绘制文本
TextRenderer.DrawText(e.Graphics, e.Header.Text,
new Font("微软雅黑", 10.5F, FontStyle.Bold),
e.Bounds, Color.FromArgb(68, 68, 68),
TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.HorizontalCenter);
}
/// <summary>
/// 设置按钮的鼠标悬停效果
/// </summary>
private void SetupButtonHoverEffects()
{
// 按钮的悬停效果现在通过FlatAppearance属性在Designer中设置
// 这里可以添加其他额外的效果,如工具提示等
}
/// <summary>
/// 刷新按钮盒列表
/// </summary>
private void RefreshButtonBoxList()
{
buttonBoxListView.Items.Clear();
foreach (var box in _buttonBoxes)
{
var item = new ListViewItem(box.Index.ToString());
item.SubItems.Add(box.Ip);
item.SubItems.Add(box.Port.ToString());
item.SubItems.Add(box.Type);
item.Tag = box;
item.UseItemStyleForSubItems = false;
buttonBoxListView.Items.Add(item);
}
}
/// <summary>
/// 刷新按钮列表
/// </summary>
private void RefreshButtonList()
{
buttonListView.Items.Clear();
if (_currentButtonBox != null)
{
foreach (var button in _currentButtonBox.Buttons)
{
var item = new ListViewItem(button.Index.ToString());
item.SubItems.Add(button.TriggerState);
item.SubItems.Add(button.TriggerDelay.ToString());
item.SubItems.Add(button.TriggerMission);
item.SubItems.Add(button.TriggerMethod);
item.SubItems.Add(button.TriggerMethodParams);
item.Tag = button;
item.UseItemStyleForSubItems = false;
buttonListView.Items.Add(item);
}
}
}
/// <summary>
/// 按钮盒列表选择改变
/// </summary>
private void buttonBoxListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (buttonBoxListView.SelectedItems.Count > 0)
{
_currentButtonBox = buttonBoxListView.SelectedItems[0].Tag as ButtonBoxModel;
if (_currentButtonBox != null)
{
// 填充按钮盒编辑区域
textBoxIp.Text = _currentButtonBox.Ip;
textBoxPort.Text = _currentButtonBox.Port.ToString();
textBoxBoxIndex.Text = _currentButtonBox.Index.ToString();
// 设置类型下拉框
if (comboBoxType.Items.Contains(_currentButtonBox.Type))
{
comboBoxType.SelectedItem = _currentButtonBox.Type;
}
else
{
comboBoxType.SelectedIndex = comboBoxType.Items.Count > 0 ? 0 : -1;
}
// 刷新按钮列表
RefreshButtonList();
}
}
else
{
_currentButtonBox = null;
ClearButtonBoxFields();
buttonListView.Items.Clear();
}
}
/// <summary>
/// 按钮列表选择改变
/// </summary>
private void buttonListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (buttonListView.SelectedItems.Count > 0)
{
_currentButton = buttonListView.SelectedItems[0].Tag as ButtonModel;
if (_currentButton != null)
{
// 填充按钮编辑区域
textBoxButtonIndex.Text = _currentButton.Index.ToString();
textBoxTriggerMission.Text = _currentButton.TriggerMission;
textBoxTriggerMethod.Text = _currentButton.TriggerMethod;
textBoxTriggerMethodParams.Text = _currentButton.TriggerMethodParams;
// 设置触发状态下拉框
if (comboBoxTriggerState.Items.Contains(_currentButton.TriggerState))
{
comboBoxTriggerState.SelectedItem = _currentButton.TriggerState;
}
else
{
comboBoxTriggerState.SelectedIndex = comboBoxTriggerState.Items.Count > 0 ? 0 : -1;
}
textBoxTriggerDelay.Text = _currentButton.TriggerDelay.ToString();
}
}
else
{
_currentButton = null;
ClearButtonFields();
}
}
/// <summary>
/// 添加按钮盒
/// </summary>
private void btnAddButtonBox_Click(object sender, EventArgs e)
{
try
{
// 获取输入框的值
string ip = textBoxIp.Text.Trim();
string portText = textBoxPort.Text.Trim();
string indexText = textBoxBoxIndex.Text.Trim();
string type = comboBoxType.SelectedItem?.ToString() ?? string.Empty;
// 确定要使用的值:如果输入框不为空则使用输入值,否则使用默认值
int newIndex;
if (!string.IsNullOrWhiteSpace(indexText))
{
if (!int.TryParse(indexText, out newIndex))
{
MessageBox.Show("Index must be numeric", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{
newIndex = _buttonBoxes.Count > 0 ? _buttonBoxes.Max(b => b.Index) + 1 : 1;
}
string newIp;
if (!string.IsNullOrWhiteSpace(ip))
{
// 验证IP地址格式
if (!IsValidIpAddress(ip))
{
MessageBox.Show("Invalid IP address, e.g. 192.168.1.100", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
newIp = ip;
}
else
{
newIp = "192.168.1.100";
}
int newPort;
if (!string.IsNullOrWhiteSpace(portText))
{
if (!int.TryParse(portText, out newPort))
{
MessageBox.Show("Port must be numeric", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{
newPort = 502;
}
string newType;
if (!string.IsNullOrWhiteSpace(type))
{
newType = type;
}
else
{
// 如果下拉框有选项,使用第一个选项作为默认值
newType = comboBoxType.Items.Count > 0 ? comboBoxType.Items[0].ToString() : "BasicButtonBox";
}
// 检查编码是否重复
if (_buttonBoxes.Any(b => b.Index == newIndex))
{
MessageBox.Show($"Index {newIndex} already exists, use another", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 检查IP地址是否重复
if (_buttonBoxes.Any(b => b.Ip == newIp))
{
MessageBox.Show($"IP {newIp} already exists, use another", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var newBox = new ButtonBoxModel
{
Index = newIndex,
Ip = newIp,
Port = newPort,
Type = newType
};
_buttonBoxes.Add(newBox);
RefreshButtonBoxList();
SaveData();
// 选中新添加的按钮盒
foreach (ListViewItem item in buttonBoxListView.Items)
{
if (item.Tag == newBox)
{
item.Selected = true;
item.EnsureVisible();
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Failed to add button box: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 删除按钮盒
/// </summary>
private void btnDeleteButtonBox_Click(object sender, EventArgs e)
{
if (_currentButtonBox == null)
{
MessageBox.Show("Please select a button box to delete", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
var result = MessageBox.Show($"Delete button box with index {_currentButtonBox.Index}?", "Confirm delete",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
_buttonBoxes.Remove(_currentButtonBox);
_currentButtonBox = null;
ClearButtonBoxFields();
RefreshButtonBoxList();
buttonListView.Items.Clear();
SaveData();
}
}
/// <summary>
/// 保存按钮盒
/// </summary>
private void btnSaveButtonBox_Click(object sender, EventArgs e)
{
if (_currentButtonBox == null)
{
MessageBox.Show("Please select a button box to save", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
try
{
string newIp = textBoxIp.Text.Trim();
// 验证IP地址格式
if (!IsValidIpAddress(newIp))
{
MessageBox.Show("Invalid IP address, e.g. 192.168.1.100", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (!int.TryParse(textBoxPort.Text, out int port))
{
MessageBox.Show("Port must be numeric", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_currentButtonBox.Port = port;
if (!int.TryParse(textBoxBoxIndex.Text, out int index))
{
MessageBox.Show("Index must be numeric", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 检查编码是否重复(排除当前项)
if (_buttonBoxes.Any(b => b.Index == index && b != _currentButtonBox))
{
MessageBox.Show($"Index {index} already exists, use another", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 检查IP地址是否重复(排除当前项)
if (_buttonBoxes.Any(b => b.Ip == newIp && b != _currentButtonBox))
{
MessageBox.Show($"IP {newIp} already exists, use another", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_currentButtonBox.Index = index;
_currentButtonBox.Type = comboBoxType.SelectedItem?.ToString() ?? string.Empty;
_currentButtonBox.Ip = newIp;
RefreshButtonBoxList();
SaveData();
MessageBox.Show("Saved", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Save failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 添加按钮
/// </summary>
private void btnAddButton_Click(object sender, EventArgs e)
{
if (_currentButtonBox == null)
{
MessageBox.Show("Please select a button box first", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
try
{
// 获取输入框的值
string indexText = textBoxButtonIndex.Text.Trim();
string triggerMission = textBoxTriggerMission.Text.Trim();
string triggerMethod = textBoxTriggerMethod.Text.Trim();
string triggerMethodParams = textBoxTriggerMethodParams.Text.Trim();
string triggerState = comboBoxTriggerState.SelectedItem?.ToString() ?? string.Empty;
string triggerDelayText = textBoxTriggerDelay.Text.Trim();
// 确定要使用的值:如果输入框不为空则使用输入值,否则使用默认值
int newIndex;
if (!string.IsNullOrWhiteSpace(indexText))
{
if (!int.TryParse(indexText, out newIndex))
{
MessageBox.Show("Button index must be numeric", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{
newIndex = _currentButtonBox.Buttons.Count > 0
? _currentButtonBox.Buttons.Max(b => b.Index) + 1
: 1;
}
// 检查按钮编码是否重复
if (_currentButtonBox.Buttons.Any(b => b.Index == newIndex))
{
MessageBox.Show($"Button index {newIndex} already exists, use another", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 解析触发延迟(必须是ushort类型,范围0-65535
ushort triggerDelay = 0;
if (!string.IsNullOrWhiteSpace(triggerDelayText))
{
if (!ushort.TryParse(triggerDelayText, out triggerDelay))
{
MessageBox.Show("Trigger delay must be 0-65535", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
var newButton = new ButtonModel
{
Index = newIndex,
TriggerMission = triggerMission,
TriggerMethod = triggerMethod,
TriggerMethodParams = triggerMethodParams,
TriggerState = triggerState,
TriggerDelay = triggerDelay
};
_currentButtonBox.Buttons.Add(newButton);
RefreshButtonList();
SaveData();
// 选中新添加的按钮
foreach (ListViewItem item in buttonListView.Items)
{
if (item.Tag == newButton)
{
item.Selected = true;
item.EnsureVisible();
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Failed to add button: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 删除按钮
/// </summary>
private void btnDeleteButton_Click(object sender, EventArgs e)
{
if (_currentButtonBox == null)
{
MessageBox.Show("Please select a button box first", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (_currentButton == null)
{
MessageBox.Show("Please select a button to delete", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
var result = MessageBox.Show($"Delete button with index {_currentButton.Index}?", "Confirm delete",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
_currentButtonBox.Buttons.Remove(_currentButton);
_currentButton = null;
ClearButtonFields();
RefreshButtonList();
SaveData();
}
}
/// <summary>
/// 保存按钮
/// </summary>
private void btnSaveButton_Click(object sender, EventArgs e)
{
if (_currentButtonBox == null)
{
MessageBox.Show("Please select a button box first", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (_currentButton == null)
{
MessageBox.Show("Please select a button to save", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
try
{
if (!int.TryParse(textBoxButtonIndex.Text, out int index))
{
MessageBox.Show("Button index must be numeric", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 检查按钮编码是否重复(排除当前按钮)
if (_currentButtonBox.Buttons.Any(b => b.Index == index && b != _currentButton))
{
MessageBox.Show($"Button index {index} already exists, use another", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 验证触发延迟(必须是ushort类型,范围0-65535
if (!ushort.TryParse(textBoxTriggerDelay.Text, out ushort triggerDelay))
{
MessageBox.Show("Trigger delay must be 0-65535", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_currentButton.Index = index;
_currentButton.TriggerMission = textBoxTriggerMission.Text;
_currentButton.TriggerMethod = textBoxTriggerMethod.Text;
_currentButton.TriggerMethodParams = textBoxTriggerMethodParams.Text;
_currentButton.TriggerState = comboBoxTriggerState.SelectedItem?.ToString() ?? string.Empty;
_currentButton.TriggerDelay = triggerDelay;
RefreshButtonList();
SaveData();
MessageBox.Show("Saved", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Save failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 清空按钮盒字段
/// </summary>
private void ClearButtonBoxFields()
{
textBoxIp.Text = string.Empty;
textBoxPort.Text = string.Empty;
textBoxBoxIndex.Text = string.Empty;
comboBoxType.SelectedIndex = -1;
}
/// <summary>
/// 清空按钮字段
/// </summary>
private void ClearButtonFields()
{
textBoxButtonIndex.Text = string.Empty;
textBoxTriggerMission.Text = string.Empty;
textBoxTriggerMethod.Text = string.Empty;
textBoxTriggerMethodParams.Text = string.Empty;
comboBoxTriggerState.SelectedIndex = comboBoxTriggerState.Items.Count > 0 ? 0 : -1;
textBoxTriggerDelay.Text = string.Empty;
}
/// <summary>
/// 加载数据
/// </summary>
private void LoadData()
{
try
{
if (File.Exists(_dataFilePath))
{
var jsonContent = File.ReadAllText(_dataFilePath, Encoding.UTF8);
if (!string.IsNullOrWhiteSpace(jsonContent))
{
_buttonBoxes = jsonContent.JsonTo<List<ButtonBoxModel>>();
if (_buttonBoxes == null)
{
_buttonBoxes = new List<ButtonBoxModel>();
}
}
else
{
_buttonBoxes = new List<ButtonBoxModel>();
}
}
else
{
_buttonBoxes = new List<ButtonBoxModel>();
}
}
catch (Exception ex)
{
MessageBox.Show($"Load data failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
_buttonBoxes = new List<ButtonBoxModel>();
}
}
/// <summary>
/// 保存数据
/// </summary>
private void SaveData()
{
try
{
var jsonContent = _buttonBoxes.ToJson();
File.WriteAllText(_dataFilePath, jsonContent, Encoding.UTF8);
}
catch (Exception ex)
{
MessageBox.Show($"Save data failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 验证IP地址格式
/// </summary>
/// <param name="ipAddress">IP地址字符串</param>
/// <returns>如果格式正确返回true,否则返回false</returns>
private bool IsValidIpAddress(string ipAddress)
{
if (string.IsNullOrWhiteSpace(ipAddress))
{
return false;
}
// 使用正则表达式验证IP地址格式(IPv4)
string pattern = @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
if (Regex.IsMatch(ipAddress, pattern))
{
// 使用System.Net.IPAddress.TryParse进行二次验证
IPAddress address;
return IPAddress.TryParse(ipAddress, out address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork;
}
return false;
}
/// <summary>
/// 窗体关闭事件
/// </summary>
private void ButtonBoxManager_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
// 关闭前保存数据
SaveData();
e.Cancel = true;
this.Visible = false;
}
}
}
}