CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
TriggerAction.cs
Go to the documentation of this file.
1#if !NETFX_CORE && !XAMARIN
2//-----------------------------------------------------------------------
3// <copyright file="TriggerAction.cs" company="Marimer LLC">
4// Copyright (c) Marimer LLC. All rights reserved.
5// Website: https://cslanet.com
6// </copyright>
7// <summary>Control used to invoke a method on the DataContext</summary>
8//-----------------------------------------------------------------------
9#define DEBUG
10using System;
11using System.Collections.Generic;
12using System.Diagnostics;
13using System.Linq;
14using System.Text;
15using System.Windows.Controls;
16using System.Windows;
17using System.ComponentModel;
18
19namespace Csla.Xaml
20{
25 public class TriggerAction : FrameworkElement
26 {
31 {
32 Visibility = System.Windows.Visibility.Collapsed;
33 Height = 20;
34 Width = 20;
35 }
36
40 private void CallMethod(object sender, EventArgs e)
41 {
42 object target = this.DataContext;
43 var cvs = target as System.Windows.Data.CollectionViewSource;
44 if (cvs != null && cvs.View != null)
45 {
46 target = cvs.View.CurrentItem;
47 }
48 else
49 {
50 var icv = target as ICollectionView;
51 if (icv != null)
52 target = icv.CurrentItem;
53 }
54 if (target == null) return; // can be null at design time - so just exit
55
56 var targetMethod = target.GetType().GetMethod(MethodName);
57 if (targetMethod == null)
58 {
59#if NETFX_CORE
60#else
61 Trace.TraceError("Csla.Xaml.TriggerAction Error: CallMethod path error: '{0}' method not found on '{1}', DataContext '{2}'", MethodName, target.GetType(), this.DataContext.GetType());
62#endif
63 throw new MissingMethodException(MethodName);
64 }
65
66 var pCount = targetMethod.GetParameters().Length;
67 if (pCount == 0)
68 {
69 targetMethod.Invoke(target, null);
70 }
71 else if (pCount == 2)
72 {
73 object parameterValue = null;
75 parameterValue = GetMethodParameter();
76 else
77 parameterValue = MethodParameter;
78
79 targetMethod.Invoke(target, new object[] { this, new ExecuteEventArgs
80 {
81 MethodParameter = parameterValue,
82 TriggerParameter = e,
83 TriggerSource = TargetControl
84 }});
85 }
86 else
87 throw new NotSupportedException(Csla.Properties.Resources.ExecuteBadParams);
88 }
89
90 private void HookEvent(FrameworkElement oldTarget, string oldEvent, FrameworkElement newTarget, string newEvent)
91 {
92 if (!ReferenceEquals(oldTarget, newTarget) || oldEvent != newEvent)
93 {
94 if (oldTarget != null && !string.IsNullOrEmpty(oldEvent))
95 {
96 var eventRef = oldTarget.GetType().GetEvent(oldEvent);
97 if (eventRef != null)
98 {
99 var invoke = eventRef.EventHandlerType.GetMethod("Invoke");
100 var p = invoke.GetParameters();
101 if (p.Length == 2)
102 {
103 var p1Type = p[1].ParameterType;
104 if (typeof(EventArgs).IsAssignableFrom(p1Type))
105 {
106 var del = Delegate.CreateDelegate(eventRef.EventHandlerType,
107 this,
108 this.GetType().GetMethod("CallMethod", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic));
109 eventRef.RemoveEventHandler(oldTarget, del);
110 }
111 else
112 {
113 throw new NotSupportedException(Csla.Properties.Resources.ExecuteBadTriggerEvent);
114 }
115 }
116 else
117 throw new NotSupportedException(Csla.Properties.Resources.ExecuteBadTriggerEvent);
118 }
119 }
120
121 if (newTarget != null && !string.IsNullOrEmpty(newEvent))
122 {
123 var eventRef = newTarget.GetType().GetEvent(newEvent);
124 if (eventRef != null)
125 {
126 var invoke = eventRef.EventHandlerType.GetMethod("Invoke");
127 var p = invoke.GetParameters();
128 if (p.Length == 2)
129 {
130 var p1Type = p[1].ParameterType;
131 if (typeof(EventArgs).IsAssignableFrom(p1Type))
132 {
133 var del = Delegate.CreateDelegate(eventRef.EventHandlerType,
134 this,
135 this.GetType().GetMethod("CallMethod", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic));
136 eventRef.AddEventHandler(newTarget, del);
137 }
138 else
139 {
140 throw new NotSupportedException(Csla.Properties.Resources.ExecuteBadTriggerEvent);
141 }
142 }
143 else
144 throw new NotSupportedException(Csla.Properties.Resources.ExecuteBadTriggerEvent);
145 }
146 }
147 }
148 }
149
150#region Properties
151
155 public static readonly DependencyProperty TargetControlProperty =
156 DependencyProperty.Register("TargetControl", typeof(FrameworkElement),
157 typeof(TriggerAction), new PropertyMetadata((o, e) =>
158 {
159 var ta = (TriggerAction)o;
160 ta.HookEvent(
161 (FrameworkElement)e.OldValue, ta.TriggerEvent, (FrameworkElement)e.NewValue, ta.TriggerEvent);
162 }));
166 [Category("Common")]
167 public FrameworkElement TargetControl
168 {
169 get { return (FrameworkElement)GetValue(TargetControlProperty); }
170 set { SetValue(TargetControlProperty, value); }
171 }
172
177 public static readonly DependencyProperty TriggerEventProperty =
178 DependencyProperty.Register("TriggerEvent", typeof(string),
179 typeof(TriggerAction), new PropertyMetadata("Click", (o, e) =>
180 {
181 var ta = (TriggerAction)o;
182 ta.HookEvent(ta.TargetControl, (string)e.OldValue, ta.TargetControl, (string)e.NewValue);
183 }));
188 [Category("Common")]
189 public string TriggerEvent
190 {
191 get { return (string)GetValue(TriggerEventProperty); }
192 set { SetValue(TriggerEventProperty, value); }
193 }
194
199 public static readonly DependencyProperty MethodNameProperty =
200 DependencyProperty.Register("MethodName", typeof(string),
201 typeof(TriggerAction), new PropertyMetadata(null));
206 [Category("Common")]
207 public string MethodName
208 {
209 get { return (string)GetValue(MethodNameProperty); }
210 set { SetValue(MethodNameProperty, value); }
211 }
212
217 public static readonly DependencyProperty MethodParameterProperty =
218 DependencyProperty.Register("MethodParameter", typeof(object),
219 typeof(TriggerAction), new PropertyMetadata(null));
224 [Category("Common")]
225 public object MethodParameter
226 {
227 get { return GetValue(MethodParameterProperty); }
228 set { SetValue(MethodParameterProperty, value); }
229 }
230
236 public static readonly DependencyProperty RebindParameterDynamicallyProperty =
237 DependencyProperty.Register("RebindParameterDynamically", typeof(bool),
238 typeof(TriggerAction), new PropertyMetadata(null));
244 [Category("Common")]
246 {
247 get { return (bool)GetValue(RebindParameterDynamicallyProperty); }
248 set { SetValue(RebindParameterDynamicallyProperty, value); }
249 }
250
251#endregion
252
253#region GetMethodParameter
254
255 private object GetMethodParameter()
256 {
257 var be = this.GetBindingExpression(MethodParameterProperty);
258 if (be != null && be.ParentBinding != null)
259 {
260 var newBinding = CopyBinding(be.ParentBinding);
261 SetBinding(MethodParameterProperty, newBinding);
262 }
263 return MethodParameter;
264 }
265
266 private static System.Windows.Data.Binding CopyBinding(System.Windows.Data.Binding oldBinding)
267 {
268 var result = new System.Windows.Data.Binding();
269 result.BindsDirectlyToSource = oldBinding.BindsDirectlyToSource;
270 result.Converter = oldBinding.Converter;
271 result.ConverterCulture = oldBinding.ConverterCulture;
272 result.ConverterParameter = oldBinding.ConverterParameter;
273 result.Mode = oldBinding.Mode;
274 result.NotifyOnValidationError = oldBinding.NotifyOnValidationError;
275 result.Path = oldBinding.Path;
276 if (oldBinding.ElementName != null)
277 result.ElementName = oldBinding.ElementName;
278 else if (oldBinding.RelativeSource != null)
279 result.RelativeSource = oldBinding.RelativeSource;
280 else
281 result.Source = oldBinding.Source;
282 result.UpdateSourceTrigger = oldBinding.UpdateSourceTrigger;
283 result.ValidatesOnExceptions = oldBinding.ValidatesOnExceptions;
284 return result;
285 }
286
287#endregion
288 }
289}
290#endif
A strongly-typed resource class, for looking up localized strings, etc.
static string ExecuteBadParams
Looks up a localized string similar to Method to be executed must have 0 or 2 parameters.
static string ExecuteBadTriggerEvent
Looks up a localized string similar to Trigger event has an unsupported signature.
Control used to invoke a method on the DataContext based on an event being raised by a UI control.
static readonly DependencyProperty TriggerEventProperty
Gets or sets the name of the event that will trigger the action.
string MethodName
Gets or sets the name of the method to be invoked.
static readonly DependencyProperty MethodParameterProperty
Gets or sets the value of a parameter to be passed to the invoked method.
bool RebindParameterDynamically
Gets or sets a value indicating whether the MethodParameter value should be dynamically rebound befor...
TriggerAction()
Creates an instance of the object.
FrameworkElement TargetControl
Gets or sets the target UI control.
static readonly DependencyProperty TargetControlProperty
Gets or sets the target UI control.
static readonly DependencyProperty RebindParameterDynamicallyProperty
Gets or sets a value indicating whether the MethodParameter value should be dynamically rebound befor...
object MethodParameter
Gets or sets the value of a parameter to be passed to the invoked method.
static readonly DependencyProperty MethodNameProperty
Gets or sets the name of the method to be invoked.
string TriggerEvent
Gets or sets the name of the event that will trigger the action.