9

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

public class BaseClass { }

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

public class ClassB : BaseClass
{
    public string PropertyB { get; set; }
}

代码隐藏:

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

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

我的 XAML 看起来像这样:

<ListView ItemsSource="{Binding Items}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding PropertyA, FallbackValue=''}"/>
            <GridViewColumn DisplayMemberBinding="{Binding PropertyB, FallbackValue={x:Null}}"/>
        </GridView>
    </ListView.View>
</ListView>

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

System.Windows.Data 警告:40:BindingExpression 路径错误:在“对象”“ClassA”(HashCode=66437409)上找不到“PropertyB”属性。绑定表达式:路径=属性B;DataItem='ClassA' (HashCode=66437409); 目标元素是'TextBlock'(名称='');目标属性是“文本”(类型“字符串”)

System.Windows.Data 警告:40:BindingExpression 路径错误:在“对象”“ClassB”(HashCode=2764078)上找不到“PropertyA”属性。绑定表达式:路径=属性A;DataItem='ClassB' (HashCode=2764078); 目标元素是'TextBlock'(名称='');目标属性是“文本”(类型“字符串”)

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

4

3 回答 3

7

我个人只是忽略它们。如果一个项目不存在,它会显示为一个空字符串,这通常是我喜欢的。

它们是调试窗口中的警告,因为它们只是警告,而不是错误。他们警告您可能出现的问题,但如果您忽略它们,不会发生任何不好的事情。

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

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

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

我有时也会使用返回的 Converter 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>
于 2011-12-07T15:26:03.233 回答
2

消除此警告的简单选项是使用PriorityBinding@snurre 提到的方法,如下所示:

<GridViewColumn.DisplayMemberBinding>
    <PriorityBinding>
        <Binding Path="PropB" />
    </PriorityBinding>
</GridViewColumn.DisplayMemberBinding>

PropB缺少属性不会出现警告。

于 2018-09-27T07:22:15.037 回答
0

我更喜欢以下方式:

编写一个自定义值转换器实现IMultiValueConverter. 在此转换器中,您可以检查传入的值,选择有效的值并将该值返回。

在 Xaml 中添加这样的 MultiBinding:

<MultiBinding Converter="{StaticResource ResourceKey=myMultiValueConverter}" ConverterParameter="SomeParameterIfNecessary">
    <Binding "ToTheFirstClass.PropertyA" />
    <Binding "ToTheSecondClass.PropertyB" />
</MultiBinding>
于 2011-12-07T12:23:23.020 回答