System.Collections.Specialized Namespace

本文详细介绍了System.Collections.Specialized命名空间中的各种集合类,包括它们的特性与应用场景,如HybridDictionary、ListDictionary等,以及如何使用这些集合来提高代码效率。

System.Collections.Specialized 命名空间包含专用的和强类型的集合,例如,链接的列表词典、位向量以及只包含字符串的集合。

名称说明
CollectionChangedEventManager提供 WeakEventManager 实现,以便可以使用“弱事件侦听器”模式附加 CollectionChanged 事件的侦听器。
CollectionsUtil创建忽略字符串大小写的集合。
HybridDictionary通过以下方法来实现 IDictionary:在集合较小时使用 ListDictionary,然后在集合变大时切换到 Hashtable。
ListDictionary使用单向链接列表实现 IDictionary。 对于通常包含少于 10 项的集合,建议使用该实现方法。
NameObjectCollectionBase为关联的 abstract 键和 String 值的集合(可通过键或索引来访问它)提供 Object 基类。
NameObjectCollectionBase.KeysCollection表示集合中 String 密钥的集合。
NameValueCollection表示可通过键或索引访问的关联 String 键和 String 值的集合。
NotifyCollectionChangedEventArgs为 CollectionChanged 事件提供数据。
OrderedDictionary表示可通过键或索引访问的键/值对的集合。
StringCollection表示字符串的集合。
StringDictionary使用字符串(而不是对象)强类型的键和值来实现哈希表。
StringEnumerator支持对 StringCollection 执行简单迭代。

Structs

名称说明
BitVector32提供一个简单结构,该结构以 32 位内存存储布尔值和小整数。
BitVector32.Section表示可以包含整数的向量部分。

接口

名称说明
INotifyCollectionChanged例如,当添加和删除项或清除整个列表时,向侦听器通知动态更改。
IOrderedDictionary表示键/值对的索引集合。

枚举

名称说明
NotifyCollectionChangedAction描述导致 CollectionChanged 事件的操作。

委托

名称说明
NotifyCollectionChangedEventHandler表示 CollectionChanged 事件的处理方法。

备注

专用的集合是具有专门用途的集合。 NameValueCollection 基于NameObjectCollectionBase; 但是,NameValueCollection接受每个密钥,多个值,而NameObjectCollectionBase接受每个密钥只有一个值。
某些强类型集合中的System.Collections.Specialized命名空间StringCollectionStringDictionary,这两个包含的全都是字符串值。

CollectionsUtil类创建的不区分大小写的集合实例。

一些集合转换。 例如,HybridDictionary类以启动ListDictionary并成为Hashtable变大。 KeyedCollection<TKey,TItem>是一个列表,但它的元素数达到指定的阈值时还创建一个查找字典。

