i am creating simple inventory system. i need only this if i click picturebox 1 relavent message should display "pic1" if i click piturebox 2 relavent message should display "pic2"
public Form1()
{
InitializeComponent();
this.MouseClick += mouseClick;
}
private void mouseClick(object sender, MouseEventArgs e)
{
var clickedPictureBox = (PictureBox)sender;
if (clickedPictureBox == pictureBox1)
{
MessageBox.Show("Pic1");
}
}
i tried the code but it is not working
First, you're using the form's mouse click event, you'll need to replace:
this.MouseClick += mouseClick;
by:
pictureBox1.MouseClick += mouseClick;
pictureBox2.MouseClick += mouseClick;
Option 1: Use the sender object
The mouse click event gives you the argument sender, which is the object that triggered the event.
So you could use it like this:
var clickedPictureBox = (PictureBox)sender;
if (clickedPictureBox == pictureBox1)
...
Option 2: use a tag
You can set tags in your winforms elements and use them. For example, go to the Designer and set the tag of both pictures to "Pic1" and "Pic2" and then use it like this:
var clickedPictureBox = (PictureBox)sender;
if (clickedPictureBox.Tag.ToString() == "Pic1")
...
Related
Well, I'm making a chess game that's based on labels. I need to listen for label click, so when user clicks on an label, I get the name of label he clicked. I know I can do it for each label, but is there an universal event that would help me do the same thing for all of them in one event / loop?
Suppose you have taken 64 labels.
In windows form, on click event of Label1 you will write following code:
private void Label1_Click(object sender, EventArgs e)
{
var label = sender as Label;
MessageBox.Show(label.Name);
}
For remaining 63 Lables, In Design view, select all 63 lables by using Ctrl key --> Go to Property window --> Under Event option select Click option --> From dropdownlist select 'Label1_Click' option.
Just finish & run the application.
You can use a Panel
structure to group your labels and then call the desired event on that Panel, so it will trigger whenever you click one of it's elements.
Another solution would be to identify your label with the coordinates of the mouse click (the amount of code that requires depends how you placed them of course).
Like mentioned in the comments you can assign one event to all...
List<Label> lbls = this.Controls.OfType<Label>().ToList();
foreach (var lbl in lbls)
{
lbl.Click += lbl_Click;
}
void lbl_Click(object sender, EventArgs e)
{
Label lbl = sender as Label;
MessageBox.Show(lbl.Name);
}
You can assign these methods to every label you need to manage in the VS form designer (you go to events of controls, at the click line and select the method in the list instead of double click on it):
private void Label_Click(object sender, EventArgs e)
{
var nameLabel = ( sender as Label )?.Name ?? "Error";
// ...
}
private void Label_Enter(object sender, EventArgs e)
{
( sender as Label ).Cursor = Cursors.Hand;
}
private void Label_Leave(object sender, EventArgs e)
{
( sender as Label ).Cursor = Cursors.Default;
}
Cursor change added for convenience if you want.
If you want to dynamically assign events, you can use the #caner answer, and you can group all in a panel to parse Panel.Controls and assign event.
You can create a custom label class that inherits from Label. You can then subscribe to the Click event of the base class and do your thing.
public class MyLabel : Label
{
public MyLabel()
: base()
{
Click += ProcessClickEvent;
}
private void ProcessClickEvent(object sender, System.EventArgs e)
{
// Do what you want to do
}
}
I am capturing click coordinates within a PictureBox but I want to achieve the same thing with a WebBrowser. After some research I found out that it is not possible to subscribe to the Mouse Click event of a WebBrowser control.
What are the possible ways to capture the clicks? Is there a sort of element which would allow me to navigate through the page but still capture the click?
I tried to create a transparent panel but transparent color doesn't mean see through as I see and when the element is in the back also doesn't capture the click, being able to capture the clicks with panel being behind the WebBrowser would also work.
PictureBox code:
private void uploadedPNG_MouseClick(object sender, MouseEventArgs e)
{
if(uploadedPNG.Image != null && !string.IsNullOrEmpty(deviceHeight.Text) && !string.IsNullOrEmpty(deviceWidth.Text))
{
mouseX = e.X;
mouseY = e.Y;
targetHeight = Int32.Parse(deviceHeight.Text);
targetWidth = Int32.Parse(deviceWidth.Text);
int outPutWidth = (mouseX * targetWidth) / uploadedPNG.Width;
int outPutHeight = (mouseY * targetHeight) / uploadedPNG.Height;
ConsoleText.Text = "Clicked X coordinate " + outPutWidth + " Clicked Y coordinate " + outPutHeight;
}
}
The WebBrowser itself doesn't provide Mouse Click coordinates: you're not actually clicking on the Control client area, you're clicking on the content of the HtmlDocument.
You can use the HtmlDocument.Click or HtmlDocument.MouseDown events to retrieve the Mouse pointer coordinates on an initialized HtmlDocument.
Note:
The HtmlElementEventArgs object returns the Mouse coordinates in both absolute coordinates (the whole Document area), in e.ClientMousePosition and relative to the clicked HtmlElement, in e.OffsetMousePosition.
This can be tricky, because you need to subscribe to the Click event when the current HtmlDocument is already created: you cannot subscribe to the event of the default Document object:
i.e., subscribing to the event in Form.Load with:
webBrowser1.Document.Click += (obj, evt) => { /*Do something */ };
will not accomplish anything. The event will never be raised: the Document is null thus, of course, it's not referency any current/active HtmlDocument.
An HtmlDocument is ready when the WebBrowser.DocumentCompleted event is raised and its ReadyState is set to WebBrowserReadyState.Complete.
You can subscribe to the Document.Click event when the Document is fully loaded, then remove the event before the WebBrowser navigates to a new page, creating a new document.
Also, the DocumentCompleted event may be raised multiple times for a single HTMLpage, so you need to be sure that you don't subscribe to the same event multiple times:
Note:
A HtmlDocument may contain more than one Frame/IFrame and each Frame may have its own HtmlDocument; IFrames have one each for sure. Refer to the notes in this question for more informations on this matter:
How to get an HtmlElement value inside Frames/IFrames?
An example:
bool WebBrowserDocumentEventSet = false;
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = (sender as WebBrowser);
if (wb.ReadyState == WebBrowserReadyState.Complete && WebBrowserDocumentEventSet == false)
{
WebBrowserDocumentEventSet = true;
wb.Document.MouseDown += this.OnHtmlDocumentClick;
}
}
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
(sender as WebBrowser).Document.MouseDown -= this.OnHtmlDocumentClick;
WebBrowserDocumentEventSet = false;
}
protected void OnHtmlDocumentClick(object sender, HtmlElementEventArgs e)
{
Console.WriteLine(e.ClientMousePosition);
}
I'm wanting to detect a right click on any PictureBox in the form. I have already set up the right click function for one PictureBox. This is fine but I would like one event that will fire for all right clicks on PictureBoxes on the form.
This right click even will need to know the PictureBox name because the context menu will be different for some of the PictureBoxes.
Here is the code I have for the right click event for one PictureBox.
private void DesktopIcon1Icon_MouseClick(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Right:
{
DesktopIconRightclick.Show(this, new Point(e.X, e.Y));
}
break;
}
}
I need to adapt this code to fire if any PictureBox is right clicked.
Example Update
if (pic = DesktopIcon2)
{
openToolStripMenuItem.visible = false;
}
You can use one event that will fire for all right clicks on PictureBoxes like this:
public Form1()
{
InitializeComponent();
pictureBox1.MouseClick += pictureBox_MouseClick;
pictureBox2.MouseClick += pictureBox_MouseClick;
}
Then you can use Sender to find PictureBox's Name like this:
private void pictureBox_MouseClick(object sender, MouseEventArgs e)
{
var pic = (sender as PictureBox).Name;//pic is the Name of the PictureBox that is clicked
switch (e.Button)
{
case MouseButtons.Right:
{
MessageBox.Show(pic);//Just for example
DesktopIconRightclick.Show(this, new Point(e.X, e.Y));
}
break;
}
}
You can try using reflection to find all PictureBox instances.
Check GetTypes as a starting point.
Check this SO for implementation example:
Using reflection to get all classes of certain base type in dll
I have Form, it has 1 Panel and Panel has 0-N PictureBox's - dynamically added to the Panel, but if I take my mouse over the PictureBox and click on it, it don't fire any action. I mean when I click on Panel, it fire the click method, but how I can make sure that those PictureBox's also behave the same way?
Since picture boxes are added dinamically you need to attach event handelers for the click event in your code.
do somthing like this just before you add it to the control collection..
PictureBox pbx = new PictureBox();
pbx.Click += new EventHandler(pbx_Click);
//Now assign other properties and then add it to control collection
//panel1.Controls.Add(pbx);
private void pbx_Click(object sender, EventArgs e)
{
//handle the click event here
}
Is your PictureBoxes are added dynamically to the Panel, then the Click event of the PictureBox must also be added.
Note that you can handle all of the PictureBoxes Click event in the same handler:
for (int i = 0; i < 10; i++)
{
PictureBox pb = new PictureBox();
pb.Name = "pb" + i;
pb.Click +=new EventHandler(pb_Click);
this.Controls.Add(pb);
}
void pb_Click(object sender, EventArgs e)
{
PictureBox pb = (PictureBox) sender;
if (pb.Name == "pb1")
{
...
}
}
You get the idea...
I am creating an application where I need to generate dynamically created controls say textbox or label etc.
Now what I that user can relocate that textbox to his desired location. Like we do in Visual Studio.
One way is to get new location by getting values from him using textbox. But I want the user interface easy.
Can we have such functionality in winforms
I have created a simple form that demonstrate how to move the control by dragging the control.
The example assumes there is a button named button1 on the form attached to the relevant event handler.
private Control activeControl;
private Point previousLocation;
private void button1_Click(object sender, EventArgs e)
{
var textbox = new TextBox();
textbox.Location = new Point(50, 50);
textbox.MouseDown += new MouseEventHandler(textbox_MouseDown);
textbox.MouseMove += new MouseEventHandler(textbox_MouseMove);
textbox.MouseUp += new MouseEventHandler(textbox_MouseUp);
this.Controls.Add(textbox);
}
void textbox_MouseDown(object sender, MouseEventArgs e)
{
activeControl = sender as Control;
previousLocation = e.Location;
Cursor = Cursors.Hand;
}
void textbox_MouseMove(object sender, MouseEventArgs e)
{
if (activeControl == null || activeControl != sender)
return;
var location = activeControl.Location;
location.Offset(e.Location.X - previousLocation.X, e.Location.Y - previousLocation.Y);
activeControl.Location = location;
}
void textbox_MouseUp(object sender, MouseEventArgs e)
{
activeControl = null;
Cursor = Cursors.Default;
}
It is the easiest way: First go to your solution name and right click. Select "Manage NuGet Packages". After a while a window opens with a search bar on top of it. Choose the "Browse option " and search DraggableControl package. The name Control.Draggable must be seen. Click on it then click install. Now you can use it's special commands for example.
private void button1_Click(object sender, EventArgs e)
{ Point p = new Point(20,70 * i);
RichTextBox tb = new RichTextBox();
tb.Location = p;
tb.Height= 60;
tb.Width = 100;
tb.Font = Normal;
ControlExtension.Draggable(tb,true);
this.Controls.Add(tb);
i++;
The ControlExtension.Draggable command can set it to be draggable or not. Just write the name of the object in the brackets (tb for me) and write a comma. Then write it is draggable (true) or not (false).
NOTE: Do not Forget to put a semicolon.
Hope it helps.
Link : https://www.nuget.org/packages/Control.Draggable/
You can call DoDragDrop with a data object containing or representing the control to begin a drag&drop operation, then handle the container's DragDrop event and move the control.
If you want to see the control as it's dragged, you can either make a transparent (handle WM_NCHITTEST) form under the mouse showing the control (call DrawToBitmap), or not use drag&drop at all and instead handle mouse events and track state manually.
If you want Visual Studio-style snaplines, you can compare the control's bounds to other controls, make a set of lines to draw, and draw them in a paint event.