WPF TargetedTriggerAction Program Call

I have a TargetedTriggerAction from a third-party library that would like to call / call without binding it to the button. I have no problem making it work with the button, but I want to do this in response to some kind of event other than the UI.

Here is the action class declaration:

public class MeasureAction : TargetedTriggerAction<Map> 

Here is my installation code:

  var measure = new MeasureAction(); measure.TargetObject = _mapControl; measure.MeasureMode = MeasureAction.Mode.Polyline; measure.MapUnits = DistanceUnit.Miles; 

I want to be able to do something like this, but I know that Invoke is protected:

 measure.Invoke(); 
+4
source share
3 answers

To trigger a trigger action, you need a trigger!

 namespace TriggerTest { using System.Windows; /// <summary> /// A trigger that may be invoked from code. /// </summary> public class ManualTrigger : System.Windows.Interactivity.TriggerBase<DependencyObject> { /// <summary> /// Invokes the trigger actions. /// </summary> /// <param name="parameter">The parameter value.</param> public void Invoke(object parameter) { this.InvokeActions(parameter); } } } 

The above implementation is a trigger implementation that can be invoked without any user interface dependencies. For instance:

 var measure = new MeasureAction(); measure.TargetObject = _mapControl; measure.MeasureMode = MeasureAction.Mode.Polyline; measure.MapUnits = DistanceUnit.Miles; ManualTrigger trigger = new ManualTrigger(); trigger.Actions.Add(measure); trigger.Invoke(null); 

To make this even easier, you can add an extension method to TriggerAction .

 namespace TriggerTest { using System.Windows.Interactivity; /// <summary> /// Allows a trigger action to be invoked from code. /// </summary> public static class TriggerActionExtensions { /// <summary> /// Invokes a <see cref="TriggerAction"/> with the specified parameter. /// </summary> /// <param name="action">The <see cref="TriggerAction"/>.</param> /// <param name="parameter">The parameter value.</param> public static void Invoke(this TriggerAction action, object parameter) { ManualTrigger trigger = new ManualTrigger(); trigger.Actions.Add(action); try { trigger.Invoke(parameter); } finally { trigger.Actions.Remove(action); } } /// <summary> /// Invokes a <see cref="TriggerAction"/>. /// </summary> /// <param name="action">The <see cref="TriggerAction"/>.</param> public static void Invoke(this TriggerAction action) { action.Invoke(null); } } } 

Now you can write what you really need :

 var measure = new MeasureAction(); measure.TargetObject = _mapControl; measure.MeasureMode = MeasureAction.Mode.Polyline; measure.MapUnits = DistanceUnit.Miles; measure.Invoke(); 
+7
source

Is a third-party class private?

If not, the best answer would apparently be to deduce your own class from MeasureAction and add invoker (keep it internal / protected if you want everything to be in order).

If it is sealed / otherwise frozen, the best option is perhaps Reflection - there are ways to cache / otherwise speed up the cost of this call, but the basic code would be something like this:

 // Paste in the code in the original question here, name of instance == measure var actionMethod = typeof(MeasureAction) .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .FirstOrDefault(meth => meth.Name == "Invoke"); if(actionMethod != null) { var result = actionMethod.Invoke(measure, null); } 
0
source

Old post, but may help. I liked it

 public class MyMeasureAction : MeasureAction { public void Execute() { OnTargetChanged(null, (Map)TargetObject); Invoke(null); } } 

...

 var mymeasure = new MyMeasureAction(); mymeasure.TargetObject = MyMap; mymeasure.xxxx = xxxx .... mymeasure.Execute(); 

The OnTargetChanged () method initializes the internal MeasureAction map

0
source

Source: https://habr.com/ru/post/1439204/


All Articles