make delayed mousedown event - c#

I have a datagridview which cells has a click event. The cells also have the following mouseDown event:
if (e.Button == MouseButtons.Left && e.Clicks == 1)
{
string[] filesToDrag =
{
"c:/install.log"
};
gridOperations.DoDragDrop(new DataObject(DataFormats.FileDrop, filesToDrag), DragDropEffects.Copy);
}
whenever I try to click a cell, the mousedown event instantly fires and tries to drag the cell. How can I make the mousedown event fire only if user has holded mouse down for 1 second for example? Thanks!

The proper way to do this is not by time but to trigger it when the user moved the mouse enough. The universal measure for "moved enough" in Windows is the double-click size. Implement the CellMouseDown/Move event handlers, similar to this:
private Point mouseDownPos;
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) {
mouseDownPos = e.Location;
}
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e) {
if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
if (Math.Abs(e.X - mouseDownPos.X) >= SystemInformation.DoubleClickSize.Width ||
Math.Abs(e.Y - mouseDownPos.Y) >= SystemInformation.DoubleClickSize.Height) {
// Start dragging
//...
}
}
}

Related

Use Mouse Left and Right buttons in c# winforms

This function only recognizes mouse's Left button. How can I make this program recognize mouse's right button in order to click this button with mouse's right button?.
private void button2_Click(object sender, EventArgs e)
{
MouseEventArgs me = (MouseEventArgs)e;
if (buttonwasclicked==false)
{
DrawLinesOnBitmap(button2.BackgroundImage);
button2.BackgroundImage= ToGrayscale(button2.BackgroundImage);
buttonwasclicked = true;
}
else {
button2.BackgroundImageLayout = ImageLayout.Stretch;
button2.BackgroundImage = Image.FromFile("C:\\Users\\rati\\Desktop\\ks.png");
buttonwasclicked = false;
}
if (me.Button == MouseButtons.Left)
{
mysum += md;
if (buttonwasclicked == true) md *= -1; else md *= -1;
label1.Text = mysum.ToString();
}
if (me.Button == MouseButtons.Right) {
enemysum += ed;
if (buttonwasclicked == true) ed *= -1; else ed *= -1;
label2.Text = enemysum.ToString();
}
}
Use the "MouseClick" event rather than the "Click" event, "Click" doesn't recognise right clicks of the mouse.
If you're using Visual Studio, simply go to the designer, click the button, go to properties and click the lightning icon. Then you find "MouseClick" and double click this.
You need to use the MouseDown and MouseUp actions together in order to interpret a click.
Your actions list should look similar to this:
Then interpret the actions as follows:
int prevMouseX;
int prevMouseY;
private void mouseDown(object sender, MouseEventArgs e)
{
prevMouseX = e.X;
prevMouseY = e.Y;
}
private void mouseUp(object sender, MouseEventArgs e)
{
if (prevMouseX == e.X && prevMouseY == e.Y)
mouseClick(sender, e);
}
private void mouseClick(object sender, MouseEventArgs e)
{
//Do Stuff
}
That should work for you!
My code interprets a click as when the mouse goes down and up in the same position.
Try this if you want to do something on Button's right click event.
=> Create one context menu and do not create any option in it.(Drag & Drop ContextMenuStrip from Toolbox)
=> Assign that context menu to that button from Button's ContextMenuStrip property in Properties panel.
Write following code on Context Menu's Opening Event
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
MessageBox.Show("hii");
e.Cancel=true;
}
You should use MouseDown event. It has MouseEventArgs parameter which contains Button property. So you can check wich button was down.

Visual C# ListView ContextMenu

I have a ListView to display Images Icons, and i need 2 different Context menu on that ListView that have to show when i Right Click inside the ListView.
ContextMenu1 have to show only when i Right Click on a Item
ContextMenu2 have to show when i DO NOT Right click on a Item, but in the blank space of the ListView.
This is the current Code that i have, but it is only working when i right click on a item:
private void ListView_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (ListView.GetItemAt(e.X, e.Y) is ListViewItem)
{
ContextMenu1.Show(Cursor.Position);
}
else
{
ContextMenu2.Show(Cursor.Position);
}
}
}
What i did wrong?
GetItemAt will always return a ListviewItem. You should check for null like this example from MSDN:
private void ListView_MouseDown(object sender, MouseEventArgs e)
{
if (ListView.GetItemAt(e.X, e.Y) != null )
{
ContextMenu1.Show(Cursor.Position);
}
else
{
ContextMenu2.Show(Cursor.Position);
}
}
Try using the MouseDown or MouseUp event instead:
listView1.MouseDown += listView1_MouseDown;
void listView1_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Right) {
if (listView1.GetItemAt(e.X, e.Y) is ListViewItem) {
ContextMenu1.Show(Cursor.Position);
} else {
ContextMenu2.Show(Cursor.Position);
}
}
}
The MouseClick event fires only when a ListItem is clicked.

dataGridView Controlled context menu click

I want to make it so that if the first row is right clicked and an option on the context menu is clicked it will do a specific function, and if the second row is right clicked it will do a specific function etc. So I've tried several different codes and none work but this is just my simplified version of the code, so how can I make it do as I want?
private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
DataGridViewRow row = new DataGridViewRow();
if (row.Selected.Equals(0) == true && e.Button == MouseButtons.Right && contextMenuStrip1.Text == "Test")
{
MessageBoxEx.Show("Test ok");
}
}
Your purpose is perform different task for different gridview row with same menu item click event.
1- On mouse down, just save the DataGridView rowIndex.
2- On menu item click event, use the saved rowindex to decide your different task.
3- Since Mouse click will fire after context menu hence use MouseDown Instead mouse click event.
int RowIndex = 0;
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (dataGridView1.CurrentRow == null)
return;
if (e.Button == MouseButtons.Right)
{
RowIndex = dataGridView1.CurrentRow.Index ;
}
}
private void testToolStripMenuItem_Click(object sender, EventArgs e) //MenuStrip item click event
{
if (RowIndex == 0)
{
}
else if (RowIndex == 1)
{
}
}

DataGridView CellDrag too sensitive

I have a datagridview control on winforms with the following event to drag 'row' out of datagrid:
private void gridOperations_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
if (Math.Abs(e.X - mouseDownPos.X) >= SystemInformation.DoubleClickSize.Width || Math.Abs(e.Y - mouseDownPos.Y) >= SystemInformation.DoubleClickSize.Height)
{
string[] filesToDrag = { "tmp/generated.log" };
gridOperations.DoDragDrop(new DataObject(DataFormats.FileDrop, filesToDrag), DragDropEffects.Copy);
}
}
}
The problem is I also have click and double click events on datagridview, the double click event almost never gets executed at first, unless I don't move my mouse at all when clicking. how can I add a 'thershold' so that if I hold mouse down and drag cell for 3 pixels, then it will trigger gridOperations.DoDragDrop? Thanks!
try to use an integer counter.
Every time the Event is fired you increment the int and if it is reaches your treshold you execute the rest of the Code and reset it to 0.
like:
private int thCount = 0;
private void gridOperations_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left && thCount==5)
{
//...
thCount = 0;
}
else
{
thCount++;
}
}
hope i could help you

Close tab on winforms tab control with middle mouse button

Is there any easy (5 lines of code) way to do this?
The shortest code to delete the tab the middle mouse button was clicked on is by using LINQ.
Make sure the event is wired up
this.tabControl1.MouseClick += tabControl1_MouseClick;
And for the handler itself
private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
var tabControl = sender as TabControl;
var tabs = tabControl.TabPages;
if (e.Button == MouseButtons.Middle)
{
tabs.Remove(tabs.Cast<TabPage>()
.Where((t, i) => tabControl.GetTabRect(i).Contains(e.Location))
.First());
}
}
And if you are striving for least amount of lines, here it is in one line
tabControl1.MouseClick += delegate(object sender, MouseEventArgs e) { var tabControl = sender as TabControl; var tabs = tabControl.TabPages; if (e.Button == MouseButtons.Middle) { tabs.Remove(tabs.Cast<TabPage>().Where((t, i) => tabControl.GetTabRect(i).Contains(e.Location)).First()); } };
Solution without LINQ not so compact and beautiful, but also actual:
private void TabControlMainMouseDown(object sender, MouseEventArgs e)
{
var tabControl = sender as TabControl;
TabPage tabPageCurrent = null;
if (e.Button == MouseButtons.Middle)
{
for (var i = 0; i < tabControl.TabCount; i++)
{
if (!tabControl.GetTabRect(i).Contains(e.Location))
continue;
tabPageCurrent = tabControl.TabPages[i];
break;
}
if (tabPageCurrent != null)
tabControl.TabPages.Remove(tabPageCurrent);
}
}
Don't have enough points to post a comment to the provided solutions but they all suffer from the same flaw: The controls within the removed tab are not released.
Regards
You could do this:
private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Middle)
{
// choose tabpage to delete like below
tabControl1.TabPages.Remove(tabControl1.TabPages[0]);
}
}
Basically you are just catching a mouse click on tab control and only deleting a page if the middle button was clicked.

Categories

Resources