Idées sur la façon d'afficher une boîte de message non modale sous forme d'infobulle

StackOverflow https://stackoverflow.com/questions/1017550

  •  06-07-2019
  •  | 
  •  

Question

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 (...) car c'est un modal. Donc, ce que j'ai fait était de créer un formulaire Windows séparé et d'afficher le formulaire à l'aide de l'événement de survol sur l'élément de menu. J'ai 2 problèmes:

1) Lorsque le formulaire Windows est affiché, le menu perd sa visibilité.
2) Le formulaire Windows n'apparaît pas à côté de l'élément de menu, comme le ferait une info-bulle.

Avez-vous des idées sur la manière de personnaliser l’info-bulle d’un composant qui lui donnerait l’air et se comporterait comme un formulaire Windows?

Était-ce utile?

La solution

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

Si vous définissez la propriété form.StartPosition sur FormStartPosition.Manual , vous pouvez alors positionner 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 également vous aider avec votre premier problème.

Si vous voulez que le formulaire se comporte comme une info-bulle, si vous ajoutez le code de gestionnaire d'événements suivant, il se peut que vous souhaitiez le vouloir:

    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 le -1 dans la définition de la position du formulaire. Cela garantit que le curseur est réellement sur le formulaire lors de son premier affichage.

Autres conseils

Etant donné que la classe Form est simplement une enveloppe autour de la fenêtre native, vous pouvez utiliser l'extrait de code suivant pour créer votre propre formulaire contextuel, qui ressemble presque à une fenêtre d'info-bulle:

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ôlez ce formulaire avec les méthodes Show () et Hide () à partir du code extérieur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top