绑定到WPF中的方法?

在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> 

这里我想绑定到树的每个RootObject上的GetChildren方法。

编辑绑定到一个ObjectDataProvider似乎不工作,因为我绑定到一个项目的列表,并且ObjectDataProvider需要一个静态方法,或者它创build它自己的实例,并使用它。

例如,使用马特的答案我得到:

System.Windows.Data错误:33:ObjectDataProvider无法创build对象; types= 'RootObject'; 错误=错误的构造函数参数。

System.Windows.Data错误:34:ObjectDataProvider:尝试在types上调用方法失败; 方法= '的GetChildren'; types= 'RootObject'; 错误='指定的成员无法在目标上调用。 TargetException:'System.Reflection.TargetException:非静态方法需要一个目标。

另一种可能适用于你的方法是创build一个自定义的IValueConverter ,它将一个方法名称作为一个参数,这样它就可以像这样使用:

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

该转换器将使用reflection来查找和调用该方法。 这要求该方法没有任何参数。

这是一个这样的转换器的来源的例子:

 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."); } } 

并进行相应的unit testing:

 [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)); } 

请注意,此转换器不强制执行targetType参数。

不知道它将如何在您的scheme中工作,但您可以使用ObjectDataProvider的MethodName属性让它调用特定的方法(具有特定的参数,如果您MethodParameters属性)来检索其数据。

以下是直接从MSDN页面获取的摘录:

 <Window.Resources> <ObjectDataProvider ObjectType="{x:Type local:TemperatureScale}" MethodName="ConvertTemp" x:Key="convertTemp"> <ObjectDataProvider.MethodParameters> <system:Double>0</system:Double> <local:TempType>Celsius</local:TempType> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </Window.Resources> 

所以这是一个ObjectDataProvider,它在“TemperatureScale”类的一个实例上调用“ConvertTemp”方法,传递两个参数(0和TempType.Celsius )。

你必须绑定的方法?

你可以绑定到一个属性是谁的吸气是方法?

 public ObservableCollection<ChildObject> Children { get { return GetChildren(); } } 

除非你可以添加一个属性来调用方法(或者创build一个包含该属性的包装类),否则我唯一的方法就是使用ValueConverter。

ObjectDataProvider也有一个ObjectInstance属性,可以用来代替ObjectType

您可以使用System.ComponentModeldynamic定义types的属性(它们不是编译的元数据的一部分)。 我在WPF中使用这种方法来启用绑定到字段中存储其值的types,因为绑定到字段是不可能的。

ICustomTypeDescriptorTypeDescriptionProvidertypes可能允许你实现你想要的。 根据这篇文章 :

TypeDescriptionProvider允许你编写一个独立的类来实现ICustomTypeDescriptor ,然后注册这个类作为其他types描述的提供者。

我自己并没有尝试过这个方法,但我希望这对你的情况很有帮助。

要在WPF场景中绑定到对象的方法,可以绑定到返回委托的属性。