3

通常,我在 XAML 中创建视图,并使用 Caliburn.Micro 将事件绑定到视图模型。

<Button cal:Message.Attach="[MouseLeftButtonUp]=[ModifyList($source)]" />

但是,我现在需要根据配置数据在代码中创建按钮。

代码不在代码隐藏中,它在工厂类中。

Button button = new Button() { Content = "Click Me" };

所以问题是如何连接事件?

4

2 回答 2

3

我以前从未这样做过,所以这可能不是最好的方法,但它似乎确实有效。

我在下面编写了一个扩展方法,应该可以非常简单地将 ActionMessage 附加到任何控件的任何事件。

public static class UIElementExtension {
    public static void AttachActionMessage(this DependancyObject control, string eventName, string methodName, object parameter) {
        var action = new ActionMessage();
        action.MethodName = methodName;
        action.Parameters.Add(new Parameter { Value = parameter });

        var trigger = new System.Windows.Interactivity.EventTrigger();
        trigger.EventName = eventName;
        trigger.SourceObject = control;
        trigger.Actions.Add(action);

        Interaction.GetTriggers(control).Add(trigger);
    }
}

要使用它,只需创建您的控件并调用AttachActionMessage()

var button = new Button { Content = "Click Me" };
button.AttachActionMessage("Click", "ModifyList", DataContext);
于 2013-08-25T15:39:11.673 回答
1

为避免出现异常,您只需在参数不为 null 且方法仅接受一个参数时添加参数。

简短回答添加此检查:

if (parameter != null)
{
    action.Parameters.Add(new Parameter { Value = parameter });
}

或者,您可以使用原始接受答案的改进版本。有了这个,您可以传递任意数量的参数或 null,具体取决于方法的参数:

public static void AttachActionMessage(this DependencyObject control, string eventName, string methodName, params object[] parameters)
{
    var action = new ActionMessage { MethodName = methodName };

    if (parameters != null)
    {
        foreach (var parameter in parameters)
        {
            action.Parameters.Add(new Parameter { Value = parameter });
        }
    }

    var trigger = new System.Windows.Interactivity.EventTrigger
    {
        EventName = eventName,
        SourceObject = control
    };
    trigger.Actions.Add(action);

    Interaction.GetTriggers(control).Add(trigger);
}

该代码使用这些方法进行了测试并且可以正常工作:

IncrementCountButton.AttachActionMessage("Click", "IncrementCount", null);
IncrementCountButton2.AttachActionMessage("Click", "IncrementCount2", 12);

public void IncrementCount()
{
    Count++;
}

public void IncrementCount2(int value)
{
    Count += value;
}
于 2016-09-24T02:05:54.230 回答