通常,我在XAML中创建视图,并使用Caliburn.Micro将事件绑定到viewmodel。
<Button cal:Message.Attach="[MouseLeftButtonUp]=[ModifyList($source)]" />
但是,我现在需要根据配置数据在代码中创建按钮。
代码不在代码隐藏中,而是在工厂类中。
Button button = new Button() { Content = "Click Me" };
所以问题是如何连接事件?
答案 0 :(得分: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);
答案 1 :(得分:0)
为避免出现异常,您必须仅在非零值时添加参数,并且该方法只接受一个参数。
简短回答添加此检查:
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;
}