Winform - تحديد ما إذا كان الماوس قد ترك تحكم المستخدم

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

سؤال

أنا أعاني من شيء أعتقد أنه يجب أن يكون بسهولة (العش).لدي نموذج Windows ولوحة تخطيط التدفق في الجزء السفلي من النموذج.داخل هذا النموذج، أقوم بتعبئته ديناميكيًا بعدد X من عناصر تحكم المستخدم.الضوابط كلها من نفس النوع.

الهدف هو عندما يقوم المستخدم بتمرير الماوس فوق عنصر تحكم المستخدم، فإنه يفتح نموذجًا آخر ويضعه في مكان وجود الماوس.عندما يترك الماوس النموذج يختفي النموذج المفتوح.

هذا يعمل بشكل رائع تقريبًا.تكمن المشكلة عندما يحتوي عنصر تحكم المستخدم على أي شيء مثل التسمية أو مربع النص بداخله.يعتبر أنه غادر جامعة كاليفورنيا لذلك يختفي النموذج.

كان تفكيري حينها هو استخدام X وY لمعرفة ما إذا كان موجودًا داخل جامعة كاليفورنيا ولكن لا يمكنني معرفة ذلك.

يمكن لي أن أسأل:

1) ما هو النهج الأفضل لذلك؟2) كيف يمكنني ترميزها، نظرًا لأن UC ديناميكية ولا أستطيع أن أعرف بالضبط أين ستكون.

شكرًا

يحرر

أحاول اكتشاف مؤشرات الماوس ولكني لا أصل إلى هناك.الكود أدناه موجود ضمن حدث 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
  • ع {X = 808 Y = 908} System.Drawing.Point
  • ع {X = 808 Y = 908} System.Drawing.Point
  • p2 {X = 545 Y = 1542} System.Drawing.Point
  • مللي ثانية {X = 574 Y = 914} System.Drawing.Point
  • حدود الشاشة {X = 808 Y = 908 العرض = 62 الارتفاع = 29} System.Drawing.Rectangle

لا أفهم كيف يمكن أن يكون لـ p2 (والدها) قيمة Y أكبر بالنسبة إلى الشاشة.

هل كانت مفيدة؟

المحلول

ربط جميع عناصر التحكم بأحداث MouseEnter وMouseLeave، ثم معرفة ما إذا كان لا يزال داخل النموذج أمر مؤلم جدًا.يمكن لمؤقت بسيط إنجاز المهمة أيضًا:

  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();
    }
  }

نصائح أخرى

فكرة 1) عندما MouseLeave عند تشغيل الحدث، يمكنك التحقق من إحداثيات الماوس (بالنسبة للشاشة) والتحقق مما إذا كانت لا تزال ضمن حدود تحكم المستخدم الخاص بك.إذا كان الأمر كذلك، فيجب افتراض أن الماوس يجب أن يمر عبر عنصر التحكم ليخرج من الحدود، ويمكنك تجاهل الحدث بأمان هذه المرة.

فكرة 2) إرفاق MouseEnter معالجات الأحداث لعناصر التحكم التابعة.ثم عندما يدخل الماوس واحدًا، ستعرف ويمكنك تجاهل عنصر تحكم المستخدم MouseLeave حدث.ثم عندما يكون الطفل MouseLeave حرائق الحدث، تحقق من وجود عنصر تحكم المستخدم MouseEnter مرة أخرى.

أعتقد أنني سأضيف معالج حدث لـ MouseLeave لكل عنصر تحكم لديك واستخدامه Parent الخاصية للعثور على عنصر تحكم المستخدم الذي تبحث عنه.أوافق على أن الأمر سيكون مؤلمًا بعض الشيء رغم ذلك.

يمكنك أيضًا المرور عبر كافة عناصر التحكم التابعة (العودية) في عنصر التحكم الخاص بك، وإرفاق حدث MouseEnter وMouseLeave بها أيضًا.

يجب عليك القيام ببعض مسك الدفاتر إذا كان الماوس تحت سيطرتك، أو بعض التحكم في الطفل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top