3

I need to bind a method to a custom control in xaml file, NOT the result of the method.

Basically the custom control will trigger the method few times when certain conditions match.

How can I do that?

I found some solutions in internet but most of them are binding the result of method into xaml, which is not the solution I looking for.

Many thanks.

2
  • Thanks ColinE and ChrisBD for quick responses! But I think command is not that suit to my case as we still neeed to trigger the command base on certain events in the custom control. However I found a solution which I going to share it below. Commented Jan 18, 2012 at 8:50
  • Yeah I got the answer from here: stackoverflow.com/questions/5146946/…. The question already is my answer. :) Commented Jan 18, 2012 at 9:08

4 Answers 4

2

There are two different approached which you can use:

  • Commands, expose a property of type ICommand which you bind to Command properties of your UI elements.
  • Use behaviours to wire a UI event to a method in your view model, for example use the MVVM Light EventToCommandBehaviour.
Sign up to request clarification or add additional context in comments.

Comments

2

Found this great answer:

Binding of static method/function to Func<T> property in XAML

Simon Rasmussen already shows all I need in his question sample code.

Comments

1

Could you be more specific on what the conditions are? @ColineE and @ChrisBD correctly point out that ICommands and EventTocommandBehavior are going to help in many circumstances, such as translating a button click or a mouseover event into a method call in a ViewModel. I would advocate using these approaches if they can be used as they are deemed best practice

However, some cases require something a little more complex than that. One solution is to use code-behind to cast the DataContext to a view model type and invokle the method directly. For instance:

// Inside MyViewModel.cs public class MyViewModel : INotifyPropertyChanged { // ... } // ... // Inside MyControl.xaml.cs public class MyControl : UserControl { public MyControl() { InitializeComponent(); } pubilc void OnSomeConditionMatches() { var myViewModel = DataContext as MyViewModel; if (myViewModel != null) { // Hacky, but it works myViewModel.CallCustomMethod(); } } } 

This is considered a little hacky and pollutes the code-behind with knowledge of the ViewModel type at runtime. Something we want to avoid as it breaks the separation of concerns between View and ViewModel.

Another method is something I've used myself when dealing with a custom control that has little or no databinding support. By using an interface on the view and an attached property you can inject a view instance into the viewModel and manipulate it directly. Sort of a hybrid MVVM / MVP pattern which I've coined MiVVM.

UML

MiVVM UML Diagram

Xaml:

<!-- Assumes myViewModel is the viewmodel we are binding to --> <!-- which has property InjectedUserControl of type IMyControl --> <Example3:MyControl DataContext="{StaticResource myViewModel}" Injector.InjectThisInto="InjectedUserControl"> </Example3:MyControl> 

Code:

// Defines an interface to the usercontrol to // manipulate directly from ViewModel public interface IMyControl { // Our test method to call void CallView(string message); } // Defines the usercontrol public partial class MyControl : UserControl, IMyControl { public MyControl() { InitializeComponent(); } public void CallView(string message) { MessageBox.Show(message); } } public class MyViewModel { private IMyControl myControl; public IMyControl InjectedUserControl { set { Debug.WriteLine(string.Format("Received Injected Control \"{0}\"", value == null ? "NULL" : value.GetType().Name)); this.myControl = value; this.OnInjectedObjectsChanged(); } } private void OnInjectedObjectsChanged() { // Directly access the view via its interface if (this.myControl != null) this.myControl.CallView("Hello From MyViewModel"); } } 

For a downloadable demo including the source for the Injector attached property, please see this blog post. Also this previous question which is related.

Best regards,

2 Comments

Thanks, you hacky solution give me new idea about my problem, also I like your idea of control injection which I thinking of it previously. However I got the answer, please check my comment in my question. Thanks a lot!
@tzuhsun no problem at all - and glad you found your answer! :) PS: Definition of hack from MIT - "An ingenious solution to an otherwise impossible problem"
0

You'll be wanting to bind to an implementation of ICommand and have that call your class method.

Here's a good blog describing more about using ICommand to execute code from WPF.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.