2011-12-07 21 views
5

Tôi có hai lớp với các thuộc tính khác nhau, nhưng cả hai thừa hưởng một số lớp cơ sở khác:Cách xử lý các ràng buộc khi đối tượng nguồn có thể không có thuộc tính đã cho?

public class BaseClass { } 

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

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

Mã-đằng sau:

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

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

Và XAML của tôi trông như thế này:

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

Khi chạy trong chế độ gỡ lỗi, cửa sổ đầu ra hiển thị điều này:

System.Windows.Data Warning: 40 : BindingExpression path error: 'PropertyB' property not found on 'object' ''ClassA' (HashCode=66437409)'. BindingExpression:Path=PropertyB; DataItem='ClassA' (HashCode=66437409); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

System.Windows.Data Warning: 40 : BindingExpression path error: 'PropertyA' property not found on 'object' ''ClassB' (HashCode=2764078)'. BindingExpression:Path=PropertyA; DataItem='ClassB' (HashCode=2764078); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

Có cách nào tốt hơn để xử lý các ràng buộc như thế này không? Có bất kỳ tác động nào về hiệu năng hay không và sử dụng FallbackValue = '' hoặc FallbackValue = {x: Null} có tốt hơn không?

+0

tôi phải đối mặt với chính xác cùng một vấn đề và tôi mong muốn thấy một giải pháp tốt cho câu hỏi đó ! – SvenG

Trả lời

6

Cá nhân tôi chỉ cần bỏ qua chúng. Nếu một mục không tồn tại, nó sẽ được hiển thị dưới dạng một chuỗi rỗng, thường là những gì tôi thích.

Chúng là cảnh báo trong cửa sổ gỡ lỗi vì chúng đơn giản là cảnh báo chứ không phải lỗi. Họ cảnh báo bạn về một vấn đề có thể xảy ra, nhưng không có gì xấu xảy ra nếu bạn bỏ qua chúng.

Nếu nó thực sự làm phiền bạn, bạn có thể sử dụng cột mẫu và chỉ định DataTemplates khác nhau cho các loại đối tượng khác nhau.

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

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

Tôi cũng sẽ đôi khi sử dụng một Converter mà trả typeof(value), và sử dụng loại đó trong một 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> 
+0

Bạn có biết cảnh báo trong cửa sổ đầu ra có tác động tiêu cực không? – SvenG

+2

@SvenG Tôi không nghĩ vậy. Các cảnh báo chỉ xuất hiện trong chế độ Gỡ lỗi và sẽ không bao giờ tồn tại trong chế độ Phát hành. Đây là câu trả lời có liên quan của SO: http://stackoverflow.com/a/2594600/302677 – Rachel

+0

Cảm ơn rất nhiều vì đã làm rõ! – SvenG

0

Tôi thích theo cách sau:

Viết công cụ chuyển đổi giá trị tùy chỉnh triển khai IMultiValueConverter. Trong bộ chuyển đổi này, bạn có thể kiểm tra các giá trị đến, chọn giá trị hợp lệ và trả lại giá trị đó.

Trong XAML thêm một MultiBinding như thế:

<MultiBinding Converter="{StaticResource ResourceKey=myMultiValueConverter}" ConverterParameter="SomeParameterIfNecessary"> 
    <Binding "ToTheFirstClass.PropertyA" /> 
    <Binding "ToTheSecondClass.PropertyB" /> 
</MultiBinding> 
+0

Giả sử tôi muốn một hoặc một thuộc tính khác được hiển thị. Nếu đây là trường hợp, tôi có lẽ sẽ đi cho một PriorityBinding thay vào đó, nhưng tôi thực sự muốn có giá trị sản phẩm nào nếu tài sản không được tìm thấy trên đối tượng. – snurre

Các vấn đề liên quan