1
2
3
4
5
6
7
8
9
10
11
|
public
void
DoWork()
{
if
(control.InvokeRequired)
{
control.Invoke(DoWork);
}
else
{
// do work
}
}
|
1
|
InvokeHelper.Invoke(<控件>,
"<方法名称>"
, <参数>);
|
1
|
InvokeHelper.Get(<控件>,
"<属性名称>"
);
|
1
|
InvokeHelper.Set(<控件>,
"<属性名称>"
, <属性值>);
|
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
|
/*******************************************************************************
* InvokeHelper.cs
* A thread-safe control invoker helper class.
* -----------------------------------------------------------------------------
* Project:Conmajia.Controls
* Author:Conmajia
* Url:[email protected]
* History:
* 4th Aug., 2012
* Added support for "Non-control" controls (such as ToolStripItem).
*
* 4th Aug., 2012
* Initiated.
******************************************************************************/
using
System;
using
System.Collections.Generic;
using
System.Reflection;
using
System.Text;
using
System.Windows.Forms;
namespace
InvokerHelperDemo
{
/// <summary>
/// A thread-safe control invoker helper class.
/// </summary>
public
class
InvokeHelper
{
private
delegate
object
MethodInvoker(Control control,
methodName,
params
object
[] args);
private
delegate
object
PropertyGetInvoker(Control control,
object
noncontrol,
string
propertyName);
private
delegate
void
PropertySetInvoker(Control control,
object
noncontrol,
string
propertyName,
object
value);
#endregion
#region
static
methods
// helpers
private
static
PropertyInfo GetPropertyInfo(Control control,
object
noncontrol,
string
propertyName)
{
if
(control !=
null
&& !
string
.IsNullOrEmpty(propertyName))
{
PropertyInfo pi =
null
;
Type t =
null
;
if
(noncontrol !=
null
)
t = noncontrol.GetType();
else
t = control.GetType();
pi = t.GetProperty(propertyName);
if
(pi ==
null
)
throw
new
InvalidOperationException(
string
.Format(
"Can't find property {0} in {1}."
,
propertyName,
t.ToString()
));
return
pi;
}
else
throw
new
ArgumentNullException(
"Invalid argument."
);
}
// outlines
public
static
object
Invoke(Control control,
string
methodName,
params
object
[] args)
{
if
(control !=
null
&& !
string
.IsNullOrEmpty(methodName))
if
(control.InvokeRequired)
return
control.Invoke(
new
MethodInvoker(Invoke),
control,
methodName,
args
);
else
{
MethodInfo mi =
null
;
if
(args !=
null
&& args.Length > 0)
{
Type[] types =
new
Type[args.Length];
for
(
int
i = 0; i < args.Length; i++)
{
if
(args[i] !=
null
)
types[i] = args[i].GetType();
}
mi = control.GetType().GetMethod(methodName, types);
}
else
mi = control.GetType().GetMethod(methodName);
// check method info you get
if
(mi !=
null
)
return
mi.Invoke(control, args);
else
throw
new
InvalidOperationException(
"Invalid method."
);
}
else
throw
new
ArgumentNullException(
"Invalid argument."
);
}
public
static
object
Get(Control control,
string
propertyName)
{
return
Get(control,
null
, propertyName);
}
public
static
object
Get(Control control,
object
noncontrol,
string
propertyName)
{
if
(control !=
null
&& !
string
.IsNullOrEmpty(propertyName))
if
(control.InvokeRequired)
return
control.Invoke(
new
PropertyGetInvoker(Get),
control,
noncontrol,
propertyName
);
else
{
PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName);
object
invokee = (noncontrol ==
null
) ? control : noncontrol;
if
(pi !=
null
)
if
(pi.CanRead)
return
pi.GetValue(invokee,
null
);
else
throw
new
FieldAccessException(
string
.Format(
"{0}.{1} is a write-only property."
,
invokee.GetType().ToString(),
propertyName
));
return
null
;
}
else
throw
new
ArgumentNullException(
"Invalid argument."
);
}
public
static
void
Set(Control control,
string
propertyName,
object
value)
{
Set(control,
null
, propertyName, value);
}
public
static
void
Set(Control control,
object
noncontrol,
string
propertyName,
object
value)
{
if
(control !=
null
&& !
string
.IsNullOrEmpty(propertyName))
if
(control.InvokeRequired)
control.Invoke(
new
PropertySetInvoker(Set),
control,
noncontrol,
propertyName,
value
);
else
{
PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName);
object
invokee = (noncontrol ==
null
) ? control : noncontrol;
if
(pi !=
null
)
if
(pi.CanWrite)
pi.SetValue(invokee, value,
null
);
else
throw
new
FieldAccessException(
string
.Format(
"{0}.{1} is a read-only property."
,
invokee.GetType().ToString(),
|