Cam*_*and 87 .net data-binding wpf xaml
如何在WPF中绑定到此场景中的对象方法?
public class RootObject
{
public string Name { get; }
public ObservableCollection<ChildObject> GetChildren() {...}
}
public class ChildObject
{
public string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
在这里,我想绑定到GetChildren每个RootObject树上的方法.
编辑绑定到一个ObjectDataProvider似乎不起作用,因为我绑定到一个项目列表,并且ObjectDataProvider需要一个静态方法,或者它创建它自己的实例并使用它.
例如,使用Matt的答案,我得到:
System.Windows.Data错误:33:ObjectDataProvider无法创建对象; 类型= 'RootObject'; Error ='构造函数的参数错误.'
System.Windows.Data错误:34:ObjectDataProvider:尝试在类型上调用方法失败; 方法= '的GetChildren'; 类型= 'RootObject'; Error ='无法在目标上调用指定的成员.TargetException:'System.Reflection.TargetException:非静态方法需要一个目标.
Dre*_*kes 69
另一种可能对您IValueConverter有用的方法是创建一个将方法名称作为参数的自定义,以便它可以像这样使用:
ItemsSource="{Binding
Converter={StaticResource MethodToValueConverter},
ConverterParameter='GetChildren'}"
Run Code Online (Sandbox Code Playgroud)
此转换器将使用反射查找并调用该方法.这要求方法没有任何参数.
以下是此类转换器源的示例:
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.");
}
}
Run Code Online (Sandbox Code Playgroud)
并进行相应的单元测试:
[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));
}
Run Code Online (Sandbox Code Playgroud)
请注意,此转换器不会强制执行该targetType参数.
Mat*_*ton 24
不确定它在您的场景中的效果如何,但您可以使用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>
Run Code Online (Sandbox Code Playgroud)
所以这是一个ObjectDataProvider,它在"TemperatureScale"类的实例上调用"ConvertTemp"方法,传递两个参数(0和TempType.Celsius).
你必须绑定到方法?
你能绑定一个获取方法的属性吗?
public ObservableCollection<ChildObject> Children
{
get
{
return GetChildren();
}
}
Run Code Online (Sandbox Code Playgroud)