4

我有一个来自 3rd 方库的 TargetedTriggerAction,它希望在不将其附加到按钮的情况下调用/调用。让它与按钮一起工作没有问题,但我想这样做以响应一些非 UI 事件。

这是动作的类声明:

 public class MeasureAction : TargetedTriggerAction<Map>

到目前为止,这是我的设置代码:

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

我希望能够做这样的事情,但我知道 Invoke 受到保护:

measure.Invoke();
4

3 回答 3

8

要调用您的触发器操作,您需要一个触发器!

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's actions.
        /// </summary>
        /// <param name="parameter">The parameter value.</param>
        public void Invoke(object parameter)
        {
            this.InvokeActions(parameter);
        }
    }
}

上面是一个触发器实现,可以在没有任何 UI 依赖项的情况下调用。例如:

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);

为了使调用更容易,您可以将扩展方法添加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);
        }
    }
}

现在你可以写出你真正想要的

var measure = new MeasureAction();
measure.TargetObject = _mapControl;
measure.MeasureMode = MeasureAction.Mode.Polyline;
measure.MapUnits = DistanceUnit.Miles; 
measure.Invoke();
于 2012-10-19T15:51:19.787 回答
0

旧帖子,但可能会有所帮助。我确实喜欢这个

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();

OnTargetChanged() 方法将初始化 MeasureAction 的内部 Map

于 2014-02-27T17:16:52.870 回答
0

第三方班是密封的吗?

如果不是,“最佳”答案可能是从中派生您自己的类MeasureAction并添加一个调用程序(如果您想保持清洁,请将其保持在内部/受保护)。

如果它被密封/以其他方式冻结,您最好的选择可能是反射 - 有一些方法可以缓存/以其他方式加快此调用的成本,但基本代码将类似于:

// 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);
}
于 2012-10-16T17:02:26.403 回答