Close tab on winforms tab control with middle mouse button - c#

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.

Related

Double Click on label open Form C#

Im trying to open a new form when a label is double clicked. Im able to drag and drop the label .Im trying to open a new form on double click of label now.
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
this.DoDragDrop(control.Name, DragDropEffects.Move);
}
private void control_DoubleClick(object sender, EventArgs e)
{
frm = new Frm();
frm.ShowDialog();
frm.Dispose();
}
EDIT 1:
I have tried both possible answers below, and they have not worked for me?
A more cleaner way is (note I changed Frm to Form1):
private void control_DoubleClick(object sender, EventArgs e)
{
using (Form1 frm = new Form1())
{
frm.ShowDialog();
}
}
You can't add DragDrop on MouseDown and then DoubleClick. That won't work.
I don't think there's an easy way to get around that, but once a control is being dragged, it won't respond to double click messages.
I've made some quick tests, and there's a "hacky" way. It'll make your dragging look weird (since it'll start after some time, instead of immediately after you press the mouse button), but here it goes:
private bool _willDrag = false;
private bool control_MouseUp(object sender, MouseEventArgs e)
{
// disable dragging if we release the mouse button
_willDrag = false;
}
private bool control_DoubleClick(object sender, EventArgs e)
{
// disable dragging also if we double-click
_willDrag = false;
// .. the rest of your doubleclick event ...
}
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
if (control == null)
return;
_willDrag = true;
var t = new System.Threading.Timer(s =>
{
var callingControl = s as Control;
if (callingControl == null)
return;
// if we released the mouse button or double-clicked, don't drag
if(!_willDrag)
return;
_willDrag = false;
Action x = () => DoDragDrop(callingControl.Name, DragDropEffects.Move);
if (control.InvokeRequired)
control.Invoke(x);
else
x();
}, control, SystemInformation.DoubleClickTime, Timeout.Infinite);
}
In the form.Designer right click on your label then properties, in the properties window click in events (the thunder icon), in the double_Click event dropdown select the event handler (control_DoubleClick) this method must have two parameters an object and a eventArgs
This is tricky as the DoDragDrop will eat up any further mouse events, and MSDN posting a rather stupid example doesn't help much.
Solution: Do not start the D&D in the MouseDown if you want to still receive click or double click events but use the MouseMove instead:
Replace this
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
this.DoDragDrop(control.Name, DragDropEffects.Move);
}
by this:
private void control_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
DoDragDrop((sender as Control), DragDropEffects.Move);
}
Don't forget to hook up the new event!

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.

Determining which tabpage has opened

I'm trying to get the tabpage that was clicked by right button of mouse,in another words the tabpage that opened the contextmenustrip.
There's a toolstripmenuitem called Close which I used to close the tab that was clicked on.
I used this code :
public partial class USBrowser : Form
{
private Point lastpoint;
}
private void closeTabToolStripMenuItem_Click(object sender, EventArgs e)
{
for (int i = 0; i < browserTabControl.TabCount; i++)
{
Rectangle rec = browserTabControl.GetTabRect(i);
if (rec.Contains(this.PointToClient(lastpoint)))
closeTab(i);//this function closes the tab at specific index
}
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (e.Button == MouseButtons.Right)
lastpoint = Cursor.Position;
}
I also added(when adding the tabpage) :
browserTabControl.TabPages.Insert(browserTabControl.TabCount - 1,WebPage);
browserTabControl.SelectTab(WebPage);
browserTabControl.SelectedTab.MouseClick += SelectedTab_MouseClick;
void SelectedTab_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
lastpoint = Cursor.Position;
}
The problem is that the lastpoint is always (0,0) !!
Why ?
Any other suggested idea is welcomed
thanx in advance
None of these event handlers will actually run. Not the form's OnMouseClick() method since you are not actually right-clicking the form. And not the tab page's MouseClick event handler since you gave the TabControl a context menu. So lastpoint being empty is the expected outcome.
It is not clear how you want this context menu to work. If you use it by right-clicking the tab page then it is simple, just destroy the selected page:
private void closeToolStripMenuItem_Click(object sender, EventArgs e) {
tabControl1.SelectedTab.Dispose();
}
If you activate it by right-clicking a tab, one that isn't selected, then it gets more complicated. You have to memorize which tab was clicked on, do so by using the context menu's Opening event:
private TabPage RightClickedTab;
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) {
RightClickedTab = tabControl1.SelectedTab;
var pos = tabControl1.PointToClient(Cursor.Position);
for (int tab = 0; tab < tabControl1.TabCount; ++tab) {
if (tabControl1.GetTabRect(tab).Contains(pos)) {
RightClickedTab = tabControl1.TabPages[tab];
break;
}
}
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e) {
if (RightClickedTab != null) RightClickedTab.Dispose();
}

How to focus a certain tabpage when it rightclicked?

How to select or focus a certain tabpage when it right clicked?
Implement the MouseDown event and find out what tab got clicked:
private void tabControl1_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Right) {
for (int tab = 0; tab < tabControl1.TabCount; ++tab) {
if (tabControl1.GetTabRect(tab).Contains(e.Location)) {
tabControl1.SelectedIndex = tab;
break;
}
}
}
}

Categories

Resources