2011-12-07 4 views
5

ho due classi con proprietà diverse, ma entrambi ereditano qualche altra classe di base:Come gestire i binding quando l'oggetto di origine potrebbe non avere la proprietà data?

public class BaseClass { } 

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

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

Codice-behind:

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

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

E il mio XAML assomiglia a questo:

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

Quando si esegue in modalità di debug, la finestra di output mostra questo:

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'è un modo migliore di gestire associazioni come queste? Ci sono implicazioni sul rendimento, ed è meglio usare FallbackValue = '' o FallbackValue = {x: Null}?

+0

io faccia esattamente lo stesso problema e sono ansioso di vedere una buona soluzione a questa domanda ! – SvenG

risposta

6

Personalmente ho appena li ignorano. Se un elemento non esiste, viene visualizzato come una stringa vuota, che di solito è ciò che preferisco.

Si tratta di avvisi nella finestra di debug perché si tratta semplicemente di avvisi, non di errori. Ti avvertono di un possibile problema, ma non accadrà nulla di brutto se li ignorerai.

Se davvero ti infastidisce, puoi probabilmente usare una colonna modello e specificare diversi DataTemplates per i diversi tipi di oggetto.

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

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

io a volte anche utilizzare un convertitore che restituisce typeof(value), e utilizzare quel tipo in 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

Sapete se gli avvisi nella finestra di output hanno un impatto negativo sulle prestazioni? – SvenG

+2

@SvenG Io non la penso così. Gli avvertimenti appaiono solo in modalità debug e non esisterebbero mai nemmeno in modalità di rilascio. Ecco una risposta SO correlata: http://stackoverflow.com/a/2594600/302677 – Rachel

+0

Grazie mille per questo chiarimento! – SvenG

0

io preferirei seguente modo:

Scrivi un convertitore di valore personalizzato attuazione IMultiValueConverter. In questo convertitore puoi controllare i valori in entrata, scegliere quello valido e restituire quel valore.

in XAML aggiungere un MultiBinding del genere:

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

Si presume che voglio una o l'altra proprietà visualizzata. Se fosse così, preferirei preferire un PriorityBinding, ma in realtà voglio valori vuoti se la proprietà non viene trovata sull'oggetto. – snurre