J'ai les gestionnaires d'événements OnMouseEnter et OnMouseLeave configurés pour mon formulaire. Lorsque la souris se déplace sur le formulaire, je veux définir l'opacité à 100% et quand il s'éloigne, je veux le mettre à 25%. Cela fonctionne bien, sauf lorsque la souris se déplace sur l'un des boutons du formulaire. L'événement OnMouseLeave déclenche et masque à nouveau le formulaire. Existe-t-il un bon moyen de gérer cela, sans avoir à câbler OnMouseEnter pour chaque contrôle sur le formulaire?OnMouseEnter pour tous les contrôles d'un formulaire
Répondre
EDIT: Je vais laisser cette réponse ici, même si elle ne peut pas fonctionner de manière fiable. La raison: empêcher quelqu'un d'autre d'essayer la même chose. Voir la fin du message pour la raison que cela ne fonctionnera pas.
Vous pouvez le faire assez facilement pour le rectangle client en obtenant la position du curseur et vérifier pour voir si elle est dans l'espace client de formulaire:
private void Form1_MouseLeave(object sender, EventArgs e)
{
Point clientPos = PointToClient(Cursor.Position);
if (!ClientRectangle.Contains(clientPos))
{
this.Opacity = 0.25;
}
}
Cela suppose qu'aucun de vos contrôles enfants va changer la opacité. Cependant, vous trouverez que c'est une solution moins que parfaite, car lorsque la souris va à la barre de titre, le formulaire va à 0.25%. Vous pouvez corriger cela en vérifiant si la position de la souris est dans la fenêtre rect (en utilisant la propriété Bounds), mais alors votre fenêtre restera opaque si la souris quitte la barre de titre et sort de la fenêtre.
Vous rencontrez un problème similaire lorsque vous entrez dans la barre de titre depuis l'extérieur.
Je pense que vous devrez gérer les messages WM_NCMOUSEENTER
et WM_NCMOUSELEAVE
afin de rendre ce travail fiable. Pourquoi cela ne peut-il pas fonctionner? Même la gestion des notifications de zones non-clients peut échouer. Il est possible que la souris entre dans un contrôle enfant, ce qui empêcherait le formulaire d'être notifié.
Je pense que c'est impossible à faire, sans gérer les événements MouseEnter et MouseLeave de tous les enfants, mais vous n'avez pas à les câbler manuellement.
Voici un code que j'ai copié & collé à partir d'un de mes projets. Il fait presque ce que vous avez décrit ici. J'ai effectivement copié l'idée et le cadre de this site.
Dans le constructeur, j'appelle AttachMouseOnChildren() pour attacher les événements. Les OnContainerEnter et OnContainerLeave sont utilisés pour gérer la souris entrant/quittant le formulaire lui-même.
#region MouseEnter & Leave
private bool _childControlsAttached = false;
/// <summary>
/// Attach enter & leave events to child controls (recursive), this is needed for the ContainerEnter &
/// ContainerLeave methods.
/// </summary>
private void AttachMouseOnChildren() {
if (_childControlsAttached) {
return;
}
this.AttachMouseOnChildren(this.Controls);
_childControlsAttached = true;
}
/// <summary>
/// Attach the enter & leave events on a specific controls collection. The attachment
/// is recursive.
/// </summary>
/// <param name="controls">The collection of child controls</param>
private void AttachMouseOnChildren(System.Collections.IEnumerable controls) {
foreach (Control item in controls) {
item.MouseLeave += new EventHandler(item_MouseLeave);
item.MouseEnter += new EventHandler(item_MouseEnter);
this.AttachMouseOnChildren(item.Controls);
}
}
/// <summary>
/// Will be called by a MouseEnter event, with any of the controls within this
/// </summary>
void item_MouseEnter(object sender, EventArgs e) {
this.OnMouseEnter(e);
}
/// <summary>
/// Will be called by a MouseLeave event, with any of the controls within this
/// </summary>
void item_MouseLeave(object sender, EventArgs e) {
this.OnMouseLeave(e);
}
/// <summary>
/// Flag if the mouse is "entered" in this control, or any of its children
/// </summary>
private bool _containsMouse = false;
/// <summary>
/// Is called when the mouse entered the Form, or any of its children without entering
/// the form itself first.
/// </summary>
protected void OnContainerEnter(EventArgs e) {
// No longer transparent
this.Opacity = 1;
}
/// <summary>
/// Is called when the mouse leaves the form. When the mouse leaves the form via one of
/// its children, this will also call OnContainerLeave
/// </summary>
/// <param name="e"></param>
protected void OnContainerLeave(EventArgs e) {
this.Opacity = DEFAULT_OPACITY;
}
/// <summary>
/// <para>Is called when a MouseLeave occurs on this form, or any of its children</para>
/// <para>Calculates if OnContainerLeave should be called</para>
/// </summary>
protected override void OnMouseLeave(EventArgs e) {
Point clientMouse = PointToClient(Control.MousePosition);
if (!ClientRectangle.Contains(clientMouse)) {
this._containsMouse = false;
OnContainerLeave(e);
}
}
/// <summary>
/// <para>Is called when a MouseEnter occurs on this form, or any of its children</para>
/// <para>Calculates if OnContainerEnter should be called</para>
/// </summary>
protected override void OnMouseEnter(EventArgs e) {
if (!this._containsMouse) {
_containsMouse = true;
OnContainerEnter(e);
}
}
#endregion
Je pense que d'une façon de gérer de manière fiable les événements de souris que vous êtes intéressé est de mettre en place un IMessageFilter sur votre objet Application à partir duquel vous pouvez intercepter tous les messages de souris (WM_MOUSEMOVE etc ..), même si elles sont envoyées à des contrôles de l'enfant de la forme.
est ici un code de démonstration:
using System;
using System.Windows.Forms;
namespace Test
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
public static Form frm = null;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
frm = new Form1 {Opacity = 0.25};
frm.Controls.Add(new Button{Dock = DockStyle.Fill, Text = "Ok"});
Application.AddMessageFilter(new MouseMoveFilter());
Application.Run(frm);
}
}
public class MouseMoveFilter : IMessageFilter
{
#region IMessageFilter Members
private const int WM_MOUSELEAVE = 0x02A3;
private const int WM_NCMOUSEMOVE = 0x0A0;
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_NCMOUSELEAVE = 0x2A2;
public bool PreFilterMessage(ref Message m)
{
switch (m.Msg)
{
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE:
Program.frm.Opacity = 1;
break;
case WM_NCMOUSELEAVE:
case WM_MOUSELEAVE:
if (!Program.frm.Bounds.Contains(Control.MousePosition))
Program.frm.Opacity = 0.25;
break;
}
return false;
}
#endregion
}
}
Vous pouvez aussi hériter de la classe de formulaire et passer outre PreProcessMessage() pour accomplir la même chose ...
- 1. Actualiser tous les contrôles sur le formulaire
- 2. VS.NET Outil pour nommer tous les contrôles sur le formulaire
- 3. Gestion d'un clic pour tous les contrôles d'un formulaire
- 4. Méthode générique pour trouver tous les contrôles TextBox dans Silverlight
- 5. Comment ajouter tous les contrôles d'un autre formulaire à un formulaire dans Winforms?
- 6. Linq Récupérer tous les contrôles (classés)
- 7. Est-ce que WPF a des contrôles équivalents pour tous les contrôles Winforms?
- 8. Pourquoi tous les contrôles de formulaire ne peuvent-ils pas être rendus via HtmlHelper?
- 9. Désactiver tous les contrôles Validator sur une page
- 10. Trouver tous les contrôles sur msform à partir de C#
- 11. Accès à tous les contrôles à partir d'une fenêtre WPF
- 12. Firefox - tous les boutons de formulaire vides
- 13. Comment utiliser "ceci" correctement pour accéder aux contrôles de formulaire?
- 14. C# usercontrol comment accéder à tous les contrôles enfants
- 15. Rechercher tous les contrôles ASP.NET correspondant à un prédicat?
- 16. Comment activer/désactiver tous les sous-contrôles d'une table?
- 17. Comment redimensionner les contrôles d'un formulaire pour les adapter à différentes résolutions?
- 18. ModelState.IsValid pour les contrôles invisibles
- 19. visual designer 2005 déplace les contrôles et redimensionne le formulaire
- 20. Comment le contrôle de l'info-bulle améliore-t-il tous les contrôles du formulaire avec une nouvelle propriété?
- 21. Récupérer tous les éléments d'un formulaire dans jQuery
- 22. Comment gérer les contrôles .NET TabPage qui se retrouvent tous dans une classe Form?
- 23. Quel est le meilleur moyen de passer en revue tous les contrôles sur un formulaire en vb2005
- 24. obtenir tous les contrôles wpf dans le fichier cs et vérifier leur type
- 25. Accéder aux contrôles sur un nouveau formulaire
- 26. Capture tous les liens, y compris la soumission de formulaire
- 27. Object.watch() pour tous les navigateurs?
- 28. Comment faire pour redimensionner les contrôles dans les fenêtres redimensionnables?
- 29. Basculer tous les contrôles en lecture seule sur un bouton Cliquez sur WinForm
- 30. Comment faire pour déplacer les contrôles au milieu d'un formulaire MFC?
Le seul problème est qu'il définit l'opacité à DEFAULT_OPACITY lorsque vous passez la souris sur la barre de titre. – Samuel