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 _buttonBoxes = new List(); private ButtonBoxModel _currentButtonBox = null; private ButtonModel _currentButton = null; /// /// 获取单例实例 /// public static ButtonBoxManager Instance { get { if (_instance == null || _instance.IsDisposed) { lock (_lock) { if (_instance == null || _instance.IsDisposed) { _instance = new ButtonBoxManager(); } } } return _instance; } } /// /// 私有构造函数,确保单例模式 /// 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(); } /// /// 初始化触发状态下拉框 /// 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; } } /// /// 初始化类型下拉框 /// private void InitializeTypeComboBox() { comboBoxType.Items.Clear(); try { // 获取当前命名空间下所有继承自BasicButtonBox的类 // 跨程序集发现:按钮盒具体类型可能位于卫星插件 dll(StandardScene.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; /// /// 设置ListView的视觉样式 /// 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(); } } } /// /// 按钮盒ListView绘制项 /// 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(); } /// /// 按钮盒ListView绘制子项 /// 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); } /// /// 按钮盒ListView绘制列标题 /// 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); } /// /// 按钮ListView绘制项 /// 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(); } /// /// 按钮ListView绘制子项 /// 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); } /// /// 按钮ListView绘制列标题 /// 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); } /// /// 设置按钮的鼠标悬停效果 /// private void SetupButtonHoverEffects() { // 按钮的悬停效果现在通过FlatAppearance属性在Designer中设置 // 这里可以添加其他额外的效果,如工具提示等 } /// /// 刷新按钮盒列表 /// 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); } } /// /// 刷新按钮列表 /// 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); } } } /// /// 按钮盒列表选择改变 /// 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(); } } /// /// 按钮列表选择改变 /// 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(); } } /// /// 添加按钮盒 /// 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); } } /// /// 删除按钮盒 /// 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(); } } /// /// 保存按钮盒 /// 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); } } /// /// 添加按钮 /// 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); } } /// /// 删除按钮 /// 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(); } } /// /// 保存按钮 /// 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); } } /// /// 清空按钮盒字段 /// private void ClearButtonBoxFields() { textBoxIp.Text = string.Empty; textBoxPort.Text = string.Empty; textBoxBoxIndex.Text = string.Empty; comboBoxType.SelectedIndex = -1; } /// /// 清空按钮字段 /// 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; } /// /// 加载数据 /// private void LoadData() { try { if (File.Exists(_dataFilePath)) { var jsonContent = File.ReadAllText(_dataFilePath, Encoding.UTF8); if (!string.IsNullOrWhiteSpace(jsonContent)) { _buttonBoxes = jsonContent.JsonTo>(); if (_buttonBoxes == null) { _buttonBoxes = new List(); } } else { _buttonBoxes = new List(); } } else { _buttonBoxes = new List(); } } catch (Exception ex) { MessageBox.Show($"Load data failed: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); _buttonBoxes = new List(); } } /// /// 保存数据 /// 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); } } /// /// 验证IP地址格式 /// /// IP地址字符串 /// 如果格式正确返回true,否则返回false 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; } /// /// 窗体关闭事件 /// private void ButtonBoxManager_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing) { // 关闭前保存数据 SaveData(); e.Cancel = true; this.Visible = false; } } } }