1: /// <summary>
2: /// Class to wrap Winform and WPF Invoke
3: /// The problem is that WPF doesn't implement ISynchronizeInvoke
4: /// </summary>
5: internal class InvokeWrapper
6: {
7: TargetType _TargetType;
8: object _InvokeTargetObject;
9: Type _TypeToInvoke;
10: Delegate _Method;
11: object _Priority;
12:
13: private enum TargetType
14: {
15: WPF,
16: Winform,
17: Unknown
18: }
19:
20: public InvokeWrapper(object InvokeTargetObject, Delegate Method)
21: {
22: _InvokeTargetObject = InvokeTargetObject;
23: _TypeToInvoke = _InvokeTargetObject.GetType();
24: this._Method = Method;
25:
26: _TargetType = TargetType.Unknown;
27: while(_TypeToInvoke.BaseType != typeof(object))
28: {
29: if(_TypeToInvoke.BaseType.FullName == "System.Windows.Forms.Form")
30: {
31: _TargetType = TargetType.Winform;
32: break;
33: }
34: if(_TypeToInvoke.BaseType.FullName == "System.Windows.Threading.DispatcherObject")
35: {
36: _TargetType = TargetType.WPF;
37:
38: string Qualified = "System.Windows.Threading.DispatcherPriority, WindowsBase, " +
39: "Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
40: // obtained by
41: // System.Reflection.Assembly.CreateQualifiedName("WindowsBase",
42: // "System.Windows.Threading.DispatcherPriority");
43:
44: Type Pri = Type.GetType(Qualified);
45: _Priority = Enum.ToObject(Pri, 9);
46: // 9 ==> System.Windows.Threading.DispatcherPriority.Normal
47:
48: object Disp = _TypeToInvoke.InvokeMember("Dispatcher",
49: System.Reflection.BindingFlags.Instance |
50: System.Reflection.BindingFlags.GetProperty |
51: System.Reflection.BindingFlags.Public,
52: null,
53: _InvokeTargetObject,
54: new object[] { });
55: _InvokeTargetObject = Disp;
56: _TypeToInvoke = Disp.GetType();
57: break;
58: }
59: _TypeToInvoke = _TypeToInvoke.BaseType;
60: }
61:
62: }
63:
64: /// <summary>
65: /// Invoke the delegate
66: /// </summary>
67: /// <returns></returns>
68: public object Invoke()
69: {
70: return Invoke(null);
71: }
72:
73: /// <summary>
74: /// Invoke the delegate
75: /// </summary>
76: /// <param name="Param">The first parameter</param>
77: /// <param name="Parameters">the other parameters</param>
78: /// <returns></returns>
79: public object Invoke(object Param, params object[] Parameters)
80: {
81: if(Parameters == null || Parameters.Length == 0)
82: return Invoke(new object[] { Param });
83:
84: object[] NewParameters = new object[Parameters.Length + 1];
85: NewParameters[0] = Param;
86: Array.Copy(Parameters, 0, NewParameters, 1, Parameters.Length);
87:
88: return Invoke(NewParameters);
89: }
90:
91: /// <summary>
92: /// Invoke the delegate
93: /// </summary>
94: /// <param name="Parameters">Parameters for the delgate or null </param>
95: /// <returns>object returned from Invoke</returns>
96: public object Invoke(object[] Parameters)
97: {
98: if(_TargetType == TargetType.Winform)
99: {
100: object Res;
101: object[] InvokeMemberParameters;
102:
103: if(Parameters == null || Parameters.Length == 0)
104: InvokeMemberParameters = new object[] { _Method };
105: else
106: InvokeMemberParameters = new object[] { _Method, Parameters };
107:
108: Res = _TypeToInvoke.InvokeMember("Invoke",
109: System.Reflection.BindingFlags.Instance |
110: System.Reflection.BindingFlags.InvokeMethod |
111: System.Reflection.BindingFlags.Public,
112: null,
113: _InvokeTargetObject,
114: InvokeMemberParameters);
115: return Res;
116: }
117: if(_TargetType == TargetType.WPF)
118: {
119: object Res = null;
120: object[] InvokeMemberParameters;
121:
122: if(Parameters == null || Parameters.Length == 0)
123: InvokeMemberParameters = new object[] { _Priority, _Method };
124: else
125: {
126: if(Parameters.Length == 1)
127: InvokeMemberParameters = new object[]
128: { _Priority, _Method, Parameters[0] };
129: else
130: InvokeMemberParameters = new object[]
131: { _Priority, _Method, Parameters[0], ExtractSecondPartArray(Parameters) };
132: }
133:
134:
135: Res = _TypeToInvoke.InvokeMember("Invoke",
136: System.Reflection.BindingFlags.Instance |
137: System.Reflection.BindingFlags.InvokeMethod |
138: System.Reflection.BindingFlags.Public,
139: null,
140: _InvokeTargetObject,
141: InvokeMemberParameters);
142:
143: return Res;
144: }
145:
146: throw new Exception(_TypeToInvoke.ToString() + " is not supported from this wrapper");
147: }
148:
149: /// <summary>
150: /// Given an n-dimension array (0 to n), returns a new n-1 array with 1 to n elements
151: /// </summary>
152: /// <param name="Params">Source array</param>
153: /// <returns>Array stripped of the first element</returns>
154: private object[] ExtractSecondPartArray(object[] Params)
155: {
156: if(Params == null)
157: throw new ArgumentNullException();
158: if(Params.Length == 0)
159: throw new ArgumentException("Source array should contain at least one element");
160: if(Params.Length == 1)
161: return null;
162:
163: object[] NewArray = new object[Params.Length - 1];
164: Array.Copy(Params, 1, NewArray, 0, NewArray.Length);
165: return NewArray;
166: }
167:
168: }