当前位置:  开发笔记 > 开发工具 > 正文

绑定到WPF中的方法?

如何解决《绑定到WPF中的方法?》经验,为你挑选了3个好方法。

如何在WPF中绑定到此场景中的对象方法?

public class RootObject
{
    public string Name { get; }

    public ObservableCollection GetChildren() {...}
}

public class ChildObject
{
    public string Name { get; }
}

XAML:


    
        
            
        
        
            
        
    

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

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

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

System.Windows.Data错误:33:ObjectDataProvider无法创建对象; 类型= 'RootObject'; Error ='构造函数的参数错误.'

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

Drew Noakes.. 69

另一种可能对您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参数.



1> Drew Noakes..:

另一种可能对您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参数.


嗯,...似乎是一个黑客,但我开始认为这可能是唯一的方法.它真的是最容易的!

2> Matt Hamilto..:

不确定它在您的场景中的效果如何,但您可以使用ObjectDataProvider上的MethodName属性让它调用特定方法(如果您使用MethodParameters属性,则使用特定参数)来检索其数据.

这是一个直接从MSDN页面获取的片段:


    
        
            0
             Celsius
        
    

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



3> Michael Prew..:

你必须绑定到方法?

你能绑定一个获取方法的属性吗?

public ObservableCollection Children
{
   get
   {
      return GetChildren();
   }
}


我接受Cameron的评论意味着他绑定了一个他无法添加属性的类型.
推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有