Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind to a method in WPF?

How do you bind to an objects method in this scenario in WPF?

public class RootObject {     public string Name { get; }      public ObservableCollection<ChildObject> GetChildren() {...} }  public class ChildObject {     public string Name { get; } } 

XAML:

<TreeView ItemsSource="some list of RootObjects">     <TreeView.Resources>         <HierarchicalDataTemplate DataType="{x:Type data:RootObject}"                                    ItemsSource="???">             <TextBlock Text="{Binding Path=Name}" />         </HierarchicalDataTemplate>         <HierarchicalDataTemplate DataType="{x:Type data:ChildObject}">             <TextBlock Text="{Binding Path=Name}" />         </HierarchicalDataTemplate>     </TreeView.Resources> </TreeView> 

Here I want to bind to the GetChildren method on each RootObject of the tree.

EDIT Binding to an ObjectDataProvider doesn't seem to work because I'm binding to a list of items, and the ObjectDataProvider needs either a static method, or it creates it's own instance and uses that.

For example, using Matt's answer I get:

System.Windows.Data Error: 33 : ObjectDataProvider cannot create object; Type='RootObject'; Error='Wrong parameters for constructor.'

System.Windows.Data Error: 34 : ObjectDataProvider: Failure trying to invoke method on type; Method='GetChildren'; Type='RootObject'; Error='The specified member cannot be invoked on target.' TargetException:'System.Reflection.TargetException: Non-static method requires a target.

like image 281
Cameron MacFarland Avatar asked Feb 02 '09 05:02

Cameron MacFarland


People also ask

How do you call a method in XAML WPF?

You Can create RelayCommand inheriting ICommand, and then create property of ICommand and assign relay command to that property and call the method.

What is binding path in WPF?

Binding path syntax. Use the Path property to specify the source value you want to bind to: In the simplest case, the Path property value is the name of the property of the source object to use for the binding, such as Path=PropertyName . Subproperties of a property can be specified by a similar syntax as in C#.

How do I bind data in XAML?

Data binding is a mechanism in XAML applications that provides a simple and easy way for Windows Runtime Apps using partial classes to display and interact with data. The management of data is entirely separated from the way the data is displayed in this mechanism.

How many types of binding are there in WPF?

WPF binding offers four types of Binding.


1 Answers

Another approach that might work for you is to create a custom IValueConverter that takes a method name as a parameter, so that it would be used like this:

ItemsSource="{Binding      Converter={StaticResource MethodToValueConverter},     ConverterParameter='GetChildren'}" 

This converter would find and invoke the method using reflection. This requires the method to not have any arguments.

Here's an example of such a converter's source:

public sealed class MethodToValueConverter : IValueConverter {     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)     {         var methodName = parameter as string;         if (value==null || methodName==null)             return value;         var methodInfo = value.GetType().GetMethod(methodName, new Type[0]);         if (methodInfo==null)             return value;         return methodInfo.Invoke(value, new object[0]);     }      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)     {         throw new NotSupportedException("MethodToValueConverter can only be used for one way conversion.");     } } 

And a corresponding unit test:

[Test] public void Convert() {     var converter = new MethodToValueConverter();     Assert.AreEqual("1234", converter.Convert(1234, typeof(string), "ToString", null));     Assert.AreEqual("ABCD", converter.Convert(" ABCD ", typeof(string), "Trim", null));      Assert.IsNull(converter.Convert(null, typeof(string), "ToString", null));      Assert.AreEqual("Pineapple", converter.Convert("Pineapple", typeof(string), "InvalidMethodName", null)); } 

Note that this converter does not enforce the targetType parameter.

like image 103
Drew Noakes Avatar answered Oct 14 '22 10:10

Drew Noakes