1.贡献个Winform自定义控件,信用卡、银行卡输入控件;每4个字符分隔显示。其他UI框架可以参考。
2.印章WinForm自定义控件封装,提供源码下载
3.Windows高速定时器,多媒体定时器winmm.dll库的使用
4.理解SynchronizationContext,如何在Winform里面跨线程访问UI控件
5.C#winform程序关闭计算机的正确姿势
6.WinForm触摸屏程序功能界面长时间不操作自动关闭回到主界面
7.分享Winform datagridview 动态生成中文HeaderText
8.Winform让扫描枪听话,防止在有焦点的地方就扫码输入的尴尬
9.WinForm调用钉钉获取考勤结果
10.C# Winform 实现Ajax效果自定义按钮
11.C#Winform 自定义透明按钮和单窗体模块化实现
12.C#Winform设计的通用标签设计器
13.C#Winform使用mysql作为本地数据库
14.C#winform自定义控件模拟设计时界面鼠标移动和调节大小、选中效果
15.我在winform项目里使用“Windows I/O完成端口”的经验分享
16.一次人脸识别ViewFaceCore使用的经验分享,看我把门店淘汰下来的POS机改成了人脸考勤机
17.
Winform高级技巧-界面和代码分离的实践案例
办法总比困难多(不会或不想用WPF MVVM模式也可以搞工控自动化和上位机编程)...
正文
活到老就该学到老。但是难道我们不可以偷懒么,老技术指哪打哪,游刃有余,如果已经炉火纯青,那么解决问题又快又好它不香吗。本文拒绝讨论技术谁优秀谁该被鄙视。上图的流程是花2天时间搞好的,我不是得瑟有什么不得了的地方。我见很多人都在探讨MVVM,数据驱动业务多么的了不起,其实老技术Winform一样的能办到不信你问问DeepSeek让它给你一个示例代码。比如这样子的,点这里下载。如果只是这么简单的话,就没有写本文的必要了。
我们看看上图的场景,因为现场的实际方案没有最终确定,所以开发人员写了5个版本的代码来验证5种流程,但界面就1个,因为业务的数据是一样的。像这种情况我们这种解决方式是极好的。写代码的同事只需要初级程序员就可以担任。帮忙验证和测试是由高级程序员来担任。我贴一些源码来辅助说明一下是怎么实现的。
1.界面的基类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
|
using
System;
using
System.Collections.Generic;
using
System.Threading;
using
System.Windows.Forms;
using
MES.Core;
using
EES.Common;
using
EES.Controls.Win;
using
EES.Common.Data;
using
System.ComponentModel;
using
System.Runtime.InteropServices;
using
System.Text;
using
System.Linq;
using
WinControls;
using
DataCool_MES.framework;
using
DataCool_MES.config;
using
DataCool_MES.utils;
using
System.Drawing;
namespace
DataCool_MES
{
public
delegate
void
FeedInfoHandler(
object
sender, Exception ex,
string
message, MessageTipsLevel level);
/// <summary>
/// 业务窗体基类
/// </summary>
public
partial
class
BaseModuleForm : DockBaseWorkForm
{
#region DllImport
[DllImport(
"kernel32"
)]
public
static
extern
long
WritePrivateProfileString(
string
section,
string
key,
string
val,
string
filepath);
[DllImport(
"kernel32"
)]
public
static
extern
int
GetPrivateProfileString(
string
section,
string
key,
string
def, StringBuilder retval,
int
size,
string
filePath);
[DllImport(
"imm32.dll"
)]
public
static
extern
IntPtr ImmGetContext(IntPtr hwnd);
[DllImport(
"imm32.dll"
)]
public
static
extern
bool
ImmGetOpenStatus(IntPtr himc);
[DllImport(
"imm32.dll"
)]
public
static
extern
bool
ImmSetOpenStatus(IntPtr himc,
bool
b);
[DllImport(
"imm32.dll"
)]
public
static
extern
bool
ImmGetConversionStatus(IntPtr himc,
ref
int
lpdw,
ref
int
lpdw2);
[DllImport(
"imm32.dll"
)]
#endregion
public
static
extern
int
ImmSimulateHotKey(IntPtr hwnd,
int
lngHotkey);
private
const
int
IME_CMODE_FULLSHAPE = 0x8;
private
const
int
IME_CHOTKEY_SHAPE_TOGGLE = 0x11;
private
SynchronizationContext sc;
protected
string
onceScanData =
string
.Empty;
private
BarCodeHooK hook;
IModuleFlow coreFlowObj;
// 获取屏幕分辨率
private
Rectangle primaryScreen;
private
float
scaleX;
// 基准分辨率宽度
private
float
scaleY;
[Browsable(
false
)]
public
IModuleFlow CoreFlowObj
{
get
{
return
coreFlowObj; }
}
[Browsable(
false
)]
/// <summary>
/// 日志记录处理异常信息显示处理对象
/// 此处用于各种日志和状态信息的记录,并进行对应的信息的显示
/// </summary>
internal
virtual
AlertLog Log
{
get
{
return
null
;
}
}
protected
event
Action CursorBegin;
protected
event
Action CursorEnd;
/// <summary>
/// 实例化脚本对象
/// </summary>
/// <returns></returns>
protected
virtual
IModuleFlow CreateModuleFlow()
{
return
null
;
}
public
BaseModuleForm()
{
DoubleBuffered =
true
;
ImeMode = ImeMode.Off;
AutoScaleMode = AutoScaleMode.None;
InitializeComponent();
#region Cursor
CursorBegin = () =>
{
Clear();
Cursor = Cursors.WaitCursor;
};
CursorEnd = () =>
{
Cursor = Cursors.Default;
};
#endregion
Load += BaseModuleForm_Load;
hook =
new
BarCodeHooK();
hook.BarCodeEvent += Hook_BarCodeEvent;
hook.Start();
FormClosed += BaseModuleForm_FormClosed;
}
private
void
BaseModuleForm_FormClosed(
object
sender, FormClosedEventArgs e)
{
try
{
hook.Stop();
hook.BarCodeEvent -= Hook_BarCodeEvent;
hook =
null
;
}
catch
(Exception ex)
{
FrameAppContext.GetInstance().AppLogger.Error(ex);
}
}
private
void
Hook_BarCodeEvent(BarCodeHooK.BarCodes barCode)
{
if
(CoreFlowObj !=
null
&& FlowContext.Instance.WorkStatus == WorkStatus.Running && !
string
.IsNullOrEmpty(barCode.BarCode))
{
onceScanData = TrimSpecialChar(barCode.BarCode);
CoreFlowObj.OnExecScanReceiving(onceScanData);
}
}
private
void
BaseModuleForm_Load(
object
sender, EventArgs e)
{
sc = SynchronizationContext.Current;
if
(!DesignMode)
{
Input = FlowContext.Instance;
FlowContext.Instance.FlowCustomEvent += OnRaiseFlowCustomEvent;
}
}
private
void
OnRaiseFlowCustomEvent(
object
sender, TEventArgs<EventClass> e)
{
sc.Post(
new
SendOrPostCallback(
delegate
(
object
obj)
{
OnFlowCustomEvent((EventClass)obj);
}), e.Data);
}
protected
virtual
void
OnFlowCustomEvent(EventClass ec)
{
if
(ec.EventType == FlowViewCommand.ClearCurText)
{
Clear();
}
}
/// <summary>
/// 获取当前窗体绑定的上下文对象
/// </summary>
/// <returns></returns>
public
virtual
BindingType GetBindingType()
{
Type type;
if
(bindingSource.DataSource
is
Type)
{
type = (Type)bindingSource.DataSource;
}
else
{
if
(bindingSource.DataSource !=
null
)
{
type = bindingSource.DataSource.GetType();
}
else
{
type =
null
;
}
}
if
(type ==
null
)
{
throw
new
Exception(
"界面输入的数据源为空"
);
}
BindingType bindingType =
new
BindingType();
Type type2;
if
(type.GUID ==
typeof
(DataCollection<>).GUID)
{
type2 = type.GetGenericArguments()[0];
bindingType.IsArray =
true
;
}
else
{
if
(type.GUID ==
typeof
(List<>).GUID)
{
type2 = type.GetGenericArguments()[0];
bindingType.IsArray =
true
;
}
else
{
type2 = type;
bindingType.IsArray =
false
;
}
}
bindingType.Type = Factory.getRawType(type2);
return
bindingType;
}
public
virtual
void
Start()
{
if
(coreFlowObj !=
null
&& FlowContext.Instance.WorkStatus == WorkStatus.Running)
return
;
IModuleFlow core =
null
;
try
{
CursorBegin.Invoke();
if
(CoreFlowObj !=
null
)
throw
new
Exception(
"正在作业,不能启动!"
);
core = CreateModuleFlow();
if
(core !=
null
)
{
core.FeedInfo += OnFeedInfo;
core.ExecBeginWork();
coreFlowObj = core;
FlowContext.Instance.WorkStatus = WorkStatus.Running;
}
ImeMode = ImeMode.NoControl;
Log.SetLogFocus();
}
catch
(Exception ex)
{
FlowContext.Instance.WorkStatus = WorkStatus.NoAction;
if
(coreFlowObj !=
null
)
{
coreFlowObj.FeedInfo -= OnFeedInfo;
coreFlowObj =
null
;
}
throw
ex;
}
finally
{
if
(FlowContext.Instance.WorkStatus == WorkStatus.Running)
{
onceScanData =
string
.Empty;
}
CursorEnd.Invoke();
}
}
public
virtual
void
Stop()
{
if
(CoreFlowObj !=
null
)
{
try
{
var
configObj = SerializerHelper.LoadFromXML<AppContentConfig>(FrameAppContext.GetInstance().RunTimeConfigPath +
"\\AppContentConfig.Config"
);
if
(configObj !=
null
&& !
string
.IsNullOrEmpty(configObj.EntryModuleName) && configObj.EntryModuleName.Equals(
"成品装箱作业"
))
{
using
(
var
dlgFrm =
new
FlowStopCheckForm())
{
var
dlg = dlgFrm.ShowDialog();
if
(dlg == DialogResult.OK && !FlowContext.Instance.IsEndPacking)
{
CoreFlowObj.ExecEndWork();
coreFlowObj =
null
;
FlowContext.Instance.WorkStatus = WorkStatus.Stopped;
}
if
(dlg == DialogResult.OK && FlowContext.Instance.IsEndPacking)
{
CoreFlowObj.StopWorkCheck();
}
}
}
else
{
CoreFlowObj.ExecEndWork();
coreFlowObj =
null
;
FlowContext.Instance.WorkStatus = WorkStatus.Stopped;
}
}
catch
(Exception ex)
{
Exception error =
new
Exception(
"流程执行异常停止,"
+ ex.InnerException ==
null
? ex.Message : ex.InnerException.Message);
FrameAppContext.GetInstance().AppLogger.Error(error);
}
finally
{
Clear();
if
(FlowContext.Instance.WorkStatus != WorkStatus.Running)
{
Log.Write(
"作业已经停止!"
,
""
, MessageTipsLevel.Warning);
FrameAppContext.GetInstance().AppLogger.Info(
"作业已经停止!"
);
FlowContext.Instance.ResetContext();
}
Utility.GCFullCollect();
}
}
}
public
virtual
void
Pause()
{
coreFlowObj.ExecPauseWork();
coreFlowObj =
null
;
FlowContext.Instance.WorkStatus = WorkStatus.Pauseing;
Clear();
Log.Write(
"作业已经暂停!"
,
""
, MessageTipsLevel.Warning);
}
/// <summary>
/// 界面UI控件的绑定数据清理
/// 此处为虚函数,用于UI派生界面的具体绑定调用处理
/// </summary>
protected
virtual
void
Clear()
{
}
/// <summary>
/// 异常信息消息处理队列的回调函数
/// 主要用于各种消息或异常信息的分类处理
/// </summary>
/// <param name="sender"></param>
/// <param name="ex">异常消息结构体</param>
/// <param name="message">异常消息</param>
/// <param name="level">异常消息级别</param>
protected
void
OnFeedInfo(
object
sender, Exception ex,
string
message, MessageTipsLevel level)
{
if
(Log ==
null
)
{
throw
new
Exception(
"AlertLog对象没有绑定或实例化!"
);
}
if
(ex !=
null
)
{
Log.Write(
string
.Format(
"{0}:->"
, DateTime.Now.ToString(
"MM/dd HH:mm:ss"
)), ex.Message, MessageTipsLevel.Error,
true
);
}
else
{
Log.Write(
string
.Format(
"{0}:->"
, DateTime.Now.ToString(
"MM/dd HH:mm:ss"
)), message, level,
true
);
}
}
/// <summary>
/// 响应扫描枪输入
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
protected
override
bool
ProcessCmdKey(
ref
Message msg, Keys keyData)
{
#region 快捷键
if
(msg.Msg == 0x0100 && ContextMenuStrip !=
null
)
{
foreach
(ToolStripMenuItem item
in
ContextMenuStrip.Items)
{
if
(keyData == item.ShortcutKeys)
{
item.PerformClick();
}
}
}
#endregion
if
(FlowContext.Instance.WorkStatus != WorkStatus.Running)
return
base
.ProcessCmdKey(
ref
msg, keyData);
else
return
true
;
}
/// <summary>
/// 截取特殊字符
/// </summary>
/// <param name="inputString"></param>
/// <returns></returns>
protected
virtual
string
TrimSpecialChar(
string
inputString)
{
return
inputString.Replace(
"\u0010"
,
""
);
}
/// <summary>
/// 动态绑定DataGridView的列
/// </summary>
/// <param name="t"></param>
/// <param name="dgv"></param>
protected
virtual
void
BingGridColumn(Type t, DataGridView dgv)
{
dgv.Columns.Clear();
var
props = t.GetProperties().Where(prop => prop.GetCustomAttributes(
typeof
(DisplayNameAttribute),
false
).Any());
int
col_width = dgv.Width / props.Count() - 8;
foreach
(
var
prop
in
props)
{
DisplayNameAttribute attrib = (DisplayNameAttribute)prop.GetCustomAttributes(
typeof
(DisplayNameAttribute),
false
).FirstOrDefault();
if
(prop.GetCustomAttributes(
typeof
(ProgressBarCellAttribute),
false
).Any())
{
DataGridViewProgressBarColumn dc =
new
DataGridViewProgressBarColumn();
dc.Name =
"col"
+ prop.Name;
dc.HeaderText = attrib.DisplayName;
dc.DataPropertyName = prop.Name;
dc.Width = col_width;
dgv.Columns.Add(dc);
}
else
{
DataGridViewTextBoxColumn dc =
new
DataGridViewTextBoxColumn();
dc.Name =
"col"
+ prop.Name;
dc.HeaderText = attrib.DisplayName;
dc.DataPropertyName = prop.Name;
dc.Width = col_width;
dgv.Columns.Add(dc);
}
}
}
/// <summary>
/// 窗体激活时设置输入法是半角
/// </summary>
/// <param name="e"></param>
protected
override
void
OnActivated(EventArgs e)
{
base
.OnActivated(e);
IntPtr HIme = ImmGetContext(
this
.Handle);
if
(ImmGetOpenStatus(HIme))
//如果输入法处于打开状态
{
int
iMode = 0;
int
iSentence = 0;
bool
bSuccess = ImmGetConversionStatus(HIme,
ref
iMode,
ref
iSentence);
//检索输入法资讯
if
(bSuccess)
{
if
((iMode & IME_CMODE_FULLSHAPE) > 0)
//如果是全形
ImmSimulateHotKey(
this
.Handle, IME_CHOTKEY_SHAPE_TOGGLE);
//转换成半形
}
}
}
/// <summary>
/// 缩放控件
/// </summary>
/// <param name="control"></param>
protected
void
ScaleControl(Control control)
{
control.Left = (
int
)(control.Left * scaleX);
control.Top = (
int
)(control.Top * scaleY);
control.Width = (
int
)(control.Width * scaleX);
control.Height = (
int
)(control.Height * scaleY);
foreach
(Control child
in
control.Controls)
{
ScaleControl(child);
}
}
}
}
|
2、代码的基类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
using
EES.Common;
using
System;
using
MES.Core;
namespace
DataCool_MES
{
/// <summary>
/// 脚本的基类
/// </summary>
public
abstract
class
ModuleBaseFlow : IModuleFlow
{
/// <summary>
/// 传递消息的事件
/// </summary>
public
event
FeedInfoHandler FeedInfo;
protected
FlowContext flowContext = FlowContext.Instance;
//是否是调试模式
protected
bool
debugMode =
false
;
//是否显示过程明细信息
protected
bool
showDetail =
false
;
/// <summary>
/// 采集到数据后发生
/// </summary>
/// <param name="data"></param>
public
virtual
void
OnExecScanReceiving(
string
data)
{
FrameAppContext.GetInstance().AppLogger.Info(data);
}
/// <summary>
/// 触发消息传递
/// </summary>
/// <param name="sender"></param>
/// <param name="ex"></param>
/// <param name="message"></param>
/// <param name="level"></param>
protected
virtual
void
OnFeedInfo(
object
sender, Exception ex,
string
message, MessageTipsLevel level)
{
FeedInfo?.Invoke(sender, ex, message, level);
if
(ex !=
null
)
OnException(ex);
}
/// <summary>
/// 手动处理脚本触发的异常
/// </summary>
/// <param name="ex"></param>
protected
virtual
void
OnException(Exception ex)
{
}
/// <summary>
/// 触发抛出异常
/// </summary>
/// <param name="sender"></param>
/// <param name="message"></param>
/// <param name="args"></param>
protected
virtual
void
RaiseException(
object
sender,
string
message,
params
object
[] args)
{
OnFeedInfo(sender,
new
Exception(
string
.Format(message, args)), message, MessageTipsLevel.Error);
if
(!message.Contains(
"由于目标计算机积极拒绝"
))
throw
new
Exception(message);
}
/// <summary>
/// 触发消息提示
/// </summary>
/// <param name="sender"></param>
/// <param name="message"></param>
protected
void
RaiseInfo(
object
sender,
string
message)
{
OnFeedInfo(sender,
null
, message, MessageTipsLevel.Information);
}
/// <summary>
/// 触发警告信息
/// </summary>
/// <param name="sender"></param>
/// <param name="message"></param>
protected
void
RaiseWarning(
object
sender,
string
message)
{
OnFeedInfo(sender,
null
, message, MessageTipsLevel.Warning);
}
/// <summary>
/// 脚本触发界面自定义事件响应
/// </summary>
/// <param name="eventType"></param>
/// <param name="portKey"></param>
/// <param name="portName"></param>
/// <param name="data"></param>
public
virtual
void
RaiseCustomEvent(
string
eventType,
string
portKey,
string
portName,
object
data)
{
try
{
FlowContext.Instance.RaiseCustomEvent(
this
, eventType, portKey, portName, data);
}
catch
(Exception ex)
{
RaiseException(
this
, ex.Message);
}
}
/// <summary>
/// 执行开始作业
/// </summary>
public
virtual
void
ExecBeginWork()
{
try
{
BeforeWorkInit();
}
catch
(Exception ex)
{
throw
ex;
}
}
/// <summary>
/// 执行结束作业
/// </summary>
public
virtual
void
ExecEndWork()
{
}
/// <summary>
/// 执行暂停作业
/// </summary>
public
virtual
void
ExecPauseWork()
{
try
{
PauseWorkCache();
}
catch
(Exception ex)
{
throw
ex;
}
finally
{
FlowContext.Instance.ResetContext();
}
}
/// <summary>
/// 开始作业前初始化
/// </summary>
protected
virtual
void
BeforeWorkInit()
{
RaiseInfo(
this
,
"作业条件检查中..."
);
}
/// <summary>
/// 结束作业时执行检查
/// </summary>
public
virtual
void
StopWorkCheck()
{
}
/// <summary>
/// 暂停作业时缓存业务临时数据
/// </summary>
protected
virtual
void
PauseWorkCache()
{
}
}
}
|
3.业务窗体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
using
System;
using
System.Collections.Generic;
using
System.ComponentModel.Composition;
using
System.ComponentModel.Composition.Hosting;
using
System.Data;
using
System.Linq;
using
System.Reflection;
using
System.Text;
using
System.Threading;
using
System.Windows.Forms;
using
MES.Core;
using
MES.Services;
using
DataCool_MES.modules.dto;
using
MES.Services.ModuleFlowServices;
using
System.Net.Sockets;
using
System.IO;
using
WinControls;
namespace
DataCool_MES.modules
{
[FullScreenStyle(
true
)]
[View(
"批量扫描tray盘混料检测"
, EntryType.入口,
"一次产品检验"
,
"包装作业"
)]
public
partial
class
BatchPackForm : BaseModuleForm
{
[Import]
protected
IModuleFlowFormService ModuleFlowFormService {
get
;
set
; }
//已扫记录
private
List<BatchScanLogDto> LogData =
new
List<BatchScanLogDto>();
private
BatchScanLogDto currentBarcodeData =
null
;
private
WorkStationConfig config;
private
TcpClient cameraClient;
private
TcpClient transmitDeviceClient;
private
byte
[] buffer =
new
byte
[2048];
public
BatchPackForm()
{
DoubleBuffered =
true
;
CheckForIllegalCrossThreadCalls =
false
;
InitializeComponent();
config = SerializerHelper.LoadFromXML<WorkStationConfig>(AppDomain.CurrentDomain.BaseDirectory +
"Config\\"
+
"WorkStationConfig.xml"
);
if
(config !=
null
)
{
FlowContext.Instance.TraySpecifications = config.TraySpecifications;
}
Load += BatchPackForm_Load;
FormClosed += BatchPackForm_FormClosed;
}
private
void
BatchPackForm_FormClosed(
object
sender, FormClosedEventArgs e)
{
if
(transmitDeviceClient !=
null
)
{
try
{
transmitDeviceClient.Client?.Disconnect(
false
);
transmitDeviceClient.Client?.Close();
transmitDeviceClient?.Close();
transmitDeviceClient =
null
;
}
catch
{
}
}
Program.Quit();
}
AlertLog log;
internal
override
AlertLog Log
{
get
{
if
(log ==
null
)
{
Interlocked.CompareExchange(
ref
log,
new
AlertLog(richTextBox1),
null
);
}
return
log;
}
}
private
void
BatchPackForm_Load(
object
sender, EventArgs e)
{
var
catalog =
new
AssemblyCatalog(Assembly.GetExecutingAssembly());
var
container =
new
CompositionContainer(catalog);
container.ComposeParts(
this
,
new
FlowWorkService());
if
(!System.Diagnostics.Debugger.IsAttached)
{
btnStart.DataBindings.Add(
new
Binding(
"Enabled"
, FlowContext.Instance,
"IsStoped"
,
false
, DataSourceUpdateMode.OnPropertyChanged));
btnStop.DataBindings.Add(
new
Binding(
"Enabled"
, FlowContext.Instance,
"IsRunning"
,
false
, DataSourceUpdateMode.OnPropertyChanged));
}
if
(config !=
null
&& !
string
.IsNullOrEmpty(config.TransmissionDeviceIP))
{
try
{
transmitDeviceClient =
new
TcpClient();
transmitDeviceClient.BeginConnect(config.TransmissionDeviceIP, config.TransmissionDevicePort,
new
AsyncCallback(ConnectCallback2), transmitDeviceClient);
}
catch
(Exception ex)
{
FrameAppContext.GetInstance().AppLogger.Error(ex);
}
}
}
protected
override
IModuleFlow CreateModuleFlow()
{
return
new
BatchScanWorkFlow(ModuleFlowFormService);
}
protected
override
void
Clear()
{
richTextBox1.Text =
""
;
}
private
void
btnStart_Click(
object
sender, EventArgs e)
{
try
{
Start();
if
(FlowContext.Instance.WorkStatus == WorkStatus.Running)
{
cameraClient =
new
TcpClient();
cameraClient.BeginConnect(config.CameraIP, config.CameraPort,
new
AsyncCallback(ConnectCallback), cameraClient);
}
if
(FlowContext.Instance.WorkStatus == WorkStatus.Running)
{
try
{
if
(transmitDeviceClient !=
null
)
{
var
sm = transmitDeviceClient.GetStream();
SendCommandToDevice(sm,
"OK"
);
}
else
{
Log.Write(
""
,
"没有和传动设备建立连接!!!"
, MessageTipsLevel.Error);
}
}
catch
(Exception ex)
{
Log.Write(
""
,
"和传动设备通信失败!!!"
+ Environment.NewLine + ex.Message, MessageTipsLevel.Error);
}
}
}
catch
(Exception ex)
{
FrameAppContext.GetInstance().AppLogger.Error($
"{ex.Message}"
);
}
}
void
ConnectCallback(IAsyncResult ar)
{
TcpClient client = (TcpClient)ar.AsyncState;
try
{
client.EndConnect(ar);
NetworkStream stream = client.GetStream();
if
(stream !=
null
)
{
buffer =
new
byte
[2048];
stream.BeginRead(buffer, 0, buffer.Length,
new
AsyncCallback(ReadCallback), stream);
}
}
catch
(Exception ex)
{
log.Write(
""
, ex.Message, MessageTipsLevel.Error);
}
}
void
ReadCallback(IAsyncResult ar)
{
NetworkStream stream = (NetworkStream)ar.AsyncState;
if
(FlowContext.Instance.WorkStatus != WorkStatus.Running)
return
;
int
bytesRead = stream.EndRead(ar);
string
responseData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
log.Write(
""
, $
"Received: {Environment.NewLine}{responseData}"
, MessageTipsLevel.Information);
FrameAppContext.GetInstance().AppLogger.Info(Environment.NewLine + responseData);
if
(!
string
.IsNullOrEmpty(responseData) && responseData.IndexOf(
"+"
) != -1)
{
ScanLog(responseData);
}
buffer =
new
byte
[2048];
stream.BeginRead(buffer, 0, buffer.Length,
new
AsyncCallback(ReadCallback), stream);
}
private
void
BtnStop_Click(
object
sender, EventArgs e)
{
try
{
Stop();
var
config = SerializerHelper.LoadFromXML<WorkStationConfig>(AppDomain.CurrentDomain.BaseDirectory +
"Config\\"
+
"WorkStationConfig.xml"
);
FlowContext.Instance.TraySpecifications = config.TraySpecifications;
if
(config !=
null
&& !
string
.IsNullOrEmpty(config.TraySpecifications) &&
config.TraySpecifications.IndexOf(
","
) == -1)
{
string
[] cellData = config.TraySpecifications.Split(
'*'
);
if
(cellData.Length > 0)
{
FlowContext.Instance.TrayRowCount = Convert.ToInt32(cellData[1]);
FlowContext.Instance.TrayCellCount = Convert.ToInt32(cellData[0]);
}
}
if
(cameraClient !=
null
&& FlowContext.Instance.WorkStatus != WorkStatus.Running)
{
cameraClient.Client?.Disconnect(
false
);
cameraClient.Client?.Close();
cameraClient?.Close();
cameraClient =
null
;
}
SendCommandToDevice(transmitDeviceClient.GetStream(),
"NG"
);
}
catch
(Exception ex)
{
FrameAppContext.GetInstance().AppLogger.Error($
"{ex.Message}"
);
}
}
protected
override
void
OnFlowCustomEvent(EventClass ec)
{
if
(ec.EventType.Equals(
"LoadData"
))
{
DataAction(LoadData);
}
if
(ec.EventType.Equals(
"ExportResultData"
))
{
DataAction(ExportLogToExcelFile);
}
}
/// <summary>
/// 从临时xml文件读取扫描历史记录
/// </summary>
private
void
SaveData()
{
if
(!System.IO.Directory.Exists(AppDomain.CurrentDomain.BaseDirectory +
"LocalData"
))
{
System.IO.Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory +
"LocalData"
);
}
if
(!System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory +
"LocalData\\"
+ DateTime.Now.ToString(
"yyyyMMdd"
) +
".xml"
))
{
SerializerHelper.SerializerToXML(AppDomain.CurrentDomain.BaseDirectory +
"LocalData\\"
+ DateTime.Now.ToString(
"yyyyMMdd"
) +
".xml"
, LogData);
}
else
{
System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory +
"LocalData\\"
+ DateTime.Now.ToString(
"yyyyMMdd"
) +
".xml"
);
SerializerHelper.SerializerToXML(AppDomain.CurrentDomain.BaseDirectory +
"LocalData\\"
+ DateTime.Now.ToString(
"yyyyMMdd"
) +
".xml"
, LogData);
}
FlowContext.Instance.L1Count = LogData.Count;
if
(LogData.Count > 0)
bindingSourceGrid.DataSource = LogData.OrderByDescending(t => t.ScanDatetime).ToList();
}
/// <summary>
/// 加载已有扫描记录
/// </summary>
private
void
LoadData()
{
if
(!System.IO.Directory.Exists(AppDomain.CurrentDomain.BaseDirectory +
"LocalData"
))
{
System.IO.Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory +
"LocalData"
);
}
if
(System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory +
"LocalData\\"
+ DateTime.Now.ToString(
"yyyyMMdd"
) +
".xml"
))
{
LogData = SerializerHelper.LoadFromXML<List<BatchScanLogDto>>(AppDomain.CurrentDomain.BaseDirectory +
"LocalData\\"
+ DateTime.Now.ToString(
"yyyyMMdd"
) +
".xml"
);
FlowContext.Instance.L1Count = LogData.Count;
if
(LogData.Count > 0)
bindingSourceGrid.DataSource = LogData.OrderByDescending(t => t.ScanDatetime).ToList();
}
}
/// <summary>
/// 扫描到一组条码
/// </summary>
/// <param name="barcodeData"></param>
private
void
ScanLog(
string
barcodeData)
{
if
(LogData.Any(t => t.BarcodeData == barcodeData))
{
log.Write(DateTime.Now +
"->:"
,
"重复扫描!"
, MessageTipsLevel.Error);
}
else
{
#region 传递收到的数据
var
entity =
new
BatchScanLogDto();
entity.BarcodeData = barcodeData;
entity.MaterialCode = FlowContext.Instance.MaterielCode;
entity.ScanDatetime = DateTime.Now.ToString();
entity.TraySpecifications = FlowContext.Instance.TraySpecifications;
entity.ResourceText = barcodeData;
currentBarcodeData = entity;
#endregion
//校验数据
ThreeColorled1_Click(threeColorled1,
new
EventArgs());
}
}
private
void
ThreeColorled1_Click(
object
sender, EventArgs e)
{
//必须是符合业务场景的扫描数据
if
(FlowContext.Instance.WorkStatus != WorkStatus.Running ||
currentBarcodeData ==
null
||
currentBarcodeData.BarcodeData.IndexOf(
"+"
) == -1)
return
;
#region 展示解析结果
BarcodeResultViewForm barcodeResultViewForm =
new
BarcodeResultViewForm(currentBarcodeData);
var
diagResult = barcodeResultViewForm.ShowDialog();
if
(diagResult == DialogResult.OK &&
!LogData.Any(r => r.ResourceText == currentBarcodeData.ResourceText))
{
threeColorled1.StatusCode =
"1"
;
log.Write(
""
,
"校验通过!"
, MessageTipsLevel.Information);
LogData.Add(barcodeResultViewForm.BarcodeData);
DataAction(SaveData);
FlowContext.Instance.L1Count = LogData.Count;
SendCommandToDevice(transmitDeviceClient.GetStream(),
"OK"
);
}
else
if
(diagResult != DialogResult.OK &&
!LogData.Any(r => r.ResourceText == currentBarcodeData.ResourceText))
{
threeColorled1.StatusCode =
"2"
;
var
sm = transmitDeviceClient.GetStream();
SendCommandToDevice(sm,
"NG"
);
log.Write(
""
, $
"{Environment.NewLine}校验结果是有混料,不予通行!!!"
, MessageTipsLevel.Warning);
}
#endregion
}
/// <summary>
/// 和传动设备建立Socket连接回调
/// </summary>
/// <param name="ar"></param>
void
ConnectCallback2(IAsyncResult ar)
{
TcpClient client = (TcpClient)ar.AsyncState;
try
{
client.EndConnect(ar);
Log.Write(
""
,
"传动设备已准备就绪..."
, MessageTipsLevel.Information);
}
catch
(Exception ex)
{
Log.Write(
""
,
"传动设备连接失败!"
+ex.Message, MessageTipsLevel.Error);
FrameAppContext.GetInstance().AppLogger.Error(ex);
}
}
/// <summary>
/// 给NetworkStream发送指令
/// </summary>
/// <param name="stream"></param>
/// <param name="cmd"></param>
private
void
SendCommandToDevice(NetworkStream stream,
string
cmd)
{
string
command = cmd;
byte
[] commandBuffer = ASCIIEncoding.ASCII.GetBytes(command);
stream.WriteAsync(commandBuffer, 0, commandBuffer.Length);
}
/// <summary>
/// 导出Excel文件(扫码原始记录)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private
void
BtnExport_Click(
object
sender, EventArgs e)
{
if
(LogData.Count == 0)
{
MessageTip.ShowError(
"还没有通过检验的记录不能导出!"
);
}
else
{
ExportExcel exportExcel =
new
ExportExcel();
string
fileName = $
"{AppDomain.CurrentDomain.BaseDirectory + "
LocalData
"}\\{DateTime.Now.Date:yyyyMMdd}{FlowContext.Instance.MaterielCode}.xls"
;
exportExcel.GridToExcel(fileName,
this
.dataGridView1);
if
(File.Exists(fileName))
{
MessageTip.ShowOk($
"Excel文件导出成功!"
);
}
}
}
/// <summary>
/// 导出Excel文件(MES要求的格式)
/// </summary>
private
void
ExportLogToExcelFile()
{
if
(LogData.Count == 0)
return
;
#region 临时表
var
dt =
new
DataTable();
dt.Columns.Add(
new
DataColumn(
"条码"
,
typeof
(
string
)));
foreach
(
var
logItem
in
LogData)
{
string
[] barcodeList = logItem.BarcodeData.Split(
new
char
[] {
','
}, StringSplitOptions.RemoveEmptyEntries);
foreach
(
var
barcode
in
barcodeList)
{
DataRow dr = dt.NewRow();
dr[0] = barcode;
dt.Rows.Add(dr);
}
}
#endregion
try
{
ExportExcel exportExcel =
new
ExportExcel();
string
fileName = $
"{AppDomain.CurrentDomain.BaseDirectory + "
LocalData
"}\\{DateTime.Now.Date:yyyyMMdd}{FlowContext.Instance.MaterielCode}(仅条码).xls"
;
if
(File.Exists(fileName))
File.Delete(fileName);
exportExcel.DataTableToExcel(fileName, dt);
if
(File.Exists(fileName))
{
MessageTip.ShowOk(
"生产过程的全部条码已保存!"
);
string
logMessage = $
"本次生产共计扫描条码{dt.Rows.Count}个,通过tray盘{LogData.Count}盘."
;
log.Write(
""
, logMessage, MessageTipsLevel.Information);
FrameAppContext.GetInstance().AppLogger.Info(logMessage);
}
}
catch
(Exception ex)
{
log.Write(
""
, ex.Message, MessageTipsLevel.Error);
}
finally
{
dt.Dispose();
}
}
private
void
button1_Click(
object
sender, EventArgs e)
{
Program.Quit();
}
private
void
richTextBox1_DoubleClick(
object
sender, EventArgs e)
{
Clear();
}
}
}
|
4.流程代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
using
System;
using
System.ComponentModel.Composition;
using
System.IO;
using
System.Net;
using
System.Net.Sockets;
using
System.Text;
using
System.Windows.Forms;
using
MES.Core;
using
MES.Services;
namespace
DataCool_MES.modules
{
/// <summary>
/// 批量扫描作业流程
/// </summary>
public
class
BatchScanWorkFlow : ModuleBaseFlow
{
private
TcpClient cameraClient;
protected
IModuleFlowFormService ModuleFlowFormService {
get
;
set
; }
/// <summary>
/// 析构函数
/// </summary>
/// <param name="svr"></param>
public
BatchScanWorkFlow(IModuleFlowFormService svr)
{
ModuleFlowFormService = svr;
}
/// <summary>
/// 和阅读器建立Socket连接回调
/// </summary>
/// <param name="ar"></param>
void
ConnectCallback(IAsyncResult ar)
{
try
{
TcpClient client = (TcpClient)ar.AsyncState;
client?.EndConnect(ar);
NetworkStream stream = client.GetStream();
if
(stream !=
null
)
{
RaiseInfo(
this
,
"读码器已准备就绪..."
);
if
(client !=
null
)
{
stream.Close();
cameraClient?.Close();
}
}
}
catch
(Exception ex)
{
RaiseException(
this
,
"读码器连接失败!!!错误码:"
+ex.Message);
}
}
/// <summary>
/// 给NetworkStream发送指令
/// </summary>
/// <param name="stream"></param>
/// <param name="cmd"></param>
private
void
SendCommandToDevice(NetworkStream stream,
string
cmd)
{
string
command = cmd;
byte
[] commandBuffer = ASCIIEncoding.ASCII.GetBytes(command);
stream.WriteAsync(commandBuffer, 0, commandBuffer.Length);
}
/// <summary>
/// 和传动设备建立Socket连接回调
/// </summary>
/// <param name="ar"></param>
void
ConnectCallback2(IAsyncResult ar)
{
try
{
TcpClient client = (TcpClient)ar.AsyncState;
client?.EndConnect(ar);
NetworkStream stream = client.GetStream();
if
(stream !=
null
)
{
//发消息让皮带开始转动
SendCommandToDevice(stream,
"OK"
);
}
}
catch
(Exception ex)
{
RaiseException(
this
,
"传动设备连接失败!!!错误码:"
+ ex.Message);
}
}
/// <summary>
/// 开始作业前准备工作
/// </summary>
protected
override
void
BeforeWorkInit()
{
base
.BeforeWorkInit();
if
(
string
.IsNullOrEmpty(FlowContext.Instance.TraySpecifications))
{
RaiseException($
"{DateTime.Now}->:"
, $
"必须设定容器的规格!"
);
}
if
(
string
.IsNullOrEmpty(FlowContext.Instance.MaterielCodeHeader+FlowContext.Instance.MaterielCodeEnder))
{
RaiseException($
"{DateTime.Now}->:"
, $
"必须输入本次校验的物料代码!"
);
}
flowContext.L1Count = 0;
RaiseCustomEvent(
"LoadData"
,
""
,
""
,
""
);
var
config = SerializerHelper.LoadFromXML<WorkStationConfig>(AppDomain.CurrentDomain.BaseDirectory +
"Config\\"
+
"WorkStationConfig.xml"
);
if
(config !=
null
&& !
string
.IsNullOrEmpty(config.CameraIP))
{
try
{
cameraClient =
new
TcpClient();
cameraClient.BeginConnect(config.CameraIP, config.CameraPort,
new
AsyncCallback(ConnectCallback), cameraClient);
}
catch
(Exception ex)
{
RaiseException(
this
,
""
,ex.Message);
}
}
else
{
RaiseException($
"{DateTime.Now}->:"
, $
"必须设定阅读器的IP地址!"
);
}
if
(config !=
null
&& !
string
.IsNullOrEmpty(config.TraySpecifications) && config.TraySpecifications.IndexOf(
","
) == -1)
{
string
[] cellData = config.TraySpecifications.Split(
'*'
);
if
(cellData.Length > 0)
{
flowContext.TrayRowCount = Convert.ToInt32(cellData[1]);
flowContext.TrayCellCount = Convert.ToInt32(cellData[0]);
}
}
FlowContext.Instance.MaterielCode= FlowContext.Instance.MaterielCodeHeader+FlowContext.Instance.MaterielCodeEnder;
RaiseInfo(
this
,
"系统准备就绪..."
);
}
/// <summary>
/// 扫描到一个条码
/// </summary>
/// <param name="data"></param>
public
override
void
OnExecScanReceiving(
string
data)
{
RaiseCustomEvent(
"ScanLog"
,
""
,
""
, data);
}
/// <summary>
/// 结束本次作业
/// </summary>
public
override
void
ExecEndWork()
{
base
.ExecEndWork();
//导出扫描记录
RaiseCustomEvent(
"ExportResultData"
,
""
,
""
,
""
);
}
}
}
|
5.界面绑定代码
1
2
3
4
|
protected
override
IModuleFlow CreateModuleFlow()
{
return
new
BatchScanWorkFlow(ModuleFlowFormService);
}
|
界面和代码中间还有个上下文对象,也就是一个单例,貌似这样子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
|
using
EES.Common;
using
MES.Core;
using
System;
using
System.ComponentModel;
namespace
DataCool_MES
{
/// <summary>
/// 工作流程上下文对象
/// </summary>
[Serializable]
public
class
FlowContext : SingletonProvider<FlowContext>, INotifyPropertyChanged
{
public
System.Configuration.Configuration AppConfig {
get
;
set
; }
public
event
EventHandler<TEventArgs<EventClass>> FlowCustomEvent;
public
event
PropertyChangedEventHandler PropertyChanged;
private
void
OnPropertyChanged(
string
propertyName)
{
PropertyChanged?.Invoke(
this
,
new
PropertyChangedEventArgs(propertyName));
}
private
WorkStatus workStatus;
/// <summary>
/// 工作流程运行状态
/// </summary>
public
WorkStatus WorkStatus
{
get
{
return
workStatus; }
set
{
workStatus = value;
OnPropertyChanged(
"WorkStatus"
);
switch
(value)
{
case
WorkStatus.Running:
IsRunning =
true
;
IsStoped =
false
;
WorkStatusName =
"运行中..."
;
break
;
case
WorkStatus.Pauseing:
IsRunning =
false
;
IsStoped =
true
;
WorkStatusName =
"暂停中..."
;
break
;
case
WorkStatus.Stopped:
IsRunning =
false
;
IsStoped =
true
;
WorkStatusName =
"已经停止..."
;
break
;
default
:
IsRunning =
false
;
IsStoped =
true
;
WorkStatusName =
"未启动"
;
break
;
}
}
}
private
string
workStation;
/// <summary>
/// 工位
/// </summary>
public
string
WorkStation
{
get
{
return
workStation; }
set
{
workStation = value;
OnPropertyChanged(
"WorkStation"
);
}
}
private
string
_operator;
/// <summary>
/// 工位操作员
/// </summary>
public
string
Operator
{
get
{
return
_operator; }
set
{ _operator = value; OnPropertyChanged(
"Operator"
); }
}
private
string
lineNo;
/// <summary>
/// 线号
/// </summary>
public
string
LineNo
{
get
{
return
lineNo; }
set
{ lineNo = value; OnPropertyChanged(
"LineNo"
); }
}
private
string
_L1Code;
/// <summary>
/// PCBA条码
/// </summary>
public
string
L1Code
{
get
{
return
_L1Code; }
set
{ _L1Code = value; OnPropertyChanged(
"L1Code"
); }
}
private
string
_L2Code;
/// <summary>
/// 过程条码
/// </summary>
public
string
L2Code
{
get
{
return
_L2Code; }
set
{ _L2Code = value; OnPropertyChanged(
"L2Code"
); }
}
private
string
workStatusName;
/// <summary>
/// 状态状态描述信息
/// </summary>
public
string
WorkStatusName
{
get
{
return
workStatusName; }
set
{ workStatusName = value; OnPropertyChanged(
"WorkStatusName"
); }
}
private
int
_L1Count;
/// <summary>
/// 第一道工序计数
/// </summary>
public
int
L1Count
{
get
{
return
_L1Count; }
set
{
_L1Count = value;
OnPropertyChanged(
"L1Count"
);
}
}
private
int
_L1CountEx = 0;
/// <summary>
/// 制令计数,可清零
/// </summary>
public
int
L1CountEx
{
get
{
return
_L1CountEx; }
set
{
_L1CountEx = value;
OnPropertyChanged(
"L1CountEx"
);
}
}
private
int
_L2Count;
/// <summary>
/// 第二道工序计数
/// </summary>
public
int
L2Count
{
get
{
return
_L2Count; }
set
{ _L2Count = value; OnPropertyChanged(
"L2Count"
); }
}
private
string
_TraySpecifications;
/// <summary>
///Tray Specifications
/// </summary>
public
string
TraySpecifications
{
get
{
return
_TraySpecifications; }
set
{
_TraySpecifications = value;
OnPropertyChanged(
"TraySpecifications"
);
}
}
public
int
TrayCellCount
{
get
;
set
;
}
public
int
TrayRowCount
{
get
;
set
;
}
private
string
orderNo;
/// <summary>
/// 状态状态描述信息
/// </summary>
public
string
OrderNo
{
get
{
return
orderNo; }
set
{
orderNo = value;
OnPropertyChanged(
"OrderNo"
);
}
}
private
string
_MaterielCode;
/// <summary>
/// 物料编码
/// </summary>
public
string
MaterielCode
{
get
{
return
_MaterielCode; }
set
{ _MaterielCode = value; OnPropertyChanged(
"MaterielCode"
); }
}
private
string
_MaterielCodeEnder;
/// <summary>
/// 物料编码
/// </summary>
public
string
MaterielCodeEnder
{
get
{
return
_MaterielCodeEnder; }
set
{ _MaterielCodeEnder = value; OnPropertyChanged(
"_MaterielCodeEnder"
); }
}
private
string
_MaterielCodeHeader;
/// <summary>
/// 物料编码
/// </summary>
public
string
MaterielCodeHeader
{
get
{
return
_MaterielCodeHeader; }
set
{ _MaterielCodeHeader = value; OnPropertyChanged(
"MaterielCodeHeader"
); }
}
private
int
progress;
/// <summary>
/// 本次扫描完成时的进度
/// </summary>
public
int
Progress
{
get
{
return
progress; }
set
{ progress = value; OnPropertyChanged(
"Progress"
); }
}
private
bool
isStoped =
true
;
/// <summary>
/// WorkStatus是否已经停止
/// </summary>
public
bool
IsStoped
{
get
{
return
isStoped; }
set
{ isStoped = value; OnPropertyChanged(
"IsStoped"
); }
}
private
bool
isRunning =
false
;
/// <summary>
/// WorkStatus是否正在运行
/// </summary>
public
bool
IsRunning
{
get
{
return
isRunning; }
set
{ isRunning = value; OnPropertyChanged(
"IsRunning"
); }
}
private
string
_Parameter1;
/// <summary>
/// 公用参数1
/// </summary>
public
string
Parameter1
{
get
{
return
_Parameter1; }
set
{ _Parameter1 = value; OnPropertyChanged(
"Parameter1"
); }
}
private
string
_Parameter2;
/// <summary>
/// 公用参数2
/// </summary>
public
string
Parameter2
{
get
{
return
_Parameter2; }
set
{ _Parameter2 = value; OnPropertyChanged(
"Parameter2"
); }
}
private
string
_Parameter3;
/// <summary>
/// 公用参数3
/// </summary>
public
string
Parameter3
{
get
{
return
_Parameter3; }
set
{ _Parameter3 = value; OnPropertyChanged(
"Parameter3"
); }
}
private
string
_Parameter4;
/// <summary>
/// 公用参数4
/// </summary>
public
string
Parameter4
{
get
{
return
_Parameter4; }
set
{ _Parameter4 = value; OnPropertyChanged(
"Parameter4"
); }
}
private
string
_Parameter5;
/// <summary>
/// 公用参数5
/// </summary>
public
string
Parameter5
{
get
{
return
_Parameter5; }
set
{ _Parameter5 = value; OnPropertyChanged(
"Parameter5"
); }
}
private
string
_Parameter6;
/// <summary>
/// 公用参数6
/// </summary>
public
string
Parameter6
{
get
{
return
_Parameter6; }
set
{ _Parameter6 = value; OnPropertyChanged(
"Parameter6"
); }
}
private
string
_Parameter7;
/// <summary>
/// 公用参数7
/// </summary>
public
string
Parameter7
{
get
{
return
_Parameter7; }
set
{ _Parameter7 = value; OnPropertyChanged(
"Parameter7"
); }
}
private
string
_Parameter8;
/// <summary>
/// 公用参数8
/// </summary>
public
string
Parameter8
{
get
{
return
_Parameter8; }
set
{ _Parameter8 = value; OnPropertyChanged(
"Parameter8"
); }
}
private
string
_Parameter9;
/// <summary>
/// 公用参数9
/// </summary>
public
string
Parameter9
{
get
{
return
_Parameter9; }
set
{ _Parameter9 = value; OnPropertyChanged(
"Parameter9"
); }
}
private
int
packagePCS;
/// <summary>
/// 二级包装,PCS数量
/// </summary>
public
int
PackagePCS_Count
{
get
{
return
packagePCS; }
set
{ packagePCS = value; OnPropertyChanged(
"PackagePCS_Count"
); }
}
private
bool
isEndPacking=
false
;
/// <summary>
/// 是否是在装尾箱
/// </summary>
public
bool
IsEndPacking
{
get
{
return
isEndPacking; }
set
{ isEndPacking= value; OnPropertyChanged(
"IsEndPacking"
); }
}
private
int
_WorkEndNumber;
public
int
WorkEndNumber
{
get
{
return
_WorkEndNumber; }
set
{
_WorkEndNumber = value;
OnPropertyChanged(
"WorkEndNumber"
);
}
}
public
void
RaiseCustomEvent(
object
sender,
string
eventType,
string
portKey,
string
portName,
object
data)
{
RaiseCustomEvent(sender, eventType, portKey, portName, data,
null
);
}
public
void
RaiseCustomEvent(
object
sender,
string
eventType,
string
portKey,
string
portName,
object
data,
object
extend)
{
if
(FlowCustomEvent !=
null
)
{
EventClass ec =
new
EventClass(sender, eventType, portKey, portName, data, extend);
FlowCustomEvent(
this
,
new
TEventArgs<EventClass>(ec));
}
}
/// <summary>
/// 重置上下文
/// </summary>
public
void
ResetContext()
{
OrderNo =
string
.Empty;
MaterielCode =
string
.Empty;
Progress = 0;
L1Code =
string
.Empty;
L1Count = 0;
L2Code =
""
;
L2Count = 0;
L1CountEx = 0;
TraySpecifications =
""
;
Parameter1 =
""
;
Parameter2 =
""
;
Parameter3 =
""
;
Parameter4 =
""
;
Parameter5 =
""
;
Parameter6 =
""
;
Parameter7 =
""
;
Parameter8 =
""
;
Parameter9 =
""
;
IsEndPacking =
false
;
}
}
}
|
好了,我的言传就是这样。我的表达能力就只能到这样了。
原创作者: datacool 转载于: https://www.cnblogs.com/datacool/p/18906932