4

我刚刚被 WPF 中的另一个具有约束力的怪异所吸引。考虑以下类及其IStupid名为的类型化属性MyStupid

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

现在考虑以下对 a 的绑定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()实现并显示类名。接口类型属性是否有解决方法?至少,有没有抛出绑定错误的原因?

4

1 回答 1

3

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

这是您可以使用的解决方法:您可以使用带有 StringFormat 参数的 Item 的 DataTemplate 而不是 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 Trace Settings 来解决此类问题: 在此处输入图像描述

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

此外,您可以使用 WPF Visualizer for Visual Studio 2012,它允许您直接从调试观察中调查树: 在此处输入图像描述

使用以下代码,您可以获得 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)的内部结构在获取属性类型的情况下的值不同

于 2013-04-30T22:46:15.813 回答