2009-06-19 11 views
4

Je dois afficher une boîte de message non modale chaque fois qu'un utilisateur survole un élément de menu. Je ne peux pas utiliser messagebox.show (...) parce que c'est un modal. Donc ce que j'ai fait était de créer un formulaire de fenêtres séparées et d'afficher le formulaire en utilisant l'événement hover sur l'élément de menu. J'ai 2 problèmes:Idées sur l'affichage d'une boîte de message non modale sous forme d'info-bulle

1) Lorsque le formulaire de fenêtres affiche le menu perd sa visibilité.
2) Le formulaire de fenêtres n'apparaît pas à côté de l'élément de menu, comme dans le cas d'une info-bulle.

Avez-vous des idées sur la façon dont je pourrais personnaliser l'infobulle d'un composant qui lui donnerait l'apparence d'un formulaire Windows?

Répondre

5

Pour répondre à votre deuxième problème:

Si vous définissez la propriété form.StartPosition à FormStartPosition.Manual alors vous pouvez placer le formulaire au niveau du curseur (par exemple):

form.StartPosition = FormStartPosition.Manual; 
form.Location = new Point(Cursor.Position.X - 1, Cursor.Position.Y - 1); 

Cela pourrait aider votre premier problème aussi.

Si vous voulez que la forme se comporte comme une info-bulle puis si vous ajoutez le code de gestionnaire d'événement suivant il pourrait vous donner l'envie vous voulez:

private void Form_MouseLeave(object sender, EventArgs e) 
    { 
     // Only close if cursor actually outside the popup and not over a label 
     if (Cursor.Position.X < Location.X || Cursor.Position.Y < Location.Y || 
      Cursor.Position.X > Location.X + Width - 1 || Cursor.Position.Y > Location.Y + Height - 1) 
     { 
      Close(); 
     } 
    } 

Ceci explique la -1 dans le réglage de la position de forme. Cela garantit que le curseur est réellement sur le formulaire lors de son affichage initial.

5

Comme classe Form est juste une enveloppe autour de la fenêtre native, vous pouvez utiliser le code suivant pour créer votre propre formulaire pop-up, qui ressemble presque fenêtre infobulle:

public class PopupForm : Form 
{ 
    private const int SWP_NOSIZE = 0x0001; 
    private const int SWP_NOMOVE = 0x0002; 
    private const int SWP_NOACTIVATE = 0x0010; 

    private const int WS_POPUP = unchecked((int)0x80000000); 
    private const int WS_BORDER = 0x00800000; 

    private const int WS_EX_TOPMOST = 0x00000008; 
    private const int WS_EX_NOACTIVATE = 0x08000000; 

    private const int CS_DROPSHADOW = 0x00020000; 

    private static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); 

    public PopupForm() 
    { 
     InitializeComponent(); 
     SetStyle(ControlStyles.Selectable, false); 
     Visible = false; 
    } 

    protected virtual void InitializeComponent() 
    { 
     FormBorderStyle = FormBorderStyle.None; 
     StartPosition = FormStartPosition.Manual; 
     ShowInTaskbar = false; 
     BackColor = SystemColors.Info; 

     // ... 
    } 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.Style |= WS_POPUP; 
      cp.Style |= WS_BORDER; 
      cp.ExStyle |= WS_EX_TOPMOST | WS_EX_NOACTIVATE; 
      //if (Microsoft.OS.IsWinXP && SystemInformation.IsDropShadowEnabled) 
      // cp.ClassStyle |= CS_DROPSHADOW; 
      return cp; 
     } 
    } 

    protected override bool ShowWithoutActivation 
    { 
     get { return true; } 
    } 

    public new void Show() 
    { 
     SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);  
     base.Show(); 
    } 

    public void Show(Point p) 
    { 
     Location = p; 
     Show(); 
    } 
} 

contrôle ce formulaire Show() et Hide() méthodes du code extérieur.

Questions connexes