<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="200" Width="300"> <StackPanel Margin="10"> <!--CheckBox 示例--> <CheckBox x:Name="checkBox1" Content="选项1" IsChecked="True" Checked="OnChecked" Unchecked="OnUnchecked"/> <CheckBox x:Name="checkBox2" Content="选项2" IsThreeState="True" Indeterminate="OnIndeterminate"/> <!--显示状态信息的文本框--> <TextBlock x:Name="statusText" Margin="0,10,0,0" FontSize="14"/> </StackPanel> </Window> using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //Checked事件处理:当复选框被选中时触发 private void OnChecked(object sender, RoutedEventArgs e) { Debug.WriteLine(statusText); statusText.Text = "选框1被选中了!!"; } //Unchecked事件处理:当复选框未被选中时触发 private void OnUnchecked(object sender, RoutedEventArgs e) { statusText.Text = "选框1取消选中了。"; } //Indeterminate事件处理:当复选框处于不确定状态时触发 private void OnIndeterminate(object sender, RoutedEventArgs e) { statusText.Text = "选框2处于不确定状态"; } } 代码哪有错误
09-23
给我解释一下以下代码并在关键的位置加上注释 using BaseDropControl; using BaseDropControl.Model; using BaseDropControl.ViewModel; using ControlsTool.Base; using Prism.Commands; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Windows; using System.Xml.Serialization; namespace GCP.DataMonitor.ViewModels { public partial class MonitorViewModel { private ObservableCollection<BaseDesignerItem> items = new ObservableCollection<BaseDesignerItem>(); /// <summary> /// 面板控件列表 /// </summary> public ObservableCollection<BaseDesignerItem> Items { get { return items; } set { SetProperty(ref items, value); } } private ObservableCollection<BaseDesignerItem> selectedItems = new ObservableCollection<BaseDesignerItem>(); public ObservableCollection<BaseDesignerItem> SelectedItems { get { return selectedItems; } set { SetProperty(ref selectedItems, value); } } private BaseDesignerItem selectedItem; /// <summary> /// 当前选中控件 /// </summary> public BaseDesignerItem SelectedItem { get { return selectedItem; } set { /*SetProperty(ref selectedItem, value);*/ if (_region == null) { _region = regionManager.Regions["PropertyRegion"]; } SetProperty(ref selectedItem, value); //取消之前显示 foreach (var item in _region.ActiveViews) { _region.Deactivate(item); } //显示选中控件的属性面板 if (value != null) { BaseDesignerItem item = (BaseDesignerItem)value; object itemView = _region.GetView(item.ID.ToString()); if (itemView == null) { if (item.PropPage != null) { _region.Add(item.PropPage, item.ID.ToString()); itemView = item.PropPage; ((PropertyGrid.PropertyView)itemView).DataContext = item.PropPage.DataContext; _region.Activate(itemView); } } if (itemView != null) { _region.Activate(itemView); } } else { //TODO: 显示CANVAS面板属性页 } } } /// <summary> /// 控件拖拽释放后触发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void OnDrop(object sender, System.Windows.DragEventArgs e) { //监控运行时不允许编辑面板 if (IsMonitorRunning) { e.Effects = DragDropEffects.None; return; } Type ctrlType = e.Data.GetData("MonitorControlType") as Type; if (ctrlType != null) { BaseDesignerItem newItem = CreateItem(ctrlType); var viewModel = newItem.DataContext as BaseControlViewModel; Point position = e.GetPosition((IInputElement)sender); viewModel.X = (int)Math.Max(0, position.X); viewModel.Y = (int)Math.Max(0, position.Y); if(viewModel.Width == 0) { viewModel.Width = 100; } if (viewModel.Height == 0) { viewModel.Height = 100; } viewModel.ZIndex = Items.Count; Items.Add(newItem); newItem.Focus(); SelectedItems.Clear(); SelectedItems.Add(newItem); } else { e.Effects = DragDropEffects.None; } } private DelegateCommand<BaseDesignerItem> deleteCommand; public DelegateCommand<BaseDesignerItem> DeleteCommand => deleteCommand ?? (deleteCommand = new DelegateCommand<BaseDesignerItem>(ExecuteDeleteCommand)); /// <summary> /// 执行删除指令 /// </summary> /// <param name="parameter"></param> void ExecuteDeleteCommand(BaseDesignerItem parameter) { if(IsMonitorRunning) { return; } this.Items.Remove(parameter); } private DelegateCommand<IEnumerable< BaseDesignerItem>> groupCommand; public DelegateCommand<IEnumerable<BaseDesignerItem>> GroupCommand => groupCommand ?? (groupCommand = new DelegateCommand<IEnumerable<BaseDesignerItem>>(ExecuteGroupCommand)); void ExecuteGroupCommand(IEnumerable<BaseDesignerItem> items) { if (items == null) { return; } BaseDesignerItem groupItem = new BaseDesignerItem(); groupItem.Visibility = Visibility.Collapsed; groupItem.IsGroup = true; groupItem.IsSelected = true; var vms = items.Select(c => c.DataContext as BaseControlViewModel).ToList(); groupItem.DataContext = new BaseControlViewModel(); (groupItem.DataContext as BaseControlViewModel).X = vms.Select(c => c.X).Min(); (groupItem.DataContext as BaseControlViewModel).Y = vms.Select(c => c.Y).Min(); //items.Select(c=>c.) SelectedItems.Add(groupItem); foreach (BaseDesignerItem item in items) item.ParentID = groupItem.ID; this.Items.Add(groupItem); } [Serializable] public class ControlData { /// <summary> /// 粘贴板数据-控件类型 /// </summary> public Type ClipType { get; set; } /// <summary> /// 粘贴板数据-控件ViewModel序列化后的字节流 /// </summary> public byte[] ClipData; } /// <summary> /// 序列化单个控件 /// </summary> /// <param name="ctrl"></param> /// <returns></returns> byte[] SerializeControl(BaseDesignerItem item) { byte[] serializeData; //控件序列化 using (MemoryStream sw = new MemoryStream()) { Type[] serialtype = GetSerializer(typeof(BaseSerial)); Type[] monitorType = GetSerializer(typeof(BaseControlViewModel)); Type[] type = serialtype.Union(monitorType).ToArray(); XmlSerializer xz = new XmlSerializer(typeof(BaseControlViewModel), type); xz.Serialize(sw, item.DataContext as BaseControlViewModel); serializeData = sw.GetBuffer(); sw.Close();//关闭 } return serializeData; } private DelegateCommand copyCommand; /// <summary> /// 拷贝指令 /// </summary> public DelegateCommand CopyCommand => copyCommand ?? (copyCommand = new DelegateCommand(ExecuteCopyCommand)); void ExecuteCopyCommand() { if(SelectedItems.Count ==0) { return; } List<ControlData> ClipBoardData = new List<ControlData>(); foreach (var item in SelectedItems) { ControlData data = new ControlData(); data.ClipType = item.Content.GetType(); //data.Assmbly = item.Content.GetType().Assembly.ToString(); data.ClipData = SerializeControl(item);//item.DataContext as BaseControlViewModel; ClipBoardData.Add(data); } Clipboard.SetData(DataFormats.Serializable, ClipBoardData); } private DelegateCommand pasteCommand; /// <summary> /// 粘贴指令 /// </summary> public DelegateCommand PasteCommand => pasteCommand ?? (pasteCommand = new DelegateCommand(ExecutePasteCommand)); void ExecutePasteCommand() { List<ControlData> clipData = Clipboard.GetData(DataFormats.Serializable) as List<ControlData>; if (clipData == null) { return; } Type[] serialtype = GetSerializer(typeof(BaseSerial)); Type[] monitorType = GetSerializer(typeof(BaseControlViewModel)); Type[] type = serialtype.Union(monitorType).ToArray(); XmlSerializer controlSerializer = new XmlSerializer(typeof(BaseControlViewModel), type); SelectedItems.Clear(); Clipboard.Clear(); foreach (var item in clipData) { using (MemoryStream st = new MemoryStream(item.ClipData)) { BaseControlViewModel panelVM = (BaseControlViewModel)controlSerializer.Deserialize(st); panelVM.X += 20; panelVM.Y += 20; BaseDesignerItem designItem = CreateItem(item.ClipType, panelVM); //更新控件和变量绑定关系 (designItem.Content as BaseControl).BindingUpdate(); Items.Add(designItem); item.ClipData = SerializeControl(designItem); //控件选中 SelectedItems.Add(designItem); st.Close(); } } //粘贴板中控件更新位置 Clipboard.SetData(DataFormats.Serializable, clipData); } private void OnDragOver(object sender, System.Windows.DragEventArgs e) { //监控运行时不允许编辑面板 if(IsMonitorRunning) { e.Effects = DragDropEffects.None; } e.Handled = false; } BaseDesignerItem CreateItem(Type ctrlType, BaseControlViewModel viewModel=null) { BaseDesignerItem newItem = new BaseDesignerItem(); object control = System.Activator.CreateInstance(ctrlType); newItem.Content = control; newItem.DataContext = ((BaseControl)newItem.Content).DataContext; newItem.PropPage = ((BaseControl)newItem.Content).PropPage; ((BaseControl)newItem.Content).VarDropEvent += OnVarDrop; if (((BaseControl)newItem.Content).GetControlType() == ControlType.Prameter) { ((BaseControl)newItem.Content).ValueChangedEvent += OnValueChanged; } if(viewModel != null) { viewModel.GetSerialData(); newItem.DataContext = viewModel; ((BaseControl)newItem.Content).SetViewModel(viewModel); } return newItem; } /// <summary> /// 变量绑定事件处理函数 /// </summary> /// <param name="e">变量绑定事件参数</param> private void OnVarDrop(VaraibleBindingEventArgs e) { try { if (e.IsAdd) { bindingProxy.AddProtocolBinding2MonitorControl(e.VariableID, e.ControlID); } else { bindingProxy.RemoveProtocolBinding2MonitorControl(e.VariableID, e.ControlID); } } catch (Exception ex) { throw; // LogHelper.Error(ex); } } } }
11-05
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using VisionCCD; namespace visionPro项目练习 { public partial class Form1 : Form { public Form1() { InitializeComponent(); //设置清空日志按钮颜色,点击时变为绿色,松开时颜色恢复 button_清空日志.MouseUp += (sender, e) => { button_清空日志.BackColor = Color.White; }; button_清空日志.MouseDown += (sender, e) => { button_清空日志.BackColor = Color.Green; }; //当鼠标悬停在按钮上时,改变背景颜色 button_清空日志.MouseEnter += (sender, e) => { button_清空日志.BackColor = Color.BlueViolet; }; button_清空日志.MouseLeave += (sender, e) => { button_清空日志.BackColor = Color.BlueViolet; }; button_清空日志.MouseEnter += (sender, e) => { button_清空日志.BackColor = Color.BlueViolet; }; button_清空日志.MouseLeave += (sender, e) => { button_清空日志.BackColor = Color.White; }; //设置打开文件按钮颜色,点击时变为绿色,松开时颜色恢复 button_openFile.MouseEnter += (sender, e) => { button_openFile.BackColor = Color.BlueViolet; }; button_openFile.MouseLeave += (sender, e) => { button_openFile.BackColor = Color.BlueViolet; }; button_openFile.MouseEnter += (sender, e) => { button_openFile.BackColor = Color.BlueViolet; }; button_openFile.MouseLeave += (sender, e) => { button_openFile.BackColor = Color.White; }; //设置打开文件按钮颜色,点击时变为绿色,松开时颜色恢复 button_openFile.MouseUp += (sender, e) => { button_openFile.BackColor = Color.White; }; button_openFile.MouseDown += (sender, e) => { button_openFile.BackColor = Color.Green; }; //设置保存文件按钮颜色,点击时变为绿色,松开时颜色恢复 button_File.MouseEnter += (sender, e) => { button_File.BackColor = Color.BlueViolet; }; button_File.MouseLeave += (sender, e) => { button_File.BackColor = Color.BlueViolet; }; button_File.MouseEnter += (sender, e) => { button_File.BackColor = Color.BlueViolet; }; button_File.MouseLeave += (sender, e) => { button_File.BackColor = Color.White; }; //设置显示按钮颜色,点击时变为绿色,松开时颜色恢复 button_display.MouseUp += (sender, e) => { button_display.BackColor = Color.White; }; button_display.MouseDown += (sender, e) => { button_display.BackColor = Color.Green; }; button_display.MouseEnter += (sender, e) => { button_display.BackColor = Color.BlueViolet; }; button_display.MouseLeave += (sender, e) => { button_display.BackColor = Color.BlueViolet; }; button_display.MouseEnter += (sender, e) => { button_display.BackColor = Color.BlueViolet; }; button_display.MouseLeave += (sender, e) => { button_display.BackColor = Color.White; }; //设置控件按钮颜色,点击时变为绿色,松开时颜色恢复 button_控件.MouseUp += (sender, e) => { button_控件.BackColor = Color.White; }; button_控件.MouseDown += (sender, e) => { button_控件.BackColor = Color.Green; }; button_控件.MouseUp += (sender, e) => { button_控件.BackColor = Color.White; }; button_控件.MouseDown += (sender, e) => { button_控件.BackColor = Color.Green; }; //设置控件按钮颜色,点击时变为绿色,松开时颜色恢复 button_控件.MouseEnter += (sender, e) => { button_控件.BackColor = Color.BlueViolet; }; button_控件.MouseLeave += (sender, e) => { button_控件.BackColor = Color.BlueViolet; }; button_控件.MouseEnter += (sender, e) => { button_控件.BackColor = Color.BlueViolet; }; button_控件.MouseLeave += (sender, e) => { button_控件.BackColor = Color.White; }; //设置控件按钮颜色,点击时变为绿色,松开时颜色恢复 button_控件.MouseUp += (sender, e) => { button_控件.BackColor = Color.White; }; button_控件.MouseDown += (sender, e) => { button_控件.BackColor = Color.Green; }; //设置button_客户端按钮颜色,点击时变为绿色,松开时颜色恢复 button_客户端.MouseEnter += (sender, e) => { button_客户端.BackColor = Color.BlueViolet; }; button_客户端.MouseLeave += (sender, e) => { button_客户端.BackColor = Color.BlueViolet; }; button_客户端.MouseEnter += (sender, e) => { button_客户端.BackColor = Color.BlueViolet; }; button_客户端.MouseLeave += (sender, e) => { button_客户端.BackColor = Color.White; }; //设置button_客户端按钮颜色,点击时变为绿色,松开时颜色恢复 button_客户端.MouseUp += (sender, e) => { button_客户端.BackColor = Color.White; }; button_客户端.MouseDown += (sender, e) => { button_客户端.BackColor = Color.Green; }; } private void Form1_Load(object sender, EventArgs e) { danlimoshi.Instance.SetToolBlock(cogToolBlockEditV21, RecordDisplay); } private void button1_Click(object sender, EventArgs e) { danlimoshi.Instance.SaveToolBlock(); } private void button2_Click(object sender, EventArgs e) { danlimoshi.Instance.Run(); ClassFustion.SaveText("当前用户点击拍照" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n", text: textBox1); } // 添加保存文件方法 private void button_File_Click(object sender, EventArgs e) { using (SaveFileDialog saveDialog = new SaveFileDialog()) { saveDialog.Filter = "日志文件|*.log|文本文件|*.txt|所有文件|*.*"; saveDialog.Title = "保存日志文件"; saveDialog.DefaultExt = ".log"; // 设置初始值 string lastPath = ClassFustion.GetPersistedLogPath(); if (!string.IsNullOrEmpty(lastPath)) { saveDialog.InitialDirectory = Path.GetDirectoryName(lastPath); saveDialog.FileName = Path.GetFileName(lastPath); } if (saveDialog.ShowDialog() == DialogResult.OK) { // 导出日志 ClassFustion.ExportLog(textBox1.Text, saveDialog.FileName); // 记录最新路径 ClassFustion.PersistLogPath(saveDialog.FileName); // 记录操作日志 ClassFustion.SaveText($"日志已保存到: {saveDialog.FileName}", text: textBox1); } } } // 添加打开文件方法 private void button_openFile_Click(object sender, EventArgs e) { using (OpenFileDialog openDialog = new OpenFileDialog()) { openDialog.Filter = "日志文件|*.log;*.txt|所有文件|*.*"; openDialog.Title = "打开日志文件"; // 设置初始目录 string lastPath = ClassFustion.GetPersistedLogPath(); if (!string.IsNullOrEmpty(lastPath)) { openDialog.InitialDirectory = Path.GetDirectoryName(lastPath); } if (openDialog.ShowDialog() == DialogResult.OK) { // 加载日志 string logContent = ClassFustion.LoadLog(openDialog.FileName); if (!string.IsNullOrEmpty(logContent)) { textBox1.Text = logContent; ClassFustion.SaveText($"已加载日志: {openDialog.FileName}", text: textBox1); } } } } private void button_清空日志_Click(object sender, EventArgs e) { textBox1.Text = ""; } private void button1_Click_1(object sender, EventArgs e) { Face face = new Face(); face.Show(); } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using communication; namespace VisionCCD { [Serializable] /// <summary> /// 通讯页面类 /// </summary> public partial class Face : Form { #region 变量 Thread th = null; SockServer servers; #endregion #region 单例模式 private static Face single = null; /// <summary> /// 通讯界面单例 /// </summary> public static Face Single { get { if (single == null) { single = new Face(); } return single; } } #endregion #region 设计窗体 /// <summary> /// 该类被实例化第1就调用此方法 /// </summary> public Face() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false;//跨线程访问 } /// <summary> /// 该方法等.show()被调用之后,程序就会调用Form1_Load,为第2步 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { } /// <summary> /// 该方法等程序被关闭时,Form1_FormClosing被调用,为第“最后一步” /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //System.Diagnostics.Process tt = System.Diagnostics.Process.GetProcessById(System.Diagnostics.Process.GetCurrentProcess().Id); //tt.Kill(); this.Hide(); e.Cancel = true; } #endregion #region TCP客户端 #region 客户端变量 #region 设置标定变量 private string tcp_Send; /// <summary> /// 标定发送表头 /// </summary> public string Tcp_Send { get { return tcp_Send; } set { if (value != null && value.Length > 0) { tcp_Send = value; } } } private int tcp_SplitHead; /// <summary> /// 起始字符 /// </summary> public int Tcp_SplitHead { get { return tcp_SplitHead; } set { if (value != null && value.ToString().Length > 0) { tcp_SplitHead = value; } } } private int tcp_SplitLengt; /// <summary> /// 字符长度 /// </summary> public int Tcp_SplitLengt { get { return tcp_SplitLengt; } set { if (value != null && value.ToString().Length > 0) { tcp_SplitLengt = value; } } } private string tcp_SplitStr; /// <summary> /// 字符 /// </summary> public string Tcp_SplitStr { get { return tcp_SplitStr; } set { if (value != null && value.Length > 0) { tcp_SplitStr = value; } } } private char[] tcp_Index; /// <summary> /// 截取数据 /// </summary> public char[] Tcp_Index { get { return tcp_Index; } set { if (value != null && value.Length > 0) { tcp_Index = value; } } } #endregion #region 设置定位变量 private string tcp_SendS; public string Tcp_SendS { get { return tcp_SendS; } set { if (value != null && value.Length > 0) { tcp_SendS = value; } } } private int tcp_SplitHeadS; public int Tcp_SplitHeadS { get { return tcp_SplitHeadS; } set { if (value != null && value.ToString().Length > 0) { tcp_SplitHeadS = value; } } } private int tcp_SplitLengtS; public int Tcp_SplitLengtS { get { return tcp_SplitLengtS; } set { if (value != null && value.ToString().Length > 0) { tcp_SplitLengtS = value; } } } private string tcp_SplitStrS; public string Tcp_SplitStrS { get { return tcp_SplitStrS; } set { if (value != null && value.Length > 0) { tcp_SplitStrS = value; } } } #endregion #endregion /// <summary> /// 通讯接收消息 /// </summary> /// <param name="value"></param> private void XingHao(string value) { try { if (value.Length >= 0) { ClientDataShow.AppendText(value + "\r\n"); } } catch (Exception ex) { MessageBox.Show("接收信号失败:" + ex.Message); } } #endregion #region 客户端 //链接按钮 private void button4_Click(object sender, EventArgs e) { SockClient.Single.Connect(ClinetIP.Text,Convert.ToInt16(ClientPort.Text)); SockClient.Single.del -= XingHao; SockClient.Single.del += XingHao; } //关闭按钮 private void button6_Click(object sender, EventArgs e) { SockClient.Single.Close();//关闭连接 this.Close();//关闭窗口 } //发送按钮 private void button3_Click(object sender, EventArgs e) { SockClient.Single.Send(textBox5.Text); MessageBox.Show("发送成功"); } #endregion //修改按钮 private void BT_DataSplit_Click(object sender, EventArgs e) { try { Tcp_Send = ClinetSendTex.Text;//标定发送表头 Tcp_SplitHead = Convert.ToInt16(CB_SplitHead.Text);//起始字符 Tcp_SplitLengt = Convert.ToInt16(CB_SplitLengt.Text);//字符长度 Tcp_SplitStr = TB_SplitStr.Text;//字符 char[] lo1 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Index1.Text));//截取数据_索引 char[] lo2 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Index2.Text)); char[] lo3 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_X1.Text));//截取数据_Word_X char[] lo4 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_X2.Text)); char[] lo5 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_Y1.Text));//截取数据_Word_Y char[] lo6 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_Y2.Text)); char[] JiLu = new char[6]; JiLu[0] = lo1[0]; JiLu[1] = lo2[0]; JiLu[2] = lo3[0]; JiLu[3] = lo4[0]; JiLu[4] = lo5[0]; JiLu[5] = lo6[0]; Tcp_Index = JiLu;//截取数据 Tcp_SplitHeadS = Convert.ToInt16(comboBox3.Text); Tcp_SplitLengtS = Convert.ToInt16(comboBox2.Text); Tcp_SplitStrS = textBox6.Text; Tcp_SendS = textBox7.Text; } catch (Exception ex) { MessageBox.Show("交互设置异常:" + ex.Message); } } #region TCP服务器 //服务器链接按钮 private void button1_Click(object sender, EventArgs e) { servers = new SockServer(); servers.CreateSever(IpAddres.Text,Convert.ToInt16(PortAddres.Text)); } //关闭按钮 private void button2_Click(object sender, EventArgs e) { servers.Send(SendTex.Text); } //发送按钮 private void button5_Click(object sender, EventArgs e) { servers.Close(); } #endregion } } using Cognex.VisionPro; using Cognex.VisionPro.CalibFix; using Cognex.VisionPro.Caliper; using Cognex.VisionPro.PMAlign; using Cognex.VisionPro.ToolBlock; using communication; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Documents; using System.Windows.Forms; namespace visionPro项目练习 { public class danlimoshi { //定义一个单例模式 private static danlimoshi instance = null; CogToolBlockEditV2 _toolBlock = null; CogToolBlock Block = null; int indexs; double x;double y; CogRecordDisplay cogRecordDisplay1; string biaotou = null; public static danlimoshi Instance { get { if (instance == null) { instance = new danlimoshi(); } return instance; } } public void SetToolBlock(CogToolBlockEditV2 toolBlock, CogRecordDisplay cogRecordDisplay1) { Block = CogSerializer.LoadObjectFromFile(Application.StartupPath + "\\File\\PAM.vpp") as CogToolBlock; this._toolBlock = toolBlock; this._toolBlock.Subject = null; this._toolBlock.Subject = Block; this.cogRecordDisplay1 = cogRecordDisplay1; Block.Ran += Block_Ran; SockClient.Single.del += GetTCPdate; } private void Block_Ran(object sender, EventArgs e) { cogRecordDisplay1.Image = (ICogImage)Block.Outputs[0].Value; // 获取输出图像 cogRecordDisplay1.Record = Block.CreateLastRunRecord(); // 获取运行记录 // 图像自适应 cogRecordDisplay1.Fit(false); // 不保持比例 CogPMAlignTool pmAlignTool = Block.Tools["CogPMAlignTool1"] as CogPMAlignTool;//获取圆检测工具 //判断圆是否被检测到 if (pmAlignTool.Results.Count > 0) { CreateLabel(0, 0, "模版匹配成功!"); CogFindCircleTool cfc = Block.Tools["CogFindCircleTool1"] as CogFindCircleTool; if (cfc.Results!=null && cfc.Results.GetCircle()!=null) { //找圆成功 CreateLabel(0, 100, "找圆成功!"); if (biaotou == "Calib") { Calib(indexs, cfc.Results.GetCircle().CenterX, cfc.Results.GetCircle().CenterY,x, y); } else if (biaotou == "CameraS1") { string val = "CameraOK:" + cfc.Results.GetCircle().CenterX + "," + cfc.Results.GetCircle().CenterY + "#0$"; SockClient.Single.Send(val); ClassFustion.SaveText("发送信号:"+val); } } else { //找圆失败 CreateLabel(0, 100, "找圆失败!", false); } } else { CreateLabel(0, 0, "圆检测失败!", false); } biaotou = null;//清空标志位 } //获得通讯TCP private void GetTCPdate(string vule) { ClassFustion.SaveText("收到信号:"+vule); if (vule.Substring(0,5) == "Calib")//判断是否为校准数据 { biaotou = "Calib"; indexs =Convert.ToInt16( vule.Split(':')[1].Split(';')[0] );//获取圆心索引号 x = Convert.ToDouble(vule.Split(';')[1].Split(',')[0]);//获取圆心X坐标 y = Convert.ToInt16(vule.Split(',')[1].Split('#')[0]);//获取圆心Y坐标 Block.Run();//执行拍照 } if (vule.Substring(0,8) == "CameraS1" ) { //判断是否为“定位表头” biaotou = "CameraS1"; Run();//执行拍照 } } /// <summary> /// 创建标签方法 /// </summary> /// public void CreateLabel(double x, double y, string text, bool Color = true) { //创建标签 CogGraphicLabel label = new CogGraphicLabel(); //设置标签字体大小 label.Font = new System.Drawing.Font("Arial", 15); if (Color) { //设置字体颜色 label.Color = CogColorConstants.Green; } else { label.Color = CogColorConstants.Red; } //设置对齐方式 label.Alignment = CogGraphicLabelAlignmentConstants.TopLeft; //显示文字内容和位置 label.SetXYText(x, y, text); //将标签显示在图形上 this.cogRecordDisplay1.InteractiveGraphics.Add(label, "CogImageConvertTool1.OutputImage", true); } //创建一个方法,将工具块保存到文件 public void SaveToolBlock() { //获取工具块内容 CogToolBlock vppToolBlock = this._toolBlock.Subject; //保存文件 CogSerializer.SaveObjectToFile(vppToolBlock, Application.StartupPath + "\\File\\PAM.vpp"); } //创建一个run方法,将图片显示在RecordDisplay上 public void Run() { //运行工具块 Block.Run(); } //这里创建一个九点标定方法,对应的坐标进行标定 public void Calib(int index,double pixel_x,double pixel_y,double Robot_x, double Robot_y) { //获取校准点到点工具 index -= 1; CogCalibNPointToNPointTool calib = Block.Tools["CogCalibNPointToNPointTool1"] as CogCalibNPointToNPointTool; //未校正XY坐标,数据传入接口 calib.Calibration.SetUncalibratedPoint(8-index, pixel_x, pixel_y); //原始坐标,数据传入接口 calib.Calibration.SetRawCalibratedPoint(index, Robot_x, Robot_y); if (index >= 8) { //标定完成标定 calib.Calibration.Calibrate(); calib.Run(); } else { // index++; SockClient.Single.Send("CalibOK"+indexs); ClassFustion.SaveText("发送信号:" + "CalibOK" + indexs); } } } } using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace visionPro项目练习 { //封装基本文件基本操作功能 public class ClassFustion { //定义一个全局变量 public static string path; //定义一个全局变量来接收形参 static string InputsPaths = ""; //定义一个全局变量来接收形参 public static System.Windows.Forms.TextBox texts = null; // 新增:持久化日志文件路径 private static string _persistedLogPath = ""; //定义一个方法,用来保存文本到文件和控件中 public static void SaveText(string value, string InputsPath = null, System.Windows.Forms.TextBox text = null) { // 正确处理InputsPath参数 if (!string.IsNullOrEmpty(InputsPath)) { InputsPaths = InputsPath; } // 更新TextBox引用 if (text != null) { texts = text; } // 安全调用Invoke方法(关键修复) if ( texts != null && texts.IsHandleCreated && !texts.IsDisposed) { texts.Invoke(new Action(() => { texts.AppendText(value + "\r\n"); })); } else { // 可选:记录警告或改用其他日志方式 Console.WriteLine($"日志文本控件不可用: {value}"); } // 原有文件日志记录代码保持不变... string yearTime = Application.StartupPath + "//" + DateTime.Now.Year.ToString(); string MonthTime = yearTime + DateTime.Now.ToLongDateString() + "//"; string DayTime = MonthTime + DateTime.Now.ToLongDateString() + "//" + "日志" + "//"; if (!Directory.Exists(yearTime))//判断文件夹是否存在,不存在则创建 { Directory.CreateDirectory(yearTime); } if (!Directory.Exists(MonthTime))//判断文件夹是否存在,不存在则创建 { Directory.CreateDirectory(MonthTime); } if (!Directory.Exists(DayTime))//判断文件夹是否存在,不存在则创建 { Directory.CreateDirectory(DayTime); } //写入文件 FileStream fs = new FileStream(DayTime + "/" + "日志.txt", FileMode.Append); //定义写入流对象 StreamWriter streamWriter = new StreamWriter(fs, Encoding.Default); //写入文件内容 streamWriter.WriteLine(value); //关闭流对象 streamWriter.Close(); //关闭文件流对象 fs.Close(); } // 新增:导出日志到指定文件 public static void ExportLog(string content, string filePath) { try { // 写入文件 File.WriteAllText(filePath, content, Encoding.UTF8); } catch (Exception ex) { MessageBox.Show($"日志导出失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 新增:从文件加载日志 public static string LoadLog(string filePath) { try { // 读取文件 return File.ReadAllText(filePath, Encoding.UTF8); } catch (Exception ex) { MessageBox.Show($"日志加载失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return string.Empty; } } // 修改:保存时设置持久化路径 public static void PersistLogPath(string filePath) { // 设置持久化日志路径 _persistedLogPath = filePath; } // 修改:获取持久化日志路径 public static string GetPersistedLogPath() { return _persistedLogPath; } //这里定义一个方法,用来选择要保存文件的文件夹 //在Form1中,拖一个按钮,点击事件中调用该方法,就可以选择文件夹了 public static void FolderBrowserDialog() { using (FolderBrowserDialog fbd = new FolderBrowserDialog()) { fbd.Description = "请选择 要保存文件的文件夹"; if (fbd.ShowDialog() == DialogResult.OK) { path = fbd.SelectedPath;//查看返回路径 } } } //这里定义一个方法,用来打开文件,并且在Form1中,拖一个按钮,点击事件中 //调用该方法,就可以打开文件了,并且将文件中的日志显示在TextBox1中 public static void OpenText() { System.Diagnostics.Process.Start(path);//打开文件 } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; using System.Threading; using System.Windows.Forms; using static System.Collections.Specialized.BitVector32; using System.Web.Services.Description; namespace communication { /// <summary> /// 以太网客户端 /// </summary> /// public class SockClient { //定义一个委托 public delegate void Del(string vlue); public Del del; #region 单例模式 private static SockClient single = null; /// <summary> /// 通讯单例 /// </summary> /// public static SockClient Single { get { if (single == null) { single = new SockClient(); } return single; } } #endregion #region sock通讯 #region 变量 /// <summary> /// 客户端 /// </summary> Socket tcp; public string value = ""; #endregion /// <summary> /// 链接通讯 /// </summary> /// <param name="IP">ip地址</param> /// <param name="port">端口号</param> /// <param name="mothed">绑定方法</param> public void Connect(string IP, int port) { if (tcp == null || !tcp.IsBound) { try { //定义一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议) tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将IP地址和端口号绑定到网络节点point上,连接服务器 tcp.Connect(IPAddress.Parse(IP), port); //创建线程接收数据 Thread th = new Thread(th_); th.IsBackground = true; th.Start(); } catch (Exception) { MessageBox.Show("连接失败"); } } } /// <summary> /// 线程调用的方法,接收服务器消息 /// </summary> private void th_() { //创建一个内存缓冲区,其大小为1024*1024字节 即1M。 byte[] Byte = new byte[1024 * 1024]; while (true) { Thread.Sleep(5);//线程安全一定加延时 try {//接收到监听的Socket的数据 int num = tcp.Receive(Byte); if (num == 0)//当服务器断开,num收到的字节数为0,可作为退出机制 { tcp.Close();//退出自动关闭客户端 tcp.Dispose(); return; } //利用 Encoding.Default.GetString 获取客户端信息,注意是 字节 转化为 字符串 value = Encoding.Default.GetString(Byte, 0, num); del.Invoke(value); } catch (Exception ex) { MessageBox.Show("接收信号异常:" + ex.Message); } } } /// <summary> /// 发送数据至服务器 /// </summary> public void Send(string value) { try { tcp.Send(Encoding.Default.GetBytes(value)); } catch (Exception) { throw new Exception("发送信号异常"); } } /// <summary> /// 关闭通讯 /// </summary> public void Close() { tcp.Close(); tcp.Dispose(); tcp = null; GC.Collect(); } #endregion } //创建一个以太网服务器 public class SockServer { Socket server; Socket newLink; #region 创建服务器 public void CreateSever(string IP, int port) { //创建一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议) server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个IP地址和端口号,用于监听客户端的连接请求 IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse(IP), port); server.Bind(iPEnd);//绑定IP地址和端口号 server.Listen(10);//设置最大连接数 Thread list = new Thread(Accept);//创建一个线程,用于监听客户端的连接请求 list.IsBackground = true;//设置为后台线程 list.Start();//开始监听客户端的连接请求 //创建线程接收数据 Thread th = new Thread(th_); th.IsBackground = true;//设置为后台线程 th.Start();//开始接收数据 } //创建一个监听客户端连接方法 private ManualResetEvent newLinkReady = new ManualResetEvent(false); public void Accept() { while (true) { // 阻塞,直到有客户端连接 Socket clientSocket = server.Accept(); // 初始化 newLink newLink = clientSocket; // 通知接收数据的线程 newLink 已经准备好 newLinkReady.Set(); } } public void th_() { // 等待 newLink 准备好 newLinkReady.WaitOne(); // 创建一个内存缓冲区,其大小为1024*1024字节 即1M。 byte[] Byte = new byte[1024 * 1024]; while (true) // 循环接收客户端的消息 { Thread.Sleep(5); // 线程安全一定加延时 // 接收客户端的消息,并将其存入Byte数组中 int num = newLink.Receive(Byte); if (num == 0) // 当客户端断开,num收到的字节数为0,可作为退出机制 { newLink.Close(); // 退出自动关闭客户端 return; } } } //创建一个发送消息的方法 public void Send(string vlue) { //将字符串转化为字节,发送给客户端 newLink.Send(Encoding.Default.GetBytes(vlue)); //发送回车换行,便于客户端接收 newLink.Send(Encoding.Default.GetBytes("\r\n")); } //创建一个关闭服务器的方法 public void Close() { server.Close();//关闭服务器 server.Dispose();//释放资源 } #endregion } } 请帮我优化此程序,是优化程序不是大幅度修改程序,优化完之后,要能保证客户端要能和服务器上位机通讯的上,即能互相接收消息也能互相发消息,优化之后也要保证程序不会报错,要能保证日志显示在文本框上,并且给服务器上位机发消息要能接收到服务器上位机回馈的消息,就比如给上位机发送:触发标定信号 ccd--->对方:CalibOK0 对方--->ccd: Calib:0;X,Y# 然后服务器上位机回馈,比如发送:上相机 触发拍照信号 对方--->CCD :CameraS1:X,Y#R$ CCD--->对方 :CameraOK:X,Y#R$ ***********多点拍照************ 上相机 触发拍照信号 对方--->CCD :CameraS1:X,Y#R$ CCD--->对方 :Multipoint3 CCD--->对方 :CameraMultipoint#X1,Y1#X2,Y2...#XN,YN# ***********双相机************ 上相机 触发拍照信号 对方--->CCD :CameraS1:X,Y#R$ CCD--->对方 :CameraOKS 下相机 触发拍照信号 对方--->CCD :CameraS2:X,Y#R$ CCD--->对方 :CameraOK:X,Y#R$
最新发布
11-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值