绑定到接口类型的属性

时间:2013-04-30 22:16:20

标签: .net wpf wpf-4.0

我对WPF中的另一个有点怪异感到不满。请考虑以下类及其名为IStupid的{​​{1}}类型属性:

MyStupid

现在考虑以下绑定到public struct DumbClass { public IStupid MyStupid { get { return new IsStupid(); } } } public interface IStupid{} public class IsStupid : IStupid{}

ListBox

xaml没有什么特别之处:

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

正如预期的那样,列表框的输出是3行“MyProject.DumbClass”。

但是,如果我设置<ListBox Name="OptOccurances" Height="238" HorizontalAlignment="Left" Margin="130,34,0,0" VerticalAlignment="Top" Width="229" > </ListBox> (或创建一个ItemTemplate,将'MyStupid'直接绑定到模板中的TextBlock),我会得到3个空行,而我预计它会说DisplayMemberPath="MyStupid"。为什么数据绑定引擎无法调用默认的MyProject.IsStupid实现并显示类名。是否有接口类型属性的解决方法?至少,有没有理由不抛出绑定错误?

1 个答案:

答案 0 :(得分:3)

我可以重现这个问题。它看起来像WPF bug。

以下是您可以使用的解决方法: 您可以使用Item的DataTemplate和StringFormat参数代替DisplayMemberPath,它会强制将属性值转换为字符串:

    <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 Visualizer for Visual Studio 2012,它允许您直接从调试Watch调查树: 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状态实际上是活动的,并且映射的对象是正确的。显然,Binding的内部结构(PropertyPathWorker)在获取属性的类型属性

时的工作方式不同