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!
Related
I am doing a simple drag and drop operation in windows forms. Whenever I start the operation the cursor changes shape. I know this is directly related to the DragDropEffects and I can't find an option that results in the default cursor. Can anybody help? Here is the code:
a.MouseDown += new MouseEventHandler(ButtonDown);
a.DragEnter += new DragEventHandler(ButtonDragEnter);
a.AllowDrop = true;
and here are the functions:
private void ButtonDown(object sender, EventArgs e)
{
PictureBox p = (PictureBox)sender;
ButtonClick(sender, e);
p.DoDragDrop(p.BackColor, DragDropEffects.All);
}
private void ButtonDragEnter(object sender, DragEventArgs e)
{
e.Data.GetFormats();
e.Effect = DragDropEffects.None;
Color c = new Color();
c = (Color) e.Data.GetData(c.GetType());
ButtonClick(sender, e,c);
}
Ok answered my own question here:
You first need to add an event to giveFeedBack:
a.GiveFeedback += new GiveFeedbackEventHandler(DragSource_GiveFeedback);
and here is the feedback function:
private void DragSource_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
e.UseDefaultCursors = false;
}
I have a range of drag drop activities all working fine on my quiz. (From answering questions to selecting an avatar)
There is a lot of repetition of the code and I am thinking it would be better implemented from a class and call the method each time that I use a drag drop.
Firstly can this be done? and secondly would I need a new method for the dragging and dropping?
Any thoughts or rough ideas would be great.
private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
pictureBox2.DoDragDrop(pictureBox2.Image, DragDropEffects.Copy);
}
private void panel1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void panel1_DragDrop(object sender, DragEventArgs e)
{
//Set background image of panel to selected avatar'
panel1.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
}
If all you want is to avoid duplicating the same events of several controls you should use common events:
private void commonPBox_MouseDown(object sender, MouseEventArgs e)
{
PictureBox PB = sender as PictureBox;
if (PB == null) return; //or throw an exception
PB.DoDragDrop(PB.Image, DragDropEffects.Copy);
}
private void commonPanel_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void commonPanel_DragDrop(object sender, DragEventArgs e)
{
Panel Pan = sender as Panel;
if (Pan == null) return; //or throw an exception
//Set background image of panel to selected avatar
Pan.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
}
Select the respective controls and enter the event names into the respective event name slots in the event pane of the properties tab.
Note how I cast the sender param of the event to get a types reference to the control that triggers the event. If the cast goes wrong the reference is set to null.
If you want more control and more flexibilty you may consider creating a DragAndDropcontroller class..:
static class DnDCtl
{
static List<Control> Targets = new List<Control>();
static List<Control> Sources = new List<Control>();
static public void RegisterSource(Control ctl)
{
if (!Sources.Contains(ctl) )
{
Sources.Add(ctl);
ctl.MouseDown += ctl_MouseDown;
}
}
static public void UnregisterSource(Control ctl)
{
if (Sources.Contains(ctl))
{
Sources.Remove(ctl);
}
}
static public void RegisterTarget(Control ctl)
{
if (!Targets.Contains(ctl))
{
Targets.Add(ctl);
ctl.DragEnter += ctl_DragEnter;
ctl.DragDrop += ctl_DragDrop;
ctl.AllowDrop = true;
}
}
static public void UnregisterTarget(Control ctl)
{
if (Targets.Contains(ctl))
{
Targets.Remove(ctl);
ctl.DragEnter -= ctl_DragEnter;
ctl.DragDrop -= ctl_DragDrop;
}
}
static void ctl_MouseDown(object sender, MouseEventArgs e)
{
PictureBox PB = sender as PictureBox;
if (PB != null) PB.DoDragDrop(PB.Image, DragDropEffects.Copy);
Panel Pan = sender as Panel;
if (Pan != null) Pan.DoDragDrop(Pan.BackgroundImage, DragDropEffects.Copy);
}
static void ctl_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
static void ctl_DragDrop(object sender, DragEventArgs e)
{
Panel Pan = sender as Panel;
if (Pan != null) Pan.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
PictureBox PB = sender as PictureBox;
if (PB != null) PB.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
}
}
Notes:
I have coded symmetric actions for Panels and PictureBoxes to show how you can handle different controls.
I have created but not used Lists of sources and targets. For more complex projects you will find them useful.
I have coded both Register and Unregister methods. You can register after some condition and unregister when it no longer applies
Such a Controller is good for dynamically alowing or disallowing Drag&Drop for controls, esp. when you create them dynamically.
You could also pass around delegates to decouple the dragdrop action from the controller.
Also note that some folks sometimes do prefer to use the MouseMove event over MouseDown esp. as it won't so easily interfere with making a selection.
ListView has a dedicated event instead, ListView.ItemDrag, which obviously should be used when registering!
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.
How can I change a button's style, in particular the image, upon the mouse being pressed and held and then the cursor dragged away from the button?
You'll notice that, on this action, the default behaviour for the button is to revert it's style to hover style. This can be partially configured using the MouseOverBackColor. I want to ensure that, whenever the MouseOverBackColor is applied, I also have a specific image on the button.
I have tried the code below, to have an "isMouseDown" flag which is checked in the leave event. However, this doesn't work for me.
private void btnFormMinimize_MouseClick(object sender, MouseEventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
bool isMouseDown = false;
private void btnFormMinimize_MouseDown(object sender, MouseEventArgs e)
{
Button b = (Button)sender;
b.Image = Properties.Resources.icon_minimize_click;
isMouseDown = true;
}
private void btnFormMinimize_MouseEnter(object sender, EventArgs e)
{
Button b = (Button)sender;
b.Image = Properties.Resources.icon_minimize_hover;
}
private void btnFormMinimize_MouseLeave(object sender, EventArgs e)
{
Button b = (Button)sender;
if (isMouseDown)
{
b.Image = Properties.Resources.icon_minimize_hover;
}
else
{
b.Image = Properties.Resources.icon_minimize;
}
}
private void btnFormMinimize_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown= false;
}
Thanks in advance.
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();
}