2011-12-07 12 views
5

que tienen dos clases con propiedades diferentes, pero ambos heredan alguna otra clase de base:¿Cómo manejar enlaces cuando el objeto fuente puede no tener la propiedad dada?

public class BaseClass { } 

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

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

de código subyacente:

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

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

Y mi XAML se parece a esto:

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

Cuando se ejecuta en modo de depuración, la ventana de salida muestra esto:

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')

¿Hay una forma mejor de manejar encuadernaciones como estas? ¿Hay alguna implicación en el rendimiento, y es mejor utilizar FallbackValue = '' o FallbackValue = {x: Null}?

+0

enfrento exactamente el mismo problema y estoy ansioso por ver una buena solución a esa pregunta ! – SvenG

Respuesta

6

Personalmente simplemente ignorarlos. Si un artículo no existe, se muestra como una cadena vacía, que generalmente es lo que prefiero.

Son advertencias en la ventana de depuración porque son simplemente advertencias, no errores. Te están advirtiendo sobre un posible problema, pero no pasará nada malo si los ignoras.

Si realmente te molesta, probablemente puedas utilizar una columna de plantilla y especificar diferentes plantillas de datos para los diferentes tipos de objetos.

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

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

yo también a veces utilizar un convertidor que devuelve typeof(value), y el uso de ese tipo en un 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

¿Sabe si las advertencias en la ventana de resultados tienen un impacto negativo en el rendimiento? – SvenG

+2

@SvenG No lo creo. Las advertencias solo aparecen en el modo de depuración, y ni siquiera existirían en el modo de lanzamiento. Aquí hay una respuesta SO relacionada: http://stackoverflow.com/a/2594600/302677 – Rachel

+0

¡Muchas gracias por esa aclaración! – SvenG

0

yo preferiría siguiente manera:

Escribir un convertidor de valor personalizado implementar IMultiValueConverter. En este convertidor puede verificar los valores entrantes, elegir el válido y devolver ese valor.

en XAML añadir un MultiBinding así:

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

Esto supone que quiero mostrar una u otra propiedad. Si este fuera el caso, probablemente iría por un PriorityBinding, pero en realidad quiero valores vacíos si la propiedad no se encuentra en el objeto. – snurre

Cuestiones relacionadas