2012-11-27 11 views
6

Ich habe ein Listenfeld, für das ich ItemContainer mit einem Kontextmenü formatiere. Hier ist das XAML für das gleiche."Kein Ziel für Methode gefunden", ausgelöst von Caliburn Message.Attach()

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
    ... 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu> 
        <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"/> 
       </ContextMenu> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Ich habe die Zielmethode in ViewModel wie unten angegeben codiert.

Das ViewModel wird als DataContext des UserControls festgelegt, in dem sich die ListBox befindet.

Der obige Code führt zu "kein Ziel gefunden für Methode". Ich bin mir nicht sicher, warum das nicht funktioniert. Ich habe auch die folgende Variante

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" 
      cal:Action.Target="{Binding ElementName=UCRelayDispositionView, Path=DataContext}"> 

versucht, wobei UCRelayDispositionView der Name des UserControl ist.

Warum funktioniert der obige Code nicht?

Edit: 1 versuchte auch folgende

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" 
      cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView, Path=DataContext}"> 

und dieses

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup" 
      cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView}"> 

EDIT: 2 habe ich versucht, den Tag in der folgenden Weise auf ItemContainer zu verwenden, aber es funktioniert auch nicht.

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Tag" Value="{Binding Path=DataContext, ElementName=UCRelayDispositionView}"/> 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu> 
        <MenuItem Header="Remove Group" 
           cal:Message.Attach="DeleteGroup()" 
           cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"/>          
        </ContextMenu> 
      </Setter.Value> 
    </Style> 
</ListBox.ItemContainerStyle> 

EDIT 3: Bindung Fehler

System.Windows.Data Error: 40 : BindingExpression path error: 'PlacementTarget' property not found on 'object' ''MenuItem' (Name='')'. BindingExpression:Path=PlacementTarget.Tag; DataItem='MenuItem' (Name=''); target element is 'MenuItem' (Name=''); target property is 'TargetWithoutContext' (type 'Object') 
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=UCRelayDispositionView'. BindingExpression:Path=DataContext; DataItem=null; target element is 'ContextMenu' (Name=''); target property is 'Tag' (type 'Object') 

Antwort

10

Ihr Problem liegt darin, dass Sie versuchen, das Ziel zu einem Element zu binden, die in der gleichen visuellen Struktur existiert nicht z.B. Sie haben eine ContextMenu, auf der das Element befindet.

Um ein Aktionsziel korrekt zu erhalten, müssen Sie die ContextMenu s PlacementTarget Eigenschaft verwenden.

Schauen Sie sich die folgende Antwort auf SO für die XAML

WPF Context Menus in Caliburn Micro

So sollte die folgende XAML arbeiten:

<MenuItem Header="Blah" cal:Message.Attach="SomeMethod()" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"> 

Dies ist für die PlacementTarget auf dem ContextMenu aussehen soll und das Ziel gesetzt, für die Aktion auf den Wert von PlacementTarget.Tag (die die ListBoxItem sein sollte).

<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/> 

zum Beispiel:

Wenn Sie setzen ListBoxItem.Tag (wie Sie bereits getan haben) die DataContext des übergeordneten Container zu sein (die ListBox) sollten Sie

so die Tagbindenden sollte ok sein Die ganze Sache sollte sein:

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/> 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"> 
        <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup()" /> 
       </ContextMenu> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ListBox.ItemContainerStyle> 
+0

Ihr Code funktioniert nicht. Gibt immer noch den gleichen Fehler. Was die Verwendung von Tag betrifft, wo platziere ich es? Ich habe dieses Kontextmenü auf ItemContainerStyle! – Jatin

+0

Wenn Sie in den SO-Link, den ich gepostet habe, nachschauen, gibt es ein Beispiel dafür, wo es hingestellt werden soll. Im Grunde müssen Sie die 'ContextMenu.PlacementTarget' -Eigenschaft verwenden, um das Element zu erhalten, das das Kontextmenü hervorgebracht hat, und es an 'DataContext' zu binden, obwohl Sie möglicherweise den' DataContext' des übergeordneten Containers in die 'Tag'-Eigenschaft hacken müssen . Dies funktioniert für mich (es könnte sich lohnen, ein Ereignis in der Ansicht zu erstellen, nur damit Sie in den Code-Behind gelangen und debuggen können, wenn Sie auf den Menüeintrag klicken. Auf diese Weise können Sie das Objektdiagramm untersuchen und den korrekten Bindungspfad ermitteln) – Charleh

+0

Ich habe die als ** EDIT 2 ** markierte Frage bearbeitet. Ich bin mir nicht sicher, ob wir Style verwenden können, um das Tag so einzustellen, aber derselbe Fehler bleibt bestehen. – Jatin