C# WPF Command Binding

Donnidonis

Commander
Registriert
Apr. 2009
Beiträge
2.711
Guten Tag,
ich habe nen kleines Problem mit einem Command Binding.
Folgender Code:
Code:
<ListView ItemsSource="{Binding ComboBoxValues}">
                   <ListView.ItemTemplate>
                       <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox IsChecked="{Binding Item1, Mode=TwoWay}"/>
                                <TextBlock Text="{Binding Item2, Mode=TwoWay}"></TextBlock>
                           </StackPanel>
                       </DataTemplate>
                   </ListView.ItemTemplate>
               </ListView>

Problem ist, ich möchte in der Checkbox ein Command Binding erstellen, kann aber nur auf Elemente der ComboBoxValues Zugreifen, Wie kann ich das Command denn an das Übergeordnete ViewModel weitergeben?

Liebe Grüße
 
So? :)
Code:
<ListView ItemsSource="{Binding ComboBoxValues}">
  <ListView.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <CheckBox IsChecked="{Binding Item1, Mode=TwoWay}" Command="{Binding DataContext.SomeCommand, RelativeSource={RelativeSource AncestorType=ListView}}"/>
        <TextBlock Text="{Binding Item2, Mode=TwoWay}" />
      </StackPanel>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>
 
Perfekt, dann funktioniert so wie es soll.
Doch jetzt habe ich natürlich noch die Frage warum es funktioniert.
Hole ich mir über die RelativeSource und dem AncestorType=ListView den Context, in dem die ListView drin liegt?
Oder wie genau funktioniert das?
 
Wenn du keine Bindungsquelle explizit angibst, wird immer der jeweilige Datenkontext des Objekts verwendet. Das ist in diesem Fall der Datenkontext deiner ComboBoxValues-Objekte.
RelativeSource überschreibt die Bindungsquelle; mit AncestorType wird dabei der Visual Tree nach oben durchlaufen, bis die erstbeste ListView gefunden wurde.
Da die Quelle dann aber direkt auf die ListView zeigt und nicht auf den Datenkontext (dein ViewModel), musst du DataContext.SomeCommand schreiben. DataContext ist eine Eigenschaft vom ListView, darin wird dein ViewModel "gespeichert".

Du kannst ja aus Spaß mal
Code:
<TextBlock Text="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
ausprobieren. Damit bindest du nicht an dein ViewModel (ListView.DataContext), sondern an die Eigenschaften der ListView selber. Deine Textblöcke sollten dann direkt die ListView-Höhe widerspiegeln.

Hoffe, ich habe das jetzt nicht zu umständlich beschrieben. :freak:

Ergänzung:
Ggf. wirst du in den Weiten des Webs auf die ausführliche Schreibweise treffen:
Code:
Command="{Binding DataContext.SomeCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}"
Da du ja den AncestorType angegeben hast, kommt der Compiler auch ohne Mode=FindAncestor klar; kann also weggelassen werden. Wollte es nur der Vollständigkeit halber angeben.
 
Zuletzt bearbeitet:
Perfekt, und keine Panik, nicht zu kompliziert beschrieben, sondern für mich genau richtig! Vielen Dank!
 
Zurück
Oben