说我有这样的界面:
public interface ISomeInterface { ... }
我还有几个实现这个接口的类;
public class SomeClass : ISomeInterface { ... }
现在我有一个WPF ListBox列出了ISomeInterface的项目,使用自定义DataTemplate.
数据绑定引擎显然不会(我已经弄明白)允许我绑定到接口属性 - 它看到该对象是一个SomeClass对象,并且数据只显示SomeClass应该碰巧有绑定属性可用非接口属性.
我怎么能告诉DataTemplate好像每个对象都是一个ISomeInterface,而不是SomeClass等?
谢谢!
为了绑定到显式实现的接口成员,您需要做的就是使用括号.例如:
隐:
{Binding Path=MyValue}
明确:
{Binding Path=(mynamespacealias:IMyInterface.MyValue)}
Beatriz Costa-MSFT的微软论坛的答案值得一读(相当古老):
数据绑定团队讨论了不久前添加对接口的支持,但最终没有实现它,因为我们无法为它提供一个好的设计.问题是接口没有像对象类型那样的层次结构.考虑您的数据源同时实现方案
IMyInterface1
,并IMyInterface2
与您在资源这两个接口的DataTemplates:它的DataTemplate你认为我们应该拿起?在对对象类型进行隐式数据模板化时,我们首先尝试查找
DataTemplate
确切类型,然后查找其父类,祖父类等.我们可以应用非常明确的类型顺序.当我们谈到添加对接口的支持时,我们考虑使用反射来找出所有接口并将它们添加到类型列表的末尾.我们遇到的问题是当类型实现多个接口时定义接口的顺序.我们必须记住的另一件事是反射并不便宜,这会减少我们对这种情况的影响.
那么解决方案是什么?您无法在XAML中完成所有操作,但您可以使用一些代码轻松完成.该
ItemTemplateSelector
属性ItemsControl
可用于选择DataTemplate
要用于每个项目的项目.在SelectTemplate
模板选择器的方法中,您将接收要模板化的项目作为参数.在这里,您可以检查它实现的接口,并返回DataTemplate
与之匹配的接口.
简短的回答是DataTemplate不支持接口(考虑多重继承,显式v.隐式等).我们倾向于解决这个问题的方法是扩展基类以允许DataTemplate专门化/泛化.这意味着一个体面但不一定是最佳的解决方案是:
public abstract class SomeClassBase { } public class SomeClass : SomeClassBase { }
你有另一种选择.在DataTemplate上设置一个Key并在ItemTemplate中引用该键.像这样:
然后按键使用它来引用模板,如下所示:
dummyboy建议的答案是最好的答案(它应该被投票到顶级imo).它确实存在设计者不喜欢它的问题(给出错误"Object null不能用作PropertyPath的访问器参数)但是有一个很好的解决方法.解决方法是在datatemplate中定义项目然后将模板设置为标签或其他内容控件.例如,我试图添加这样的图像
但它一直给我同样的错误.解决方案是创建标签并使用数据模板来显示我的内容
这有其缺点,但它似乎对我很好.