Databind是由附加到绑定对象的扩展方法返回的对象内的属性

时间:2016-02-15 19:59:34

标签: c# wpf

不确定我是否正确使用了白话,所以希望代码示例能够澄清。

public class myClassObj
{
    public string aProperty {get;}
}
public class anotherClassObj
{
    public string bProperty {get;}
}

然后我有一个静态扩展方法:

public static anotherClassObj getOtherObj(this myClassObj obj)
{
    anotherClassObj returnObj = new anotherClassObj();
    return returnObj;
}

然后在XAML中:

<DataTemplate>
    <TextBlock Text="{Binding aProperty}"/>
    <TextBlock Text="{Binding getOtherObj().bProperty}"/>
</DataTemplate>

忽略明显的语法错误和缺乏构造函数等,这样的想法是否可能?

基本上我想扩展绑定对象以暴露比被绑定的实际对象的一部分更多的属性。

1 个答案:

答案 0 :(得分:1)

  

这样的想法可能吗?

想法?是。您要求的确切机制?否。

WPF的XAML绑定语法需要源对象上的属性路径。扩展方法是编译时构造。在运行时,它只是在与传递给方法的类完全不同的类中调用静态方法。绑定系统无法有效查找扩展方法。

恕我直言,最好的替代方法是使用"decorator pattern"或类似技术将原始模型对象包装在一个模型对象中,该对象将扩展方法公开为属性,然后绑定到装饰< / em>对象。 E.g:

public class myClassObj
{
    public string aProperty {get;}
}

public class DecoratedClassObj : myClassObj
{
    public anotherClassObj OtherObj { get { return this.getOtherObj(); } }
}

...然后

<DataTemplate>
    <TextBlock Text="{Binding aProperty}"/>
    <TextBlock Text="{Binding OtherObj}"/>
</DataTemplate>

当然,您的模型对象必须实例化为DecoratedClassObj而不是myClassObj,并且该实例用作模型对象(无论您在何处使用模板)。以上显示了通过继承进行装饰。另一种方法是使用组合代替;在该方法中,您必须在装饰器对象中复制装饰对象所需的所有属性(和其他功能)。

请注意,通过装饰,您还可以选择实现INotifyPropertyChanged,以允许更新绑定状态,而实际上影响getOtherObj()方法的返回值的基础数据会发生更改。如果需要通过模型对象修改它,它甚至允许属性设置者访问底层数据。


其他选项包括:

  1. 编写您自己的XAML标记扩展,以处理您要使用的扩展方法语法。这将在XAML中提供类似的语法(但使用您自己的扩展而不是{Binding}扩展名)。您可能希望在此方法中仍然创建一个通用代理对象,可以配置类似于上面建议的装饰器对象,以便它可以参与绑定到实际的目标属性(即Text)。
  2. 写一个附属物。在这种情况下,XAML看起来不像你拥有的那样;而不是绑定到Text属性,你有一些附加属性,如MyAttachedPropertyClass.MyAttachedProperty="MyStaticClass.getOtherObj",你的附加属性通过查找(可能是通过反射)并调用{{}来设置Text属性。 1}}扩展方法。您可以根据需要使附加属性值变得复杂,例如使其成为包含目标属性名称的可解析字符串值以及扩展方法类和名称,甚至使其成为存储的用户定义对象这样的细节。就此而言,您可以拥有一个类似于上一替代方案中建议的代理对象,而不是仅仅设置一次目标属性。
  3. 就个人而言,我很多更喜欢简单地装饰原始模型对象的想法。它更容易,恕我直言的实现更容易理解。我只提供完整性的其他选项,让您了解避免编写显式装饰器所需的内容。 :)