本文介绍了绑定到 WPF 中的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,在 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>

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

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

EDIT 绑定到 ObjectDataProvider 似乎不起作用,因为我绑定到项目列表,而 ObjectDataProvider 需要要么是静态方法,要么是创建自己的实例并使用它.

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 错误:33:ObjectDataProvider 无法创建对象;类型='根对象';Error='构造函数的参数错误.'

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

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.

推荐答案

另一种可能适合您的方法是创建自定义 IValueConverter 将方法名称作为参数,以便像这样使用:

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

以及相应的单元测试:

[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 参数.

Note that this converter does not enforce the targetType parameter.

这篇关于绑定到 WPF 中的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:29