Domanda

Sto lottando con qualcosa che penso dovrebbe essere facilmente (ish). Ho un modulo di Windows e un pannello flowgridlayout nella parte inferiore del modulo. All'interno di questo modulo lo popolo dinamicamente con il numero X di controlli utente. I controlli sono tutti dello stesso tipo.

L'obiettivo è quando l'utente passa il mouse sopra il controllo utente che apre un altro modulo e lo posiziona dove si trova il mouse. Quando il mouse lascia il modulo, il modulo aperto scompare.

Questo funziona quasi alla grande. Il problema è quando il controllo utente ha qualcosa come un'etichetta o una casella di testo al suo interno. Si ritiene che abbia lasciato la UC, quindi il modulo scompare.

Il mio pensiero era quindi di usare X e Y per dire se si trova all'interno della UC ma non riesco a capirlo.

Posso chiedere:

1) Qual è l'approccio migliore a questo? 2) Come posso codificarlo, poiché gli UC sono dinamici, non posso sapere esattamente dove saranno.

Grazie

Modifica

Sto cercando di capire i puntatori del mouse ma non ci arrivo. Il codice seguente è all'interno dell'evento UC SmallTagBox_MouseLeave:

        Point loc = this.Location;
        Point p = this.PointToScreen(this.Location);
        Point p2 = this.PointToScreen(this.Parent.Location);

        Point ms = MousePosition;
        Rectangle screenBounds = new Rectangle(this.PointToScreen(this.Location), this.Size);
        if (!screenBounds.Contains(ms))
        {
            thw.Close();
            thw = null;
        }
  • loc {X = 275 Y = 3} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p2 {X = 545 Y = 1542} System.Drawing.Point
  • ms {X = 574 Y = 914} System.Drawing.Point
  • screenBounds {X = 808 Y = 908 Larghezza = 62 Altezza = 29} System.Drawing.Rectangle

Non capisco come p2 (il suo genitore) possa avere un valore Y maggiore rispetto allo schermo.

È stato utile?

Soluzione

Agganciare tutti gli eventi MouseEnter e MouseLeave di controllo, quindi capire se è ancora all'interno del modulo è piuttosto doloroso. Anche un semplice timer può svolgere il lavoro:

  public partial class Form1 : Form {
    private Timer mTimer;
    public Form1() {
      InitializeComponent();
      mTimer = new Timer();
      mTimer.Interval = 200;
      mTimer.Tick += mTimer_Tick;
      mTimer.Enabled = true;
    }
    private void mTimer_Tick(object sender, EventArgs e) {
      if (!this.DesktopBounds.Contains(Cursor.Position)) this.Close();
    }
  }

Altri suggerimenti

Idea 1) Quando si attiva l'evento MouseLeave , puoi controllare le coordinate del mouse (relative allo schermo) e verificare che siano ancora entro i limiti del tuo controllo utente. In tal caso, si dovrebbe presumere che il mouse debba passare di nuovo attraverso il controllo per uscire dai limiti e questa volta è possibile ignorare l'evento in modo sicuro.

Idea 2) Collega i gestori di eventi MouseEnter ai controlli figlio. Quindi quando il mouse entra in uno, saprai e puoi ignorare l'evento MouseLeave di usercontrol. Quindi, quando l'evento MouseLeave del bambino viene generato, controlla nuovamente MouseEnter di usercontrol.

Penso che aggiungerei un gestore eventi per MouseLeave per ogni controllo che possiedi e utilizzare la proprietà Parent per trovare il controllo utente che stai cercando. Sono d'accordo, sarà un po 'doloroso però.

Puoi anche scorrere tutti i controlli figlio (ricorsivi) sul tuo controllo e allegare anche un evento MouseEnter e MouseLeave.

Devi fare un po 'di contabilità se il mouse è sotto il tuo controllo o un controllo figlio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top