.net - 绑定(bind)到 WPF 中的方法?

标签 .net wpf data-binding xaml

在这种情况下,如何在 WPF 中绑定(bind)到对象方法?

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>

在这里,我想绑定(bind)到树的每个 RootObject 上的 GetChildren 方法。

编辑绑定(bind)到ObjectDataProvider似乎不起作用,因为我绑定(bind)到项目列表,并且ObjectDataProvider需要要么是静态方法,要么创建自己的实例并使用它。

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

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.

最佳答案

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

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

此转换器将使用反射查找并调用该方法。这要求该方法没有任何参数。

以下是此类转换器的源示例:

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 参数。

关于.net - 绑定(bind)到 WPF 中的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/502250/

相关文章:

c# - for循环中的条件是否在每次迭代中都被评估?

c# - 知道 TPL 数据流 block 是否繁忙的方法?

c# - 当单元测试在不同的程序集中时,如何 stub Properties.Settings 对象?

wpf - Caliburn.Micro 消息冒泡跳过控件

c# - 在 WPF 中使用计时器刷新 UI(使用 BackgroundWorker?)

wpf - 覆盖 DataGridTextColumn

c# - 绑定(bind)到类成员

.net - .Net对象验证

c# - 更新绑定(bind)到 dataSet dataTable 的 listView,它从 SQL c# wpf 中查找数据

.net - 将文本添加到绑定(bind)的 TextBlock