2012-11-27 15 views
6

Ho una casella di riepilogo per la quale sto creando ItemContainer per includere un menu di scelta rapida. Ecco lo xaml per lo stesso."Nessun obiettivo trovato per il metodo" generato da 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> 

Ho codificato il metodo di destinazione in ViewModel come indicato di seguito.

public void DeleteGroup() { //ToDo 
    ... 
} 

Il ViewModel è impostata come DataContext dell'UserControl in cui v'è la ListBox.

Il codice sopra riportato è "Nessun obiettivo trovato per il metodo". Non sono sicuro del motivo per cui questo non funziona. Ho anche provato il seguente variante

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

dove UCRelayDispositionView è il nome dell'UserControl.

Perché il codice sopra riportato non funziona?

Edit: 1 provato anche il seguente

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

e questo

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

EDIT: 2 ho cercato di utilizzare il tag nel seguente modo su ItemContainer ma non funziona neanche.

<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: Legatura errori

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') 

risposta

10

Il tuo problema è che si sta cercando di legare il target a un elemento che non esiste nella stessa struttura ad albero visuale per esempio hai un ContextMenu su cui risiede l'elemento.

Per ottenere correttamente un obiettivo di azione, è necessario utilizzare la proprietà s ContextMenu s.

Partenza la seguente risposta su SO per il XAML

WPF Context Menus in Caliburn Micro

Così il seguente XAML dovrebbe funzionare:

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

Questo dovrebbe cercare il PlacementTarget sulla ContextMenu e impostare il target per l'azione al valore di PlacementTarget.Tag (che dovrebbe essere il ListBoxItem).

Se si imposta ListBoxItem.Tag (come avete già fatto) di essere il DataContext del contenitore principale (la ListBox) si dovrebbe essere ok

così il legame tag deve essere:

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

esempio il tutto dovrebbe essere:

<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

Il tuo codice non funziona. Dà ancora lo stesso errore. Per quanto riguarda l'utilizzo di Tag, dove lo metto? Ho questo menu contestuale su ItemContainerStyle! – Jatin

+0

Se hai un aspetto nel link SO che ho postato, c'è un esempio di dove metterlo. Fondamentalmente è necessario utilizzare la proprietà 'ContextMenu.PlacementTarget' per ottenere l'elemento che ha generato il menu di scelta rapida e associarlo a' DataContext', anche se potrebbe richiedere l'hacking del 'DataContext' del contenitore padre nella proprietà' Tag' . Questo funziona per me (potrebbe valere la pena creare un evento nella vista solo così puoi entrare nel code-behind e fare il debug quando fai clic sulla voce del menu. In questo modo puoi esplorare il grafico dell'oggetto e scoprire il percorso di binding corretto) – Charleh

+0

Ho modificato la domanda contrassegnata come ** EDIT 2 **. Non sono sicuro se possiamo usare Style per impostare il Tag in questo modo, ma lo stesso errore rimane. – Jatin

Problemi correlati