C# 在代码中创建控件时如何将单击事件绑定到ViewModel

C# 在代码中创建控件时如何将单击事件绑定到ViewModel,c#,caliburn.micro,C#,Caliburn.micro,通常,我在XAML中创建视图,并使用Caliburn.Micro将事件绑定到viewmodel <Button cal:Message.Attach="[MouseLeftButtonUp]=[ModifyList($source)]" /> 所以问题是如何连接活动?我以前从来没有这样做过,所以这可能不是最好的方法,但似乎确实有效 我在下面编写了一个扩展方法,它可以使将ActionMessage附加到任何控件的任何事件变得非常简单 public static class UIEle

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

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

所以问题是如何连接活动?

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

我在下面编写了一个扩展方法,它可以使将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()


为了避免出现异常,只需在参数不为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;
}

杰出的这正是我的想法,但不确定如何实现。我现在已经将其更新为UIElement的扩展方法。使它更干净,并使重复使用成为可能。
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;
}