ОБНОВЛЕНО
Это происходит в void WndProc(ref Message m)
.Я пытался воспроизвести проблему с другим контролем (PictureBox
).Двойной щелчок левой кнопкой мыши дал:
protected virtual void WndProc(ref Message m)
{
// ...
switch (m.Msg)
{
// ...
case 514:
WmMouseUp(ref m, MouseButtons.Left, 1);
return;
// ...
}
// ...
}
А двойной щелчок правой кнопкой мыши привел к вызову:
protected virtual void WndProc(ref Message m)
{
// ...
switch (m.Msg)
{
// ...
case 517:
WmMouseUp(ref m, MouseButtons.Right, 1);
return;
// ...
}
// ...
}
Где void WmMouseUp(ref Message m, MouseButtons button, int clicks)
выглядит так:
private void WmMouseUp(ref Message m, MouseButtons button, int clicks)
{
// ...
OnDoubleClick(new MouseEventArgs(button, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
OnMouseDoubleClick(new MouseEventArgs(button, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
// ...
}
Оба OnDoubleClick
и OnMouseDoubleClick
огонь с MouseEventArgs
.Вот почему это решение работает.
private void control_DoubleClick(object sender, EventArgs e)
{
if ((e as MouseEventArgs)?.Button == MouseButtons.Right)
return;
// do your stuff
}
Но ситуация отличается от ListView
:
protected virtual void WndProc(ref Message m)
{
// ...
switch (m.Msg)
{
// ...
case 514:
case 517: // m.Msg value
case 520:
{
NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();
int indexOfClickedItem = GetIndexOfClickedItem(lvhi);
if (!base.ValidationCancelled && listViewState[262144] && indexOfClickedItem != -1)
{
listViewState[262144] = false;
OnDoubleClick(EventArgs.Empty);
OnMouseDoubleClick(new MouseEventArgs(downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
}
if (!listViewState[524288])
{
OnMouseUp(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
listViewState[1048576] = false;
}
ItemCollectionChangedInMouseDown = false;
listViewState[524288] = true;
base.CaptureInternal = false;
return;
}
// ...
}
// ...
}
Он запускает OnDoubleClick
с EventArgs.Empty
.Поэтому первое решение не не работает.
В качестве обходного пути можно использовать исправленный ListView
:
public class PatchedListView : ListView
{
protected override void WndProc(ref Message m)
{
var suppress = m.Msg == 517 &&
Enum.TryParse(typeof(ListView).GetField("downButton", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this).ToString(),
out MouseButtons mouseButtons) &&
mouseButtons == MouseButtons.Right;
if (suppress)
return;
base.WndProc(ref m);
}
}