2016-06-20 16 views
1

Ich habe ein Benutzersteuerelement erstellt, das ViewModelA() als sein ViewModel hat, dann befindet sich in meiner View ein StackPanel, das ViewModelA.Data als DataContext verwendet.Wie bekomme ich mein original ViewModel?

Mein Problem ist in diesem StackPanel, ich habe eine Schaltfläche, die meine erstellte ICommand in ViewModelA() implementieren muss. Wie kann ich das machen?

Gibt es etwas wie <Button DataContext="DataContext.Parent" /> oder so ähnlich?

Hier ist, wie ich meine Viewmodel und View implementiert:

App.xaml

<DataTemplate DataType="{x:Type vm:ViewModelA}"> 
    <vw:ViewA /> 
</DataTemplate> 

ViewA.xaml (wo der Knopf innerhalb des Stapels Panel sollte die ICommand implementieren)

<StackPanel x:Name="RightPaneDetails" 
      Grid.Column="1" 
      Margin="15,0,0,30" 
      DataContext="{Binding Data}"> 
    <!-- Some controls goes here that binds to ViewModelA.Data properties --> 
    <StackPanel Orientation="Horizontal"> 
     <Button DataContext={Binding} Command="{Binding LookupCommand}" /> <!-- This button should implement the ViewModelA.LookupCommand --> 
    </StackPanel> 
</StackPanel> 

TIA

PS, ViewModelA.Data ist mein Modell.

+0

Datacontext geerbt wird die visuelle Struktur nach unten bewertet werden, um sicherzustellen, gibt es keine Notwendigkeit Datacontext überhaupt angeben. Entfernen Sie den gesamten DataContext in ViewA. Alle Steuerelemente sollten ihren DataContext zurück auf ViewModelA setzen. – Jai

+0

Ja, ich verstehe. Aber meine Steuerelemente (Textfelder und Beschriftungen) sind von den Eigenschaften von ViewModelA.Data begrenzt ... Wäre es hässlich, wenn ich ' ............' dann in alle entfernen würde Meine Bindung steuert als '' –

+0

Versuchen Sie AnjumSKhan Antwort ohne den DataContext-Teil. – Jai

Antwort

1

Es sieht so aus, als ob Sie in Ihrem UC DataContext als ViewModelA eingestellt haben. So können Sie verwenden

<Button DataContext={Binding} Command="{Binding DataContext.LookupCommand, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" />

Es auch geschrieben werden kann:

<Button DataContext={Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor} } Command="{Binding LookupCommand}" />

+0

Sieht gut aus! Ich dachte, dies wird es lösen, aber es funktioniert immer noch nicht ... –

+0

Ich machte Annahmen in Bezug auf den DataContext Ihrer Benutzersteuerung. Zeig deinen vollen XAML. – AnjumSKhan

+0

Sehen Sie sich den DataContext der Steuerelemente genauer an, indem Sie entweder Snoop oder den Live-Property-Explorer (VS2015) verwenden. – lokusking

0

Obwohl @ AnjumSKhan Lösung richtig ist, ich möchte alternative Lösung vorzuschlagen:

<StackPanel x:Name="RightPaneDetails"> <!-- do not set bind datacontext here --> 

    <!-- Some controls goes here that binds to ViewModelA.Data properties, e.g: --> 
    <TextBlock Text="{Binding Data.SomeProperty}" /> 
    <!-- If there too many elements bound to Data, you can group them in stackpanel --> 


    <StackPanel Orientation="Horizontal"> 
     <!-- This button is databound to ViewModelA.LookupCommand 
      DataContext doesn't have to be set, since it's inherited from parent. Actually entire stackpanel is redundant here--> 
     <Button Command="{Binding LookupCommand}" /> 
    </StackPanel> 
</StackPanel> 

Wie Sie sehen können, habe ich es einfach vermieden, DataContext auf die übergeordneten RightPaneDetails zu setzen, damit die untergeordneten c eine leicht beide Eigenschaften des ViewModelA.Data zugreifen (TextBlock-) und ViewModelA Eigenschaften (Button)


Ein paar andere Hinweise:

  1. Hinweis, dass anstelle von

    RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor} 
    

    können Sie schreiben einfach

    RelativeSource={RelativeSource AncestorType=UserControl} 
    
  2. Alternative Lösung Relative ist Elementname:

    <StackPanel x:Name="Root"> 
        <StackPanel DataContext="{Binding Data}"> 
        <Button Command="{Binding DataContext.LookupCommand, ElementName=Root}" /> 
    

    ich diese preffer weil Existenz von „Root“ Elemente bei der Kompilierung überprüft wird, und es ist besser lesbar.

  3. vermeiden und Datacontext eine andere Eigenschaft auf dem gleichen Element zu binden, z:

    <Button DataContext="{Binding....}" Command="{Binding ...}" /> 
    

    Es gibt keine Garantie, die zuerst ausgewertet wird verbindlich.Sie können jedoch eingestellt IsAsyc Wahr = auf die zweite Bindung Command={Binding ..., IsAsync=True} es später als nicht async Bindungen

+0

Ich dachte auch darüber nach. Aber anscheinend findet OP das hässlich. Für meine persönliche Vorliebe würde ich diese Methode auch wählen. Die Bindung wird komplizierter, wenn Sie DataContext an verschiedenen Teilen zuweisen. Ich würde es vorziehen, dass die gesamte View den vererbten DataContext verwendet und mehr Wirkung beim Schreiben von verketteten Bindungspfaden hat. – Jai

Verwandte Themen