绑定到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.ComponentModel
dynamic定义types的属性(它们不是编译的元数据的一部分)。 我在WPF中使用这种方法来启用绑定到字段中存储其值的types,因为绑定到字段是不可能的。
ICustomTypeDescriptor
和TypeDescriptionProvider
types可能允许你实现你想要的。 根据这篇文章 :
TypeDescriptionProvider
允许你编写一个独立的类来实现ICustomTypeDescriptor
,然后注册这个类作为其他types描述的提供者。
我自己并没有尝试过这个方法,但我希望这对你的情况很有帮助。
要在WPF场景中绑定到对象的方法,可以绑定到返回委托的属性。