动态用户控件事件不执行 C# 中的方法
Dynamic User Control events not executing methods in C#
我正在努力弄清楚为什么我的用户控件事件没有执行。我在动态用户控件 "MainControl" 中有一个动态用户控件 "MainMenu"。
在 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;
}
}
在主控件中:
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
。
希望我已经足够清楚了,在此先感谢。
使用 focus/focus 丢失等总是很棘手。我的建议是稍微修改一下您的代码。
首先你的 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
}
}
}
好的...以免尝试另一种改进的方法。原因是我们不想被迫处理对每个添加到 MainControl
的控件的点击并强制它获得焦点。就是笨拙。
我们还想将整个代码封装在一个控件中 (MainMenu
) - 不是 "must have",但肯定是 "nice to have"
这是我的新想法:
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;
}
}
希望这个解决方案会更好,更有用
我正在努力弄清楚为什么我的用户控件事件没有执行。我在动态用户控件 "MainControl" 中有一个动态用户控件 "MainMenu"。
在 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;
}
}
在主控件中:
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
。
希望我已经足够清楚了,在此先感谢。
使用 focus/focus 丢失等总是很棘手。我的建议是稍微修改一下您的代码。
首先你的 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
}
}
}
好的...以免尝试另一种改进的方法。原因是我们不想被迫处理对每个添加到 MainControl
的控件的点击并强制它获得焦点。就是笨拙。
我们还想将整个代码封装在一个控件中 (MainMenu
) - 不是 "must have",但肯定是 "nice to have"
这是我的新想法:
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;
}
}
希望这个解决方案会更好,更有用