Context menu does not get updated properly

Hello,

I have a context menu in my diagram with two entries, copy and paste, which are supposed to be activated depending on whether a node/link is selected or data is in the Clipboard respectively.

<go:Diagram.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Copy" Command="{Binding Path=Diagram.CommandHandler.CopyCommand}">
            <MenuItem.Icon>
                <cctrl:AutoGreyableImage Source="../Images/copy16x16.png"/>
            </MenuItem.Icon>
        </MenuItem>
        <MenuItem Header="Paste" Command="{Binding Path=Diagram.CommandHandler.PasteCommand}">
            <MenuItem.Icon>
                <cctrl:AutoGreyableImage Source="../Images/paste16x16.png"/>
            </MenuItem.Icon>
        </MenuItem>
    </ContextMenu>
</go:Diagram.ContextMenu>

I have overridden the Copy/CanCopy as well as Paste/CanPaste methods in a custom CommandHandler as I’m working with a custom app internal Clipboard. When a node is selected I can right click and the copy-button is active. Now, when I right click again, the paste-button should be enabled as there’s data in my clipboard but actually that button is still disabled. When I deselect my currently selected node and do a right click again, the paste button is suddenly enabled just as desired before.
It seems the CanPaste method does not get called upon opening the context menu but only when the selection changes. I tried to call the method on copying but that doesn’t do anything of course. How can I get the menu buttons checked when the menu opens, not when the diagram’s selection changes?

This isn’t exactly a GoXam-specific issue, but I think you can somehow raise an event to get the RoutedUICommand to re-evaluate. Maybe CommandManager.InvalidateRequerySuggested ?

I thought it was as a SelectionChanged triggered the re-evaluation but it seems it is triggered by a focus change. I’ll try to find a solution.

Alright, it works if I set the DataContext to null if the context menu is invisible

<ContextMenu.Style>
    <Style TargetType="{x:Type ContextMenu}">
        <Style.Triggers>
            <Trigger Property="IsVisible" Value="False">
                <Setter Property="DataContext" Value="{x:Null}"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</ContextMenu.Style>

However, I have the same problem with Ctrl+C. Copying doesn’t work after I dropped a node in the diagram. Neither Copy nor CanCopy are being called, despite the node being selected. But it works if I un- and reselect the node.

Found a solution. Problem is that the diagram loses focus when I click+drag a node from the palette and doesn’t get it back afterwards, so I just set the keyboard focus manually in the ExternalObjectsDropped event.

Yes, we’ve been wondering for a while whether a successful external drop should change the focus automatically to the dropped-in Diagram.

As I would expect it does I’d say it should.

To be clear, the target Diagram never loses focus because it never gets it during the drag-and-drop operation from the Palette. The Palette retains focus throughout the process.

The reason we did not have the target Diagram gain focus upon a drop is so that the user can continue to perform other commands in the Palette. And due to a general notion that we wanted to minimize the focus changes that the library does, since that can be disorienting to the user. However, this case might be a reasonable exception to that.

Note that it is trivial to implement this yourself just by implementing a Diagram.ExternalObjectsDropped event handler that changes focus to the target Diagram. I suppose that’s another reason why we didn’t do that automatically.

I see. Yes, the solution is actually quite simple as soon as you realize what’s causing the unexpected behavior. In my case especially because I already had an ExternalObjectsDropped event handler implemented and just needed to add that one line.