Sorry, this is kinda beginner question but I'm not getting through.
I have a Windows Forms Applicaton with 4 panel controls on it. Now I want that the panels change their background when the user hovers with the mouse. I have tried following:
private void Panel1_MouseIn(object sender, EventArgs e)
{
panel1.BackColor = Color.Red;
}
private void Panel1_MouseOut(object sender, EventArgs e)
{
panel1.BackColor = Color.Blue;
}
That is working fine, but because I have 4 panels and not one I would have to add 6 more functions like this... The I tried to make one single function for all of them but event sender does not have an accessible BackColor property.
Is there a way to make one single MouseIn function for all panels?
If yes, how?
YOu should cast it:
private void Panel_MouseIn(object sender, EventArgs e)
{
Panel pan = sender as Panel;
pan.BackColor = Color.Red;
}
And use this one function for all 4 panels as event handler
You can cast your sender-object to a Panel like
Panel panel = (Panel)sender;
if(panel != null)
// Set the BackColor
You should first cast the sender object to Panel :
Panel panel = sender as Panel;
if (panel == null)
return;
panel.BackColor = Blue;
You could define an EventHandler for MouseIn and MouseOut and then
private void Panel1_MouseIn(object sender, EventArgs e)
{
Panel p = sender as Panel;
if(p == panel1){
//set color
}
else if(p == panel2){
//set color
}
...
}
The same for MouseOut
Inside mouse in and function remove all the code you have placed and write the one simple line of code below
And try it it will work
((Control)sender).BackColor = Color.Red;
Related
I'm doing some kind of a pixel film editor and my problem there is that I am using Labels which I have to click individually to change their color, I would like to change the color by holding down the mouse button and just hovering above the Label.
Is there any Event or such to do so? I didn't find one. At the moment I am using Mouse_Down.
A look on the Editor
my Mouse_Down Event:
private void Mouse_Down(object sender, MouseEventArgs e)
{
var ActiveLabel = sender as Label;
if (ActiveLabel != null)
{
ActiveLabel.BackColor = ActiveColor.BackColor;
}
}
So I want it like on GIMP or stuff, to not click any single "pixel" but instead click and hold the mouse button and move it around and color all pixels I move over whilst my mouse is pressed.
Here's the idea:
You have a flag (boolean) which indicates whether the user is currently painting or not. If the mouse hovers over a label (event MouseEnter), you check whether it should be painted or not. If it shall be painted, you apply the code you already have.
bool paintmode = false;
// Assign this to all labels, since you don't know
// where the user will start painting
private void Mouse_Down(object sender, MouseEventArgs e)
{
paintmode = true;
}
// Make sure you assign this to all items, even the Form
// as you'll never know where the user will release the mouse
private void Mouse_Up(object sender, MouseEventArgs e)
{
paintmode = false;
}
// Assign this only to labels which can get painted
private void Mouse_Enter(object sender, MouseEventArgs e)
{
if (paintmode)
{
var ActiveLabel = sender as Label;
if (ActiveLabel != null)
{
ActiveLabel.BackColor = ActiveColor.BackColor;
}
}
}
I have a custom user control that contains a chart element that takes up 80% of the space.
When this is placed in a form, i can click the area not occupied by the chart and the click/mousedown/mouseup events work. But yet when i click in the chart area the mouse events aren't passed through and therefore not triggered.
Is there a global way of doing this without having at add the event function for each control on the form?
void Drag_MouseDown(object sender, MouseEventArgs e)
{
activeControl = sender as UserControl;
previousLocation = e.Location;
Cursor = Cursors.SizeAll;
}
void Drag_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 Drag_MouseUp(object sender, MouseEventArgs e)
{
activeControl = null;
Cursor = Cursors.Default;
}
These are at the moment having to be manually set to both the custom usercontrol and the chart
It seems like chart overrides your mouse events. So, you can try to add event listeners to chart as well.
PS: We can assign same method to different listeners.
I have a form that has a set of labels that can be clicked - See Screenshot (Labels 93 to Label 21 on the Player side and labels 10 to 22 on the computer side).
All I want to do is change the label back colour when the control is clicked. This I have figured out.
My question is more about clean code. Instead of having
private void Playerlabel_Click(object sender, EventArgs e)
{
lblPlayerCardInt.BackColor = Color.FromArgb(219, 255, 248);
}
private void Playerlabel2_Click(object sender, EventArgs e)
{
lblPlayerCardStrength.BackColor = Color.FromArgb(219, 255, 248);
}
//repeat 5 times and then another 5 times for the computer labels.
Is there a way of defining a method so that no matter if I click the label or the computer clicks it, the method of highlighting the label is called.
I'm think something along the lines of
public void HighlightLabel()
{
foreach (Control x in this.Controls)
{
if (x is Label)
{
((Label)x).BackColor = Color.FromArgb(219, 255, 248);
}
}
}
Is this the right approach? It may seem like an obvious question, but new to programming in C#/OOP so want to be sure I'm doing it the correct way.
Yes you can set only 1 Click event-handler for all those labels:
Step 1:
private void lbl_Click(object sender, EventArgs e)
{
Label lbl = sender as Label;
lbl.BackColor = Color.FromArgb(219, 255, 248);
}
Step 2:
If you create labels on design time then do the following for each label:
On Form designer, select label then open View > Properties > Events tab
Select above lbl_Click event-handler from the dropdown list
OR
If your create labels programatically then use this instead:
lblPlayerCardInt.Click += new EventHandler(lbl_Click);
lblPlayerCardStrength.Click += new EventHandler(lbl_Click);
...
Seeing as all you're doing is setting the backcolor each time why not just have 1 method and do something like:
private void label_Click(object sender, EventArgs e)
{
Label mylabel = (Label) sender;
mylabel.backcolor = Color.FromArgb(219, 255, 248);
}
You can then just put Label_Click in as the click event for each label rather than doing a separate method for each label.
However, if you want to do more based on the label you can use the sender to determine the label clicked. Something like this:
private void label_Click(object sender, EventArgs e)
{
Label mylabel = (Label) sender;
//Determine which label has been clicked by name or id for example
switch(myLabel.Name)
{
case "lblPlayerCardint":
//Do something
break;
}
}
You could cast the event sender object to a label
private void label_Click(object sender, EventArgs e)
{
Label lblClicked=sender as Label;
lblClicked.BackColor = Color.FromArgb(219, 255, 248);
}
You could use OfType which is part of the System.Linq namespace:
foreach(Label lbl in this.Controls.OfType<Label>())
lbl.BackColor = Color.FromArgb(219, 255, 248);
This should do the trick for you and register the same click event for all your labels on the form.
this.Controls
.OfType<Label>()
.AsParallel()
.ForAll(x => x.Click += (o,e) => x.BackColor= Color.FromArgb(219, 255, 248));
I have the following problem: I have a panel which has a specific color, say red.
When the user presses his mouse, the color of this panel gets stored in a variable. Then the user moves, his mouse still pressed, over to another panel. When he releases the mouse there, this panel should get the background color of the first that had been stored in the variable. My code looks something like this:
public Color currentColor;
private void ColorPickMouseDown(object sender, MouseEventArgs e)
{
Panel pnlSender = (Panel)sender;
currentColor = pnlSender.BackColor;
}
private void AttempsColorChanger(object sender, MouseEventArgs e)
{
Panel pnl = (Panel)sender;
pnl.BackColor = currentColor;
}
I need to identify the sender first because there are many possible panels that can trigger this event. The first MouseDown method works totally fine, the color is stored nicely in the variable. The secon one however doesn't even get triggered when the user does what I described above. When the ser clicks on the second panel, it works (there is an MouseUp part in a click aswell I guess).
What's wrong here? Why is the event not triggered when the user holds the mouse key down before?
(This answer assumes you are using Windows Forms.)
It could be that you need to capture the mouse by setting this.Capture = true in the MouseDown of the source control. (See Control.Capture)
If you did that, the source window would get the MouseUp event, and it would be the source window that had to determine the destination window under the mouse coords. You can do that using Control.GetChildAtPoint() (see this answer on Stack Overflow).
Use Windows Forms Drag and Drop Support Instead! <- Click for more info
I'm going to suggest you bite the bullet and use the .Net Drag and Drop methods to do this. It requires some reading up, but it will be much better to use it.
You start a drag in response to a MouseDown event by calling Control.DoDragDrop().
Then you need to handle the Control.DragDrop event in the drop target control.
There's a few more things you might need to do to set it up; see the Control.DoDragDrop() documentation for an example.
(For WPF drag and drop support, see here.)
when your mouse enter the target control , mouse down triggerd ang get target BackColor! you need add an boolean flag to your code :
public Color currentColor;
bool flag=false;
private void ColorPickMouseDown(object sender, MouseEventArgs e)
{
if(flag==false)
{
flag=true
Panel pnlSender = (Panel)sender;
currentColor = pnlSender.BackColor;
}
}
//assume mouse up for panles
private void AttempsColorChanger(object sender, MouseEventArgs e)
{
if(flag==true)
{
Panel pnl = (Panel)sender;
pnl.BackColor = currentColor;
flag=flase;
}
}
and also you need change your flag in mouseMove( if )
As I mentioned in my comment Mouse Events are captured by the originating control, You would probably be better off using the DragDrop functionality built into Windows Forms. Something like this should work for you. I assigned common event handlers, so they can be assigned to all of your panels and just work.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void panel_MouseDown(object sender, MouseEventArgs e)
{
((Control)sender).DoDragDrop(((Control)sender).BackColor,DragDropEffects.All);
}
private void panel_DragDrop(object sender, DragEventArgs e)
{
((Control)sender).BackColor = (Color)e.Data.GetData(BackColor.GetType());
}
private void panel_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
}
I know it's an old question but I had the same issue and none of the above answers worked for me. In my case I had to handle the MouseMove event in the target control and check for the mouse to be released. I did set 'BringToFront' on my target panel just in case that helped at all.
public Color currentColor;
private void ColorPickMouseDown(object sender, MouseEventArgs e)
{
Panel pnlSender = (Panel)sender;
currentColor = pnlSender.BackColor;
}
private void panelTarget_MouseMove(object sender, MouseEventArgs e)
{
//the mouse button is released
if (SortMouseLocation == Point.Empty)
{
Panel pnl = (Panel)sender;
pnl.BackColor = currentColor;
}
}
I have created a Table layout in windows forms as shown in figure, i have added a right mouse button click Menu to my table, i want to color the cell when i right click on the perticuler cell, so how can i do it.
When i click add device the cell should paint to green color,
When i click delete device it should show default color,
When i click fire the cell should be painted with red color
so on
The below is my form and table layout
Hi there i dont have what you looking for but,
TableLayoutPanels don't really have 'cells' as such and are really meant to be a container for controls. This means you can't really retrieve individual rows, columns or cells. An alternative would be to use panels and put individual click events on each of these.
However if you're determined that you want to use TableLayoutPanels, you can use the XY coordinate of where the mouse click occurred on the TableLayoutPanel from EventArgs. And determine which block it is, since you've got evenly spread rows/columns.
For example if you have all the cells the same size and the the TableLayoutPanel is docked in the form this will get the selected Cell.:
Point selectedCell = new Point();
private void tableLayoutPanel1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
//show contextMenuStrip
selectedCell = new Point(e.X / (tableLayoutPanel1.Width / tableLayoutPanel1.ColumnCount), e.Y / (tableLayoutPanel1.Height / tableLayoutPanel1.RowCount));
}
}
I got the answer for my question it can be done as shown below
First we need to find the label control(sender) which has sent the event as follows
private void AssignClickEvent()
{
foreach (Control c in tableLayout.Controls.OfType<Label>())
{
c.MouseClick += tablelayout_MouseClick;
addDevice.Click += addDevice_Click;
deleteDevice.Click += deleteDevice_Click;
fire.Click += fire_Click;
fault.Click += fault_Click;
suppress.Click += suppress_Click;
}
}
have a globle varible of pointer control
public Label h = new Label();
then we need to copy the sender to the control
private void tablelayout_MouseClick(object sender, MouseEventArgs e)
{
Label l = (Label)sender;
if (e.Button == MouseButtons.Right)
{
h = l;
num = l.Text;
m.MenuItems.AddRange(new MenuItem[] { addDevice, deleteDevice, fire, fault,suppress });
tableLayout.ContextMenu = m;
m.Show((Control)(sender), e.Location);
}
}
then use global control `h' to set color to the control
public void addDevice_Click(object sender, EventArgs e)
{
try
{
h.BackColor = Color.Green; ;
comport.Write("AB");
comport.Write(num);
comport.Write(" ");
stausLable.Text = "Device "+num+" added";
comport.WriteLine("000000000000");
}
catch (InvalidOperationException )
{
stausLable.Text = "Open communication port";
}
}
There is an easier way without having to implement those events as well as the extra variables. Assuming the contextmenu is named 'DeviceActionsContextMenu' and is linked to the label controls (as per your comment), Implement the toolstrip Item's click event -
private void addDeviceToolStripMenuItem_Click(object sender, EventArgs e)
{
(contextMenuStrip1.SourceControl as Label).BackColor = Color.Green;
}
Or Implement the contextmenu's Item clicked event -
private void DeviceActionsContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem == addDeviceToolStripMenuItem)
{
(contextMenuStrip1.SourceControl as Label).BackColor = Color.Green;
}
}