绑定到接口类型属性 [英] Binding to interface typed properties

查看:178
本文介绍了绑定到接口类型属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚位在WPF又结合怪胎。考虑下面的类和它的 IStupid 类型属性名为 MyStupid

I just got bit by yet another binding oddity in WPF. Consider the following class and its IStupid typed property called MyStupid:

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

现在考虑下面结合一个列表框

Now consider the following binding to a ListBox:

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

没有什么特别之处的XAML:

There is nothing special about the xaml:

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

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

As expected, the output of the listbox is 3 rows of "MyProject.DumbClass".

但是,如果我设置的DisplayMemberPath =MyStupid(或创建一个ItemTemplate,结合直接MyStupid模板中一个TextBlock),我得到3个空行,而不是当我预期它说 MyProject.IsStupid 。为什么数据绑定引擎无法调用默认的ToString()实施并显示类名。有一种解决方法的接口类型的属性?最起码,是有一个原因,为什么没有约束力引发错误?

However if I set DisplayMemberPath="MyStupid" (or create an ItemTemplate, binding 'MyStupid' directly to a TextBlock in the template), I get 3 empty rows instead, when I expected it to say MyProject.IsStupid. Why is the databinding engine unable to call the default ToString() implementation and display the class name. Is there a workaround for a interface typed property? At the very least, is there a reason why no binding error is thrown?

推荐答案

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

I can reproduce this issue. It looks like WPF bug.

下面是可以使用的解决方法: 相反的DisplayMemberPath的,您可以使用项目的DataTemplate中使用的StringFormat参数,这将有力地转换属性值的字符串:

Here is the workaround you can use: Instead of DisplayMemberPath, you can use Item's DataTemplate with StringFormat parameter, which will forcefully convert property value to string:

    <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跟踪设置,以找出这样那样的问题:

Generally you can use WPF Trace Settings to figure out such kind of problems:

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

But in this case as I see no binding errors happen.

此外,您可以使用WPF可视化的Visual Studio 2012,它允许你去调查从调试观看棵树:

Additionally you can use WPF Visualizer for Visual Studio 2012, which allows you to investigate tree right from the debug Watch:

使用下面的code,你可以得到的TextBlock与其绑定:

Using the following code you can get TextBlock with its binding:

    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);
    }

和它表明绑定状态实际上是主动和映射的对象是正确的。显然,内部(PropertyPathWorker)的结合原理不同的情况下获得的价值属性类型

And it shows that Binding status is actually active and the object mapped is correct. Obviously internals of Binding (PropertyPathWorker) works differently for getting the value in case type of property

这篇关于绑定到接口类型属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