Kolejny post ‘ku pamięci’, abym w przyszłości nie musiał tego szukać.

Bawiłem się ostatnio przyciskiem, który ma pokazywać ContextMenu po naciśnięciu przycisku. Kod wyglądał (mniej więcej) następująco:

<Button Content=”ContextMenu” Click=”Button_Click”>                           

    <Button.ContextMenu>

        <ContextMenu x:Name=”menu”>

            <MenuItem Header=”Item 1″ Command=”ApplicationCommands.Close” />

            <MenuItem Header=”Item 2″ Command=”ApplicationCommands.Open” />

        ContextMenu>

    Button.ContextMenu>

Button>

Jak widać wykorzystuję Commands. Automatyczne pojawianie się ContextMenu po przyciśnięciu prawego przycisku działało bez problemu, tak więc nie spodziewałem się problemów z kodem poniżej:

private void Button_Click(object sender, RoutedEventArgs e)

{

    menu.IsOpen = true;

}

Jednak ku mojemu zdziwieniu tak o to wyglądało menu:cm

I oczywiście CanExecute zawsze ustawiało e.CanExecute = true.

Co się zatem dzieje, że to nie działa? Okazuje się, że samo pokazanie nie sprawdza czy dane polecenie może być wykonane czy nie. Należy wykonać dodatkową operację już po pokazaniu menu. Zatem poprawnie należy to zrobić w następujący sposób:

private void Button_Click(object sender, RoutedEventArgs e)

{

    menu.IsOpen = true;

    CommandManager.InvalidateRequerySuggested();

}

Rozwiązanie, znalezione na MSDN – ContextMenu – Command and sharing across controls. Może komuś zaoszczędzi to trochę czasu.

Dopisano: Wygląda, że się trochę pośpieszyłem. Wywołanie tej instrukcji powoduje wykonanie CanExecute, tylko w jakichś szczególnych sytuacjach?
Ktoś wie jak temu zaradzić?

Wygląda na to, że działa danie zwykłego prostego Focus() w konstruktorze okna zaraz po InitializeComponents().