diff --git a/CalcBinding/CalcBinding.cs b/CalcBinding/CalcBinding.cs
index 3ac7de1..fab5a03 100644
--- a/CalcBinding/CalcBinding.cs
+++ b/CalcBinding/CalcBinding.cs
@@ -49,7 +49,16 @@ public override object ProvideValue(IServiceProvider serviceProvider)
BindingBase resBinding;
- if (sourcePropertiesPathesWithPositions.Count() == 1)
+ if (sourcePropertiesPathesWithPositions.Count == 1 && targetPropertyType == typeof(System.Windows.Input.ICommand) && expressionTemplate == "{0}()")
+ {
+ var methodName = sourcePropertiesPathesWithPositions.Single().Item1;
+
+ var targetProvider = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
+ var targetObject = targetProvider.TargetObject as FrameworkElement;
+
+ return new DataContextMethodCommand(methodName, targetObject);
+ }
+ else if (sourcePropertiesPathesWithPositions.Count() == 1)
{
var binding = new System.Windows.Data.Binding(sourcePropertiesPathesWithPositions.Single().Item1)
{
diff --git a/CalcBinding/CalcBinding.csproj b/CalcBinding/CalcBinding.csproj
index f26a50b..d8e08e8 100644
--- a/CalcBinding/CalcBinding.csproj
+++ b/CalcBinding/CalcBinding.csproj
@@ -69,6 +69,7 @@
+
diff --git a/CalcBinding/DataContextMethodCommand.cs b/CalcBinding/DataContextMethodCommand.cs
new file mode 100644
index 0000000..94f5b63
--- /dev/null
+++ b/CalcBinding/DataContextMethodCommand.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Windows;
+using System.Windows.Input;
+
+namespace CalcBinding
+{
+ public class DataContextMethodCommand : ICommand
+ {
+ string _methodName;
+ FrameworkElement _targetObject;
+
+ public DataContextMethodCommand(string methodName, FrameworkElement targetObject)
+ {
+ _methodName = methodName;
+ _targetObject = targetObject;
+ }
+
+ public event EventHandler CanExecuteChanged;
+
+ public bool CanExecute(object parameter)
+ {
+ return true;
+ }
+
+ public void Execute(object parameter)
+ {
+ //get DataContext as late as possible to execute on the correct instance
+ var dataContext = _targetObject.DataContext;
+ var dataContextType = dataContext.GetType();
+ var dataContextMethod = dataContextType.GetMethod(_methodName);
+ dataContextMethod.Invoke(dataContext, null);
+ }
+ }
+}
diff --git a/Tests/CalcBindingSystemTests.cs b/Tests/CalcBindingSystemTests.cs
index 08d7c5d..a01a89b 100644
--- a/Tests/CalcBindingSystemTests.cs
+++ b/Tests/CalcBindingSystemTests.cs
@@ -744,6 +744,36 @@ public void BindingToPropertyContainingDigits()
);
}
+ [TestMethod]
+ public void BindingToMethod()
+ {
+ var viewModel1 = new ExampleViewModel();
+ var viewModel2 = new ExampleViewModel();
+ Assert.IsFalse(viewModel1.ClickMethodInvoked);
+ Assert.IsFalse(viewModel2.ClickMethodInvoked);
+
+ var button = new Button();
+ button.DataContext = viewModel1;
+
+ var calcBinding = new CalcBinding.Binding("ClickMethod()");
+ var bindingExpression = calcBinding.ProvideValue(new ServiceProviderMock(button, Button.CommandProperty));
+
+ button.SetValue(Button.CommandProperty, bindingExpression);
+ var command = button.GetValue(Button.CommandProperty) as System.Windows.Input.ICommand;
+ command.Execute(null);
+
+ Assert.IsTrue(viewModel1.ClickMethodInvoked);
+ Assert.IsFalse(viewModel2.ClickMethodInvoked);
+
+ button.DataContext = viewModel2;
+ command = button.GetValue(Button.CommandProperty) as System.Windows.Input.ICommand;
+ command.Execute(null);
+
+ Assert.IsTrue(viewModel1.ClickMethodInvoked);
+ Assert.IsTrue(viewModel2.ClickMethodInvoked);
+ }
+
+
#region Convert
public void StringAndObjectBindingAssert(string path, INotifyPropertyChanged source,
diff --git a/WpfExample/ExampleViewModel.cs b/WpfExample/ExampleViewModel.cs
index 4a9fb98..187064c 100644
--- a/WpfExample/ExampleViewModel.cs
+++ b/WpfExample/ExampleViewModel.cs
@@ -170,6 +170,24 @@ public ConcreteViewModel2(int a)
///
public class ExampleViewModel : BaseViewModel
{
+ private bool clickMethodInvoked;
+ public bool ClickMethodInvoked
+ {
+ get { return clickMethodInvoked; }
+ set
+ {
+ clickMethodInvoked = value;
+
+ new object().TraceTime(
+ () => RaisePropertyChanged(() => ClickMethodInvoked)
+ );
+ }
+ }
+ public void ClickMethod()
+ {
+ ClickMethodInvoked = !ClickMethodInvoked;
+ }
+
private double a = 10;
public double A
{
diff --git a/WpfExample/FifthPage.xaml b/WpfExample/FifthPage.xaml
new file mode 100644
index 0000000..d092230
--- /dev/null
+++ b/WpfExample/FifthPage.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WpfExample/FifthPage.xaml.cs b/WpfExample/FifthPage.xaml.cs
new file mode 100644
index 0000000..9b08342
--- /dev/null
+++ b/WpfExample/FifthPage.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace WpfExample
+{
+ ///
+ /// Interaction logic for FifthPage.xaml
+ ///
+ public partial class FifthPage : UserControl
+ {
+ public FifthPage()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/WpfExample/MainWindow.xaml b/WpfExample/MainWindow.xaml
index a9e7725..709b810 100644
--- a/WpfExample/MainWindow.xaml
+++ b/WpfExample/MainWindow.xaml
@@ -14,10 +14,13 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/WpfExample/WpfExample.csproj b/WpfExample/WpfExample.csproj
index a3a8e5c..496d163 100644
--- a/WpfExample/WpfExample.csproj
+++ b/WpfExample/WpfExample.csproj
@@ -76,6 +76,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -100,6 +104,9 @@
App.xaml
Code
+
+ FifthPage.xaml
+
FourthPage.xaml