События динамического управления пользователями, не выполняющие методы в C # - PullRequest
0 голосов
/ 25 апреля 2018

Я изо всех сил пытаюсь выяснить, почему мои события пользовательского контроля не выполняются.У меня есть динамический UserControl, "MainMenu", в динамическом UserControl, "MainControl".

В MainMenu у меня есть следующее:

public partial class MainMenu : UserControl
{
    public MainMenu()
    {
        InitializeComponent();

        ///
        ///Event Subscriptions
        /// 
        this.LostFocus += this.MainMenu_LostFocus;
    }

    public void MainMenu_LostFocus(object sender, EventArgs e)
    {
        this.Visible = false;
    }
}

В MainControl:

public partial class MainControl : UserControl
{
    private Custom_UI.MainMenu mainMenu = new Custom_UI.MainMenu();
    public MainControl()
    {
        InitializeComponent();
        mainMenu.Visible = false;
        mainMenu.BringToFront();            
        this.Controls.Add(mainMenu);
        mainMenu.BringToFront();
    }
    private void menuButton1_Click(object sender, EventArgs e)
    {
        if (mainMenu.Visible)
        {
            mainMenu.Visible = false;                
        }
        else
        {
            mainMenu.Visible = true;
            this.Focus();
        }
    }
}

И, наконец, основная форма:

public partial class Form1 : Form
{
    MainControl mainControl = new MainControl() {
        Dock = DockStyle.Fill
    };
    public Form1()
    {
        InitializeComponent();
        this.Controls.Add(mainControl);
    }
}

Итакв основном, метод MainMenu_LostFocus не вызывается, когда я щелкаю в другом месте формы.Я также попытался использовать this.MouseLeave вместо this.LostFocus.

Надеюсь, это было достаточно ясно, и спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

ОК ... чтобы не попробовать другой, улучшенный подход.причина в том, что мы не хотим, чтобы нас заставляли обрабатывать клики на каждом элементе управления, добавленном к MainControl, и заставлять его получать фокус.просто неуклюжемоя новая идея:

 public partial class MainMenu : UserControl
    {

        //this class will be checking native windows messages, the one we're interested in is "MouseDown" with 0x0201 code 
        //(i won't be describing the whole stuff what is going inside: have that checked if you wish in documentation :)

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        public class TestMessageFilter : IMessageFilter
        {
            const int WM_MOUSEMOVE = 0x200;
            const int WM_LBUTTONDOWN = 0x0201;

            public event EventHandler MouseMoved;
            public event EventHandler MouseDown;

            public bool PreFilterMessage(ref Message m)
            {
                // Blocks all the messages relating to the left mouse button.
                if (m.Msg == WM_LBUTTONDOWN)
                {
                    MouseDown?.Invoke(this, new EventArgs());
                }
                return false;
            }
        }


        public MainMenu()
        {
            InitializeComponent();

            //use our class that checks Windows Messages, subscribe it's event
            var tmf = new TestMessageFilter();
            tmf.MouseDown += UserControl1_MouseDown;
            //and add our class to Application's messages filter.
            Application.AddMessageFilter(tmf);

            //use "ordinary" events to detect mouse enter/mouse leave over control
            this.MouseLeave += UserControl1_MouseLeave;
            this.MouseEnter += UserControl1_MouseEnter;
        }

        private void UserControl1_MouseDown(object sender, EventArgs e)
        {
            //if mouse is not over control make it's visible false
            if (mouseLeft)
            {
                this.Visible = false;
            }
        }

        //variable to save mouse state (if that is over the control, or left)
        private bool mouseLeft;

        private void UserControl1_MouseEnter(object sender, EventArgs e)
        {
            mouseLeft = false;
        }


        private void UserControl1_MouseLeave(object sender, EventArgs e)
        {
            mouseLeft = true;
        }

    }

надеюсь, что это решение будет лучше и полезнее

0 голосов
/ 26 апреля 2018

с использованием фокуса / потери фокуса и т. Д. Всегда было сложно.то, что я мог бы предложить, это немного изменить ваш код.

прежде всего ваш MainMenu должен получить фокус, чтобы потерять его

второй, чтобы потерять его, другой элемент управления должен получитьфокус - и это должно быть обработано вами (нажатие на MainControl не сработает, вам нужно принудительно)

попробуйте это:

public partial class MainControl : UserControl
{
    private Custom_UI.MainMenu mainMenu = new Custom_UI.MainMenu();
    public MainControl()
    {
        InitializeComponent();
        mainMenu.Visible = false;
        mainMenu.BringToFront();            
        this.Controls.Add(mainMenu);
        mainMenu.BringToFront();
        this.Click += me_Click;
    }

    private void me_Click(object sender, EventArgs e)
    {
        this.Focus(); //this will cause main control to get control (if main menu is focused it'll lose focus and handle it's focus lost and set visible to false in result
    }

    private void menuButton1_Click(object sender, EventArgs e)
    {
        if (mainMenu.Visible)
        {
            mainMenu.Visible = false;   // this should work anyway
        }
        else
        {
            mainMenu.Visible = true;
            mainMenu.Focus(); //when showing mainMenu set focus to it
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...