问题
Is it possible to use a method of the DataContext in a binding?
E.g. the signature public bool ProjectIsActive(int number)
[note: not static], can it be declared in a binding?
EDIT: Following the suggestion of ywm and Sheridan I tried adding a resource to my Window with name _this.
I changed the signature to public bool ProjectIsActive(object number)
.
<Window.Resources>
<ObjectDataProvider x:Key="ProjectIsActive"
ObjectInstance="_this.DataContext"
MethodName="ProjectIsActive">
<ObjectDataProvider.MethodParameters>
<sys:Object></sys:Object>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Then the Binding of the Trigger is set as:
<Binding Source="{StaticResource ProjectIsActive}" Path="MethodParameters[0]" BindsDirectlyToSource="true" />
It gives the error: System.Windows.Data Error: 35 : ObjectDataProvider: Failure trying to invoke method on type; Method='ProjectIsActive'; Type='String'; Error='No method was found with matching parameter signature.' MissingMethodException:'System.MissingMethodException: Method 'System.String.ProjectIsActive' not found. at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at System.Windows.Data.ObjectDataProvider.InvokeMethodOnInstance(Exception& e)'
The method signature of ObjectDataProvider.MethodParameters doesn't distinghuish return value from input paramter, I don't know how to proceed.
NOTE: The objective can be also achieved by using a MultiValueConverter and casting in the Convert method etc. I was only curious because binding to a property is so easy, and binding to a method [in my case] so difficult. There are also still better ways to avoid a call to a method.
回答1:
You can use the ObjectDataProvider to access data returned from a method.
<Window.Resources>
<ObjectDataProvider x:Key="colors"
ObjectType="{x:Type local:ColorHelper}"
MethodName="GetColorNames"/>
</Window.Resources>
回答2:
In addition to @ywm's answer, you can also supply input parameters for your method in this way:
xmlns:System="clr-namespace:System;assembly=mscorlib"
...
<Window.Resources>
<ObjectDataProvider x:Key="ProjectIsActiveMethod"
ObjectType="{x:Type System:Boolean}" IsAsynchronous="True"
MethodName="ProjectIsActive">
<ObjectDataProvider.MethodParameters>
<System:Int32>10</System:Int32>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
回答3:
It seems like there is no way to do it unless you write your own ObjectDataProvider that can take a biding.
This is result of that post, which explains how to write a FreezableProxy to accomplish it with the OBjectDataProvider.
来源:https://stackoverflow.com/questions/19924376/binding-to-a-method-in-datacontext