czwartek, 6 listopada 2008

ContextMenu, ToolStripMenuItem, Checked

Defaultowe zachowanie ContextMenu polega na tym że po wybraniu konkretnego elementu, context menu sie chowa. A co w przypadku kiedy nie chcemy żeby się chowało ? Przykładowo mamy Context Menu które oczywiście się otwiera po przyciśnięciu prawym klawiszem myszy i jest generowane dynamicznie. Zazwyczaj niech zawiera 2-3 stałe przyciski(ToolStripMenuItem) i do kilkunastu ToolStripMenuItem z włączaną opcją Checked. Ktoś odpowie ale to już nie jest defaultowe context menu i w tym celu należy użyć customowej kontrolki i pewnie ma rację. Ale ContextMenu supportuje nam bardzo fajny propertis:

m_ContextMenuStrip.AutoClose = false;

AutoClose pozwala nam po zdarzeniu kliknieciu na Item w ContextMenu nie zamykać go.
Nie ma róży bez kolców :) ContextMenu będzie teraz wisieć nam wiecznie, i niestety trzeba wygenerować jego zamknięcie przy zdarzeniach generowania samego ContextMenu.
Czyli jeśli wyłączamy AutoClose to automatycznie kliknięcie poza obszar ContextMenu nie spowoduje jego zamknięcia.

W moim przypadku było akurat drzewo(TreeView) które dla każdej gałęzi(node) i korzenia(root) mogło wygenerować inne Context Menu i odbywało się to na zdarzeniu MouseUp.

Więc rozwiązaniem problemu wiszącego ContextMenu jest:

protected override void StructureTreeView_MouseUp(object sender, MouseEventArgs e)
{
if (m_ContextMenuStrip.Visible)
{
m_ContextMenuStrip.Visible = false;
m_ContextMenuStrip.Close();
}

if (e.Button != MouseButtons.Right)
return;

m_ContextMenuStrip.Items.Clear();
...
m_ContextMenuStrip.AutoClose = false;
m_StructureTreeView.SelectedNode = node;
m_ContextMenuStrip.Show(m_StructureTreeView, new Point(e.X, e.Y));

}


Tak więc w przypadku jakimkolwiek kliknięciu poza obszar ContextMenu, pierwszy if sprawdzi czy jest ono otwarte(Visible) i je sobie zamknie :)

Ma to jednak jeszcze jeden bug którego nie udało mi się rozwiązać ale który nie jest aż tak strasznie dokuczliwy. Otóż jeśli otworzymy ContextMenu i uruchomimy InternetExplorera to ContextMenu będzie przez niego prześwietlać :)

Brak komentarzy: