绑定到接口类型的属性

问题描述:

我刚刚在WPF中找到了另一个绑定的奇怪点。考虑下面的类及其IStupid类型的属性称为MyStupid绑定到接口类型的属性

public struct DumbClass 
{ 
    public IStupid MyStupid { get { return new IsStupid(); } } 
} 
public interface IStupid{} 
public class IsStupid : IStupid{} 

现在考虑下面结合一个ListBox

var items = new List<DumbClass>(new []{new DumbClass(), new DumbClass(), new DumbClass()}); 
OptListBox.ItemsSource = items; 

没有什么特别之处XAML:

<ListBox Name="OptOccurances" Height="238" HorizontalAlignment="Left" Margin="130,34,0,0" VerticalAlignment="Top" Width="229" > 
</ListBox> 

正如所料,列表框的输出是3行“MyProject.DumbClass”。

但是,如果我设置DisplayMemberPath="MyStupid"(或者创建一个ItemTemplate,将'MyStupid'直接绑定到模板中的TextBlock),我会得到3个空行,而我期望它会说MyProject.IsStupid。为什么数据绑定引擎无法调用默认的ToString()实现并显示类名称。是否有接口类型属性的解决方法?至少,没有绑定错误引发的原因吗?

+0

对于除foo/bar之外的其他内容+1。 – 2013-04-30 22:30:23

+0

一个名为'DumbClass'的结构是真的愚蠢,因为它甚至没有意识到它不是一个类。 – Dan 2013-04-30 22:31:45

+0

绑定错误永远不会“抛出”。你可以在Visual Studio的输出窗口看到任何绑定错误,你有什么? – 2013-04-30 22:44:05

我可以重现此问题。它看起来像WPF的错误。

这里是你可以用变通方法: 相反的DisplayMemberPath的,您可以使用项目的DataTemplate中使用的StringFormat参数,这将属性值强制转换为字符串:

<ListBox x:Name="OptOccurances" Height="238" HorizontalAlignment="Left" Margin="130,34,0,0" VerticalAlignment="Top" Width="229" > 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Path=MyStupid, StringFormat='{}{0}' }"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

一般来说,你可以使用WPF跟踪设置,以弄清楚这样的问题: enter image description here

但在这种情况下,因为我看到没有发生绑定错误。

此外,您可以使用WPF可视化的Visual Studio 2012,它允许你去调查从调试观察树权: enter image description here

使用下面的代码,你可以用它的结合得到的TextBlock:

private void btn_Click_1(object sender, RoutedEventArgs e) 
    { 
     var listBoxItem = OptOccurances.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem; 
     var item = OptOccurances.Items[1] as DumbClass; 
     var tbk = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(listBoxItem, 0),0),0) as TextBlock; 
     var binding = BindingOperations.GetBinding(tbk, TextBlock.TextProperty); 
     var be = BindingOperations.GetBindingExpression(tbk, TextBlock.TextProperty); 
     var vs = DependencyPropertyHelper.GetValueSource(tbk, TextBlock.TextProperty); 
     var val = tbk.GetValue(TextBlock.TextProperty); 
    } 

它显示绑定状态实际上是活动的,并且映射的对象是正确的。很明显,Binding(PropertyPathWorker)的内部工作方式不同,以获取属性的值类型

+0

即使将跟踪设置设置为详细,也没有附加信息。不,结构不是问题 - 它和类一样。不,字符串类型属性工作正常。即使是IsStupid类型的属性也能正常工作(与IStupid相反)。虽然对于wpf跟踪设置,但它似乎是 – 2013-05-01 12:36:35

+0

+1的接口类型。 – 2013-05-01 12:42:15

+0

更新了解决方法 – 2013-05-01 20:40:45