【提问】为什么自定义控件中重载的事件无法响应,请看代码
这个是自定义控件中的代码。
public partial class PicListEx : UserControl
{
private Size size = new Size(100, 100);
private Thread LoadPictureThread = null;
public PicListEx()
{
InitializeComponent();
lViewPic.View = View.LargeIcon;
}
/// <summary>
/// 加载图片
/// </summary>
/// <param name="filePaths">包含图片路径的数组</param>
public void loadPicFile(List<string> filePaths)
{
if (LoadPictureThread == null || !LoadPictureThread.IsAlive)
{
LoadPictureThread = new Thread(new ParameterizedThreadStart(LoadPictureFunc));
LoadPictureThread.IsBackground = true;
LoadPictureThread.Start(filePaths);
}
else
{
return;
}
}
private void LoadPictureFunc(object obj)
{
List<string> filePaths = null;
if (obj is List<string>)
{
filePaths = obj as List<string>;
}
else
{
return;
}
try
{
Invoke(new MethodInvoker(new Action(delegate()
{
lViewPic.Items.Clear();
lViewPic.BeginUpdate();
})));
ImageList Ilist = new ImageList();//与ListView关联的大图标列表
Ilist.ImageSize = size;//设置大小
Invoke(new MethodInvoker(new Action(delegate()
{
lViewPic.LargeImageList = Ilist; //关联
})));
foreach (string filePath in filePaths)
{
if (File.Exists(filePath))
{
string fileName = Path.GetFileNameWithoutExtension(filePath);
Image img = ResizeImage(filePath);
Invoke(new MethodInvoker(new Action(delegate()
{
Ilist.Images.Add(filePath, img);
})));
ListViewItem lvitem = new ListViewItem(fileName);
lvitem.Tag = filePath;
lvitem.ImageKey = filePath;
Invoke(new MethodInvoker(new Action(delegate()
{
lViewPic.Items.Add(lvitem);
})));
img.Dispose();
}
}
Invoke(new MethodInvoker(new Action(delegate()
{
lViewPic.EndUpdate();
lViewPic.Refresh();
})));
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message);
}
finally
{
Invoke(new MethodInvoker(new Action(delegate()
{
})));
}
}
private void lViewPic_Click(object sender, EventArgs e)
{
MessageBox.Show("自定义控件内_单击事件.");//**能够响应
}
private void lViewPic_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("自定义控件内_鼠标点击事件.");//**能够响应
}
protected override void OnClick(EventArgs e)
{
MessageBox.Show("重载的自定义控件单击事件.");//**无法响应
base.OnClick(e);
}
protected override void OnMouseEnter(EventArgs e)
{
MessageBox.Show("重载的自定义控件鼠标进入控件事件.");//**无法响应
base.OnMouseEnter(e);
}
}
下面是在窗口加载自定义控件后,窗口中的代码:
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
picListExLeft.Click += picListExLeft_Click;
}
string filePath = "";
private void tsBtn_OpenForld_Click(object sender, EventArgs e)
{
string folderPath = "";
FolderBrowserDialog folderDlg = new FolderBrowserDialog();
if (folderDlg.ShowDialog() == DialogResult.OK)
{
folderPath = folderDlg.SelectedPath;
}
List<string> listfile = new List<string>();
if (folderPath != "" && Directory.Exists(folderPath))
{
DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
foreach (FileInfo fileinfo in dirInfo.GetFiles())
{
if (fileinfo.Extension.ToUpper() == ".JPG")
listfile.Add(fileinfo.FullName);
}
}
folderDlg.Dispose();
folderDlg = null;
if (listfile.Count > 0)
{
picListExLeft.loadPicFile(listfile);
}
}
private void tsBtn_OpenPic_Click(object sender, EventArgs e)
{
OpenFileDialog openFd = new OpenFileDialog();
if (openFd.ShowDialog() == DialogResult.OK)
{
filePath = openFd.FileName;
}
openFd.Dispose();
openFd = null;
if (filePath != "")
{
List<string> listTem = new List<string>();
listTem.Add(filePath);
picListExLeft.loadPicFile(listTem);
}
}
private void picListExLeft_Click(object sender, EventArgs e)
{
ListViewItem item = picListExLeft.GetListViewSelectedItem;
if (item != null && (item.Tag as string).Trim() != "")
{
MessageBox.Show((item.Tag as string).Trim());
}
}
private void picListExLeft_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("鼠标单击");////**无法响应
}
private void picListExLeft_Load(object sender, EventArgs e)
{
MessageBox.Show("LOAD");
}
private void picListExLeft_MouseDoubleClick(object sender, MouseEventArgs e)
{
MessageBox.Show("双击");//**无法响应
}
private void picListExLeft_MouseEnter(object sender, EventArgs e)
{
MessageBox.Show("鼠标进入");//**无法响应
}
}
请教为什么,那些事件无法触发呢,事件都已经通过“+=”注册过了。
另外如何才能触发让那几个事件呢。
[解决办法]
private void lViewPic_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("自定义控件内_鼠标点击事件.");//**能够响应
}
这个地方也要用override 这个之后才会引起单击事件。
[解决办法]
因为你点击的操作都在图片上,而不是在控件上
[解决办法]
点的是图片,不是自定义控件本身,这样处理下,间接触发点击事件,外面就能获取到
private void lViewPic_Click(object sender, EventArgs e)
{
this.OnClick(e);
}
private void lViewPic_MouseClick(object sender, MouseEventArgs e)
{
this.OnMouseClick(e);
}
[解决办法]
定义两个共用的事件方法,把自定义控件上所有子控件的 Click 和 MouseClick 事件都指向这两个方法
private void this_Click(object sender, EventArgs e)
{
this.OnClick(e);
}
private void this_MouseClick(object sender, MouseEventArgs e)
{
this.OnMouseClick(e);
}
[解决办法]
把 picListExLeft_MouseClick 这类方法都删掉,这三个方法加到用户控件代码中
private void BindEvent(Control.ControlCollection ccle)
{
foreach (Control item in ccle)
{
item.Click += this.this_Click;
item.MouseClick += this.this_MouseClick;
this.BindEvent(item.Controls);
}
}
private void this_Click(object sender, EventArgs e)
{
this.OnClick(e);
}
private void this_MouseClick(object sender, MouseEventArgs e)
{
this.OnMouseClick(e);
}
把
this.BindEvent(this.Controls);
这行代码加到用户控件构造函数最后一行
把所有子控件的点击事件汇集起来,用户控件外就能接收到所有的点击事件
[解决办法]
你看看这个,或许你也是这个原因:
http://msdn.microsoft.com/zh-cn/library/ms171542.aspx
ListView 控件
注意
只有当用户单击 ListView 控件中的项时,才会发生下面详细说明的事件行为。 单击控件上的任何其他位置都不会引发任何事件。 除下面所描述的事件外,还有 BeforeLabelEdit 和 AfterLabelEdit 事件,如果要对 ListView 控件进行验证,则您可能会用到这两个事件。
单击左键:Click、MouseClick
单击右键:Click、MouseClick
双击左键:Click、MouseClick;DoubleClick、MouseDoubleClick
双击右键:Click、MouseClick;DoubleClick、MouseDoubleClick