当源对象可能没有给定属性时如何处理绑定?

snu*_*rre 7 c# wpf binding fallbackvalue

我有两个具有不同属性的类,但都继承了其他一些基类:

public class BaseClass { }

public class ClassA : BaseClass
{
    public string PropertyA { get; set; }
}

public class ClassB : BaseClass
{
    public string PropertyB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

代码隐藏:

public ObservableCollection<BaseClass> Items { get; set; }

public MainWindow()
{
    Items = new ObservableCollection<BaseClass>
        {
            new ClassA {PropertyA = "A"},
            new ClassB {PropertyB = "B"}
        };
}
Run Code Online (Sandbox Code Playgroud)

我的XAML看起来像这样:

<ListView ItemsSource="{Binding Items}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding PropertyA, FallbackValue=''}"/>
            <GridViewColumn DisplayMemberBinding="{Binding PropertyB, FallbackValue={x:Null}}"/>
        </GridView>
    </ListView.View>
</ListView>
Run Code Online (Sandbox Code Playgroud)

在调试模式下运行时,输出窗口显示:

System.Windows.Data警告:40:BindingExpression路径错误:'object'''ClassA'(HashCode = 66437409)'找不到'PropertyB'属性.BindingExpression:路径= PropertyB; DataItem ='ClassA'(HashCode = 66437409); target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')

System.Windows.Data警告:40:BindingExpression路径错误:'对象'''ClassB'(HashCode = 2764078)'上找不到'PropertyA'属性.BindingExpression:路径= PropertyA; DataItem ='ClassB'(HashCode = 2764078); target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')

有没有更好的方法来处理像这样的绑定?是否有任何性能影响,使用FallbackValue =''或FallbackValue = {x:Null}是否更好?

Rac*_*hel 6

就个人而言,我只是忽略它们.如果某个项目不存在,它将显示为空字符串,这通常是我喜欢的.

它们是调试窗口中的警告,因为它们只是警告,而不是错误.他们会警告你一个可能存在的问题,但是如果忽略它们就不会发生任何不好的事情.

如果它真的困扰你,你可以使用模板列并为不同的对象类型指定不同的DataTemplates.

<DataTemplate TargetType="{x:Type local:ClassA}">
    <TextBlock Text="{Binding PropertyA}" />
</DataTemplate>

<DataTemplate TargetType="{x:Type local:ClassB}">
    <TextBlock Text="{Binding PropertyB}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

我有时也会使用一个返回的转换器typeof(value),并在DataTrigger中使用该类型

<Style.Triggers>
    <DataTrigger Value="{x:Type local:ClassA}" 
                 Binding="{Binding Converter={StaticResource ObjectToTypeConverter}}">
        <Setter Property="Text" Value="{Binding PropertyA}" />
    </DataTrigger>
    <DataTrigger Value="{x:Type local:ClassB}" 
                 Binding="{Binding Converter={StaticResource ObjectToTypeConverter}}">
        <Setter Property="Text" Value="{Binding PropertyB}" />
    </DataTrigger>
</Style.Triggers>
Run Code Online (Sandbox Code Playgroud)

  • 唯一的问题是,现在,根据应用程序的大小,您最终会在输出窗口中显示"警告",其中一些可能是可接受的,如上所述,还有一些值得调查.我宁愿WPF提供一种方式让我在绑定中指定"如果这个绑定失败就不要警告我"然后我知道如果弹出BindingExpression警告,那就是我需要调查的东西.它类似于在构建时不需要编译时警告.如果您开始允许某些警告持续存在,则会妨碍您识别实际问题的能力. (3认同)
  • @SvenG我不这么认为.警告仅出现在调试模式下,甚至在发布模式下也不会出现.这是一个相关的SO答案:http://stackoverflow.com/a/2594600/302677 (2认同)