Update:
I made a post about a new more flexible version of the method binding that uses a slightly different syntax here:
http://www.singulink.com/CodeIndex/post/updated-ultimate-wpf-event-method-binding
The full code listing is available here:
https://gist.github.com/mikernet/7eb18408ffbcc149f1d9b89d9483fc19
Any future updates will be posted to the blog so I suggest checking there for the latest version.
Original Answer:
.NET 4.5+ supports markup extensions on events now. I used this to create a method binding that can be used like this:
<!-- Basic usage --> <Button Click="{data:MethodBinding OpenFromFile}" Content="Open" /> <!-- Pass in a binding as a method argument --> <Button Click="{data:MethodBinding Save, {Binding CurrentItem}}" Content="Save" /> <!-- Another example of a binding, but this time to a property on another element --> <ComboBox x:Name="ExistingItems" ItemsSource="{Binding ExistingItems}" /> <Button Click="{data:MethodBinding Edit, {Binding SelectedItem, ElementName=ExistingItems}}" /> <!-- Pass in a hard-coded method argument, XAML string automatically converted to the proper type --> <ToggleButton Checked="{data:MethodBinding SetWebServiceState, True}" Content="Web Service" Unchecked="{data:MethodBinding SetWebServiceState, False}" /> <!-- Pass in sender, and match method signature automatically --> <Canvas PreviewMouseDown="{data:MethodBinding SetCurrentElement, {data:EventSender}, ThrowOnMethodMissing=False}"> <controls:DesignerElementTypeA /> <controls:DesignerElementTypeB /> <controls:DesignerElementTypeC /> </Canvas> <!-- Pass in EventArgs --> <Canvas MouseDown="{data:MethodBinding StartDrawing, {data:EventArgs}}" MouseMove="{data:MethodBinding AddDrawingPoint, {data:EventArgs}}" MouseUp="{data:MethodBinding EndDrawing, {data:EventArgs}}" /> <!-- Support binding to methods further in a property path --> <Button Content="SaveDocument" Click="{data:MethodBinding CurrentDocument.DocumentService.Save, {Binding CurrentDocument}}" />
View model method signatures:
public void OpenFromFile(); public void Save(DocumentModel model); public void Edit(DocumentModel model); public void SetWebServiceState(bool state); public void SetCurrentElement(DesignerElementTypeA element); public void SetCurrentElement(DesignerElementTypeB element); public void SetCurrentElement(DesignerElementTypeC element); public void StartDrawing(MouseEventArgs e); public void AddDrawingPoint(MouseEventArgs e); public void EndDrawing(MouseEventArgs e); public class Document { // Fetches the document service for handling this document public DocumentService DocumentService { get; } } public class DocumentService { public void Save(Document document); }
More details can be found here: http://www.singulink.com/CodeIndex/post/building-the-ultimate-wpf-event-method-binding-extension
The full class code is available here: https://gist.github.com/mikernet/4336eaa8ad71cb0f2e35d65ac8e8e161