2009-06-17 10 views
16

¿Cómo puedo agregar este botón a la barra de título en WPF, al ser utilizado en muchas aplicaciones que pensé que sería incorporado o algo así, pero parece que no lo es. De todos modos, avíseme si sabe algo al respecto.Ayuda "?" botón

Gracias.

Editar:

no existe nada equivalente a this?

Básicamente, para tener? icono en formas de ganar, todo lo que tiene que hacer es lo siguiente:

public Form1() 
{ 
    InitializeComponent(); 

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

WPF no tienen nada de eso?

+0

¿Por qué la barra de título? La mayoría de las aplicaciones que veo lo colocan en la barra de menú. –

+1

Lo que pasa es que vamos a usarlo principalmente en ventanas de diálogo, que normalmente no tienen una barra de menú. Al hacer clic en él aparecerá la ayuda contextual para esa ventana. Algo así como en MS Word 2007 en la ventana de diálogo de fuentes. – Carlo

Respuesta

30

Es simple, simplemente inserte este código en su clase de Windows.

Este código usa la interoperabilidad para eliminar los estilos WS_MINIMIZEBOX y WS_MAXIMIZEBOX y agrega el estilo extendido WS_EX_CONTEXTHELP (el signo de interrogación solo aparecerá si elimina los botones minimizar y maximizar).

EDITAR: se agregó detección de clic en el botón de ayuda, esto se hace enganchando en el WndProc usando HwndSource.AddHook y escuchando un mensaje WM_SYSCOMMAND con wParam de SC_CONTEXTHELP.

Cuando se detecta un clic, este código mostrará un cuadro de mensaje, cambiando esto a un evento, evento enrutado o incluso un comando (para aplicaciones MVVM) se deja como un ejercicio para el lector.

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

esto funciona, una pregunta más: ¿Cómo agrego un controlador OnClick al "?" ¿botón? – Carlo

+0

He agregado el código para detectar clics en el botón de ayuda, espero que esto ayude – Nir

+0

Funcionó como un amuleto. ¡Gracias! – Carlo

0

No hay botones de ayuda que salgan de la caja con WPF. Sin embargo, no debería ser un impulso para hacer tu propio.

+0

¿A la barra de título? Parece que necesitarías cambiar el Window chrome, que está documentado, pero no es trivial. – micahtan

+0

Y tampoco es una buena práctica. En cambio, veo aplicaciones WPF que simulan sus propias barras de título, tampoco son ideales. –

+0

@Drew: Sí, esa es la única solución que he visto hasta ahora y no me parece muy buena. Especialmente porque ya tenemos toneladas de cuadros de diálogo y no sería bueno ir a cada uno y simular la barra de título. – Carlo

0

Si tiene la intención de agregar el botón al área no cliente, eche un vistazo a this article.