2009-06-17 10 views
16

Jak dodać ten przycisk do paska tytułu w WPF, ponieważ jest on używany w wielu aplikacjach, które myślałem, że zostanie on wbudowany lub coś takiego, ale wygląda na to, że tak nie jest. W każdym razie daj mi znać, jeśli coś o tym wiesz.Pomoc "?" przycisk

Dzięki.

Edit:

nie ma nic równoważne this?

Zasadniczo, aby mieć? ikona w formularzach wygranych, wszystko co musisz zrobić, to:

public Form1() 
{ 
    InitializeComponent(); 

    this.HelpButton = true; 
    this.MaximizeBox = false; 
    this.MinimizeBox = false; 
} 

Czy WPF nie ma czegoś takiego?

+0

Dlaczego pasek tytułu? Większość aplikacji, które widzę, umieszczam na pasku menu. –

+1

Chodzi o to, że używamy go głównie w oknach dialogowych, które zwykle nie mają paska menu. Kliknięcie go spowoduje wyświetlenie pomocy kontekstowej dla tego okna. Coś jak w MS Word 2007 w oknie dialogowym czcionek. – Carlo

Odpowiedz

30

To proste, wystarczy wstawić ten kod do klasy okna.

Ten kod używa funkcji interop do usuwania stylów WS_MINIMIZEBOX i WS_MAXIMIZEBOX i dodawania rozszerzonego stylu WS_EX_CONTEXTHELP (znak zapytania pojawi się tylko po usunięciu przycisków minimalizacji i maksymalizacji).

EDYCJA: dodane wykrywanie kliknięcia na przycisku pomocy, odbywa się poprzez podłączenie do WndProc przy użyciu HwndSource.AddHook i odsłuchanie komunikatu WM_SYSCOMMAND za pomocą wParam z SC_CONTEXTHELP.

Po wykryciu kliknięcia ten kod wyświetli okno komunikatu, zmieniając je w zdarzenie, wydarzenie routowane, a nawet polecenie (w przypadku aplikacji MVVM) pozostawia się jako ćwiczenie dla czytnika.

private const uint WS_EX_CONTEXTHELP = 0x00000400; 
private const uint WS_MINIMIZEBOX = 0x00020000; 
private const uint WS_MAXIMIZEBOX = 0x00010000; 
private const int GWL_STYLE = -16; 
private const int GWL_EXSTYLE = -20; 
private const int SWP_NOSIZE = 0x0001; 
private const int SWP_NOMOVE = 0x0002; 
private const int SWP_NOZORDER = 0x0004; 
private const int SWP_FRAMECHANGED = 0x0020; 
private const int WM_SYSCOMMAND = 0x0112; 
private const int SC_CONTEXTHELP = 0xF180; 


[DllImport("user32.dll")] 
private static extern uint GetWindowLong(IntPtr hwnd, int index); 

[DllImport("user32.dll")] 
private static extern int SetWindowLong(IntPtr hwnd, int index, uint newStyle); 

[DllImport("user32.dll")] 
private static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags); 


protected override void OnSourceInitialized(EventArgs e) 
{ 
    base.OnSourceInitialized(e); 
    IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; 
    uint styles = GetWindowLong(hwnd, GWL_STYLE); 
    styles &= 0xFFFFFFFF^(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); 
    SetWindowLong(hwnd, GWL_STYLE, styles); 
    styles = GetWindowLong(hwnd, GWL_EXSTYLE); 
    styles |= WS_EX_CONTEXTHELP; 
    SetWindowLong(hwnd, GWL_EXSTYLE, styles); 
    SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); 
    ((HwndSource)PresentationSource.FromVisual(this)).AddHook(HelpHook); 
} 

private IntPtr HelpHook(IntPtr hwnd, 
     int msg, 
     IntPtr wParam, 
     IntPtr lParam, 
     ref bool handled) 
{ 
    if (msg == WM_SYSCOMMAND && 
      ((int)wParam & 0xFFF0) == SC_CONTEXTHELP) 
    { 
     MessageBox.Show("help"); 
     handled = true; 
    } 
    return IntPtr.Zero; 
} 
+0

to działa, jeszcze jedno pytanie: Jak dodać moduł obsługi OnClick do "?" przycisk? – Carlo

+0

Dodałem kod, aby wykryć kliknięcia przycisku pomocy, mam nadzieję, że to pomoże – Nir

+0

Działa jak urok. Dzięki! – Carlo

0

Żaden przycisk pomocy nie wychodzi z pudełka z WPF. Nie należy jednak naciskać, aby rzucić własną ręką.

+0

Do paska tytułu? Wygląda na to, że musisz zmienić chrome Window, co jest udokumentowane, ale nie jest trywialne. – micahtan

+0

I nie jest to najlepsza praktyka. Zamiast tego widzę aplikacje WPF, które wykreślają własne paski tytułu, również nie są idealne. –

+0

@ Drew: Tak, to jedyne rozwiązanie, które do tej pory widziałem i nie wydaje mi się to zbyt dobre. Specjalnie dlatego, że mamy już mnóstwo okien dialogowych i nie byłoby dobrze, aby przejść do każdego i wyśmiać pasek tytułu. – Carlo

0

Jeśli zamierzasz dodać przycisk do obszaru niezwiązanego z klientem, spójrz na numer this article.