2010-06-10 5 views
6

Dieses Beispiel ist zugegebenermaßen ein wenig erfunden, aber ich mache etwas ähnliches. Lassen Sie uns sagen, dass ich die folgenden einfachen Klassen haben:Gibt es eine einfache Möglichkeit, eine WPF-Datenbindung anzugeben, bei der der Pfad eine Ebene höher ist?

public class Person 
{ 
    public string Name { get; set; } 
    public List<Alias> Aliases { get; set; } 
} 

public class Alias 
{ 
    public string AliasName { get; set; } 
} 

Und lassen Sie uns sagen, dass ich XAML mit einem LayoutRoot Gitter haben, und ein Datagrid, wo ich statt der Aliases Eigenschaften die Eigenschaft Name im Datagrid zugreifen möchten wie in der zweiten Spalte hier:

<Grid x:Name="LayoutRoot" DataContext="PersonInstance"> 
    <DataGrid ItemsSource="{Binding Aliases}"> 
     <DataGrid.Columns> 
      <data:DataGridTextColumn Header="AliasName" Binding="{Binding AliasName, Mode=TwoWay}"/> 
      <data:DataGridTextColumn Header="Name" Binding="{Binding ../Name, Mode=TwoWay}"/> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

intuitiv ist, wie ich den Namen zu binden versuchen würde, aber es ist unnötig zu sagen, dass dumm aussieht. Gibt es bei der Angabe eines Pfades etwas Ähnliches oder müssen Sie eine relative Quelle zum LayoutRoot-Datenkontext abrufen. Wenn es sein muss, was ist der effizienteste Weg?

+0

Warum funktioniert das nicht? 'Binding =" {Binding Name, Modus = TwoWay} "' – Amsakanna

+0

@Veer, weil es keine Name-Eigenschaft in der Klasse Alias ​​gibt ... – Anvaka

+0

@Anvaka: Aber der Datenkontext ist die Instanz der Personenklasse. Es sollte die Name-Eigenschaft kennen. – Amsakanna

Antwort

10

Dies sollte für Sie arbeiten:

<DataGridTextColumn Header="Name" 
        Binding="{Binding RelativeSource={RelativeSource 
                 FindAncestor, 
                 AncestorLevel=3, 
                 AncestorType={x:Type Grid}, 
                 Mode=FindAncestor}, 
                Path=DataContext.Name}"/> 

Sie eine der verwenden können folgende:

Um das Quellelement der nächsten übergeordneten eines bestimmten Typs gleich zu machen:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type 
desiredType}}} 

Um das Quellelement gleich dem n-ten nächstliegenden Elternteil eines gegebenen Typs zu machen:

{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorLevel=n, AncestorType={x:Type desiredType}}} 

Um das Quellelement, um das vorherige Datenelement in einer datengebundenen Sammlung gleich:

{Binding RelativeSource={RelativeSource PreviousData}} 
+1

Dies ist unverschämt ausführlich. Ihr erstes Beispiel sollte geschrieben werden: {Binding RelativeSource = {RelativeSource FindAncestor, Grid, 3}} '. Die anderen sollten ebenfalls vereinfacht werden. Jeder, der die Funktion von FindAncestor versteht, wird 'FindAncestor, Grid, 3' genauso leicht verstehen wie Ihre vier Codezeilen und mit weniger Nachdenken. –

0

Ich denke, es gibt keinen besseren Weg, dies zu tun, als relativ Quelle auf den Baum mit. Sie könnten Ihr Modell neu schreiben (zum Beispiel, fügen Sie einen Verweis auf Eltern Person von Alias), aber das ist kaum besser Ansatz.

Aus Performance-Perspektive habe ich nie Engpässe in relativen Quellbindungen gefunden. Es gibt immer etwas anderes, das deine App von Raketengeschwindigkeit fernhält.

Verwandte Themen