c# - Binding Event to a Method of the ViewModel without ICommand -


the problem: bind event public method of viewmodel via xaml.

the notorious solution create public icommand property on viewmodel returns relaycommand or delegatecommand , use eventtrigger , invokecommandaction windows.interactivity in xaml bind event command. similar alternative use mvvmlight's eventtocommand, provides possibility pass eventargs command's parameter.

this solution has pitfall of being verbose, , hence makes code hard refactor , maintain.

i use markupextension binding event public method of viewmodel directly. such possibility provided eventbindingextension this blog post.

example usage in xaml:

<button content="click me" click="{my:eventbinding onclick}" /> 

where viewmodel has following method:

public void onclick(object sender, eventargs e) {     messagebox.show("hello world!"); } 

i have few questions regarding approach:

  1. i have tested , works charm me since no expert ask if solution have pitfalls or possibly unexpected behaviors.
  2. is in compliance mvvm pattern?
  3. eventbindingextension requires public method bound to match parameters of event. how extended allow object source parameter omitted?
  4. what other markupextensions similar there available in frameworks wpf or nuget packages?

1) 1 of benefits of icommand can more route commands around application modifying bindings accordingly. binding directly handler lose functionality , have implement yourself. may not issue in specific case it's unnecessary layer regardless.

2) bit of subjective topic think although it's not technical violation of mvvm it's not in keeping overall philosophy. wpf, , mvvm, designed data-driven; binding method smacks of going old event-driven way of doing things (at least me). in case while binding method might still qualify mvvm, @ least technically, passing ui object in sender not!

3) you'll need modify gethandler function construct, compile , return either linq expression or il delegate accepts expected parameters, removes first , passes rest binding target's method. should enough started:

static delegate gethandler(object datacontext, eventinfo eventinfo, string eventhandlername) {     // vm handler we're binding     var eventparams = getparametertypes(eventinfo.eventhandlertype);     var method = datacontext.gettype().getmethod(eventhandlername, eventparams.skip(1).toarray());     if (method == null)         return null;      // construct expression calls     var instance = expression.constant(datacontext);     var paramexpressions = eventparams.select(p => expression.parameter(p)).toarray();     var call = expression.call(instance, method, paramexpressions.skip(1));      // wrap in lambda , compile     return expression.lambda(eventinfo.eventhandlertype, call, paramexpressions).compile(); } 

4) bit of generic question, 1 use translate localization.


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -