thanks to http://www.eqqon.com/index.php/Piccolo_Snippets, i had mousewheel zooming working well until i added winform widgets to the form outside of the canvas; see pic of a test form below:
i found that if i clicked on button1, and moused back onto the canvas, i no longer get mousewheel events. Other mouse events (e.g. PNode entry/leave) still work however. even after clicking on the canvas, the mousewheel is still dead. the canvas's mousedown event works fine also. so only the mousewheel breaks. below is minimalist code to demonstrate what i'm seeing.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UMD.HCIL.Piccolo;
using UMD.HCIL.Piccolo.Event;
using UMD.HCIL.Piccolo.Nodes;
namespace piccolo_wheel_test {
public partial class Form1 : Form {
int mdown_count = 0;
int mwheel_count = 0;
public Form1() {
InitializeComponent();
PNode rect = PPath.CreateRectangle(40, 40, 20, 50);
rect.Brush = Brushes.Blue;
pCanvas1.Layer.AddChild(rect);
pCanvas1.Camera.MouseWheel += new PInputEventHandler(Camera_MouseWheel);
pCanvas1.Camera.MouseDown += new PInputEventHandler(Camera_MouseDown);
}
void Camera_MouseWheel(object sender, PInputEventArgs e) {
Debug.WriteLine("got mouse wheel: " + (mwheel_count++).ToString());
}
void Camera_MouseDown(object sender, PInputEventArgs e) {
Debug.WriteLine("got mouse down: " + (mdown_count++).ToString());
}
private void pCanvas1_Enter(object sender, EventArgs e) {
Debug.WriteLine("enter pcanvas");
}
private void pCanvas1_Leave(object sender, EventArgs e) {
Debug.WriteLine("leave pcanvas");
}
private void button1_Enter(object sender, EventArgs e) {
Debug.WriteLine("enter button");
}
private void button1_Leave(object sender, EventArgs e) {
Debug.WriteLine("leave button");
}
}
}
as an aside, i see that the canvas does not raise "enter"/"leave" events consistently; i see one "enter" when the form loads and one "leave" if i click button1 but no more "enter"/"leave" if i go back and forth. further, when i click on button1, i raises its "enter" event but when i click back on the canvas, "button1" doesn't raise its "leave" event (which it does if i clicked on other winform widgets, such as the trackbar.) thanks.
Related
I'm trying to make a button follow the cursor, but my code only seems to just go to the mouse cursor right after execution and just stay there. Can anyone give me the correct code and help me?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
button1.Location = Cursor.Position;
}
}
}
I would suggest overriding the OnMouseMove method of the MainForm and using the Location property of the MouseEventArgs e argument. This will provide the correct Client coordinates of the cursor taking into account where MainForm is located on the screen. Then you can offset that value using the Width and Height properties of buttonMoveMe to center it on the mouse.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
var point = new Point(
e.Location.X - (buttonMoveMe.Width / 2),
e.Location.Y - (buttonMoveMe.Height / 2));
buttonMoveMe.Location = point;
}
}
Be aware that this event _will not be received when the mouse is over the button itself. The button will be getting the MouseMove events (not the MainForm) in this case. In other words, this basic suggestion only moves the button when the mouse leaves the button.
I think you need to use the MouseMove event.
So these are things you need to do:
Create a button control which is going to follow the cursor. (I will call it yourButton)
Open event menu of the control (click on it in the constructor).
Find event MouseMove inside Mouse category.
Double click on it. (This will automatically create the method which will be linked to the event)
In this method write: yourButton.Location = e.Location;
So it should look like that:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
yourButton.Location = e.Location;
}
In my example I made button follow my cursor inside the form.
If you need shorter way, you can just copy-paste the method I wrote before and in the form class constructor add:
this.MouseMove += Form1_MouseMove;
In this way your code would look like that:
public Form1()
{
InitializeComponent();
this.MouseMove += Form1_MouseMove;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
yourButton.Location = e.Location;
}
Hope this will help you, have a nice day!
UPD:
In case you want the cursor to be in the center of the button, you should edit our previous Form1_MouseMove and add one more event.
Edit the code of Form1_MouseMove, now it should be:
yourButton.Location = new Point(e.X - yourButton.Width / 2, e.Y - yourButton.Height / 2);
Now you need to use MouseMove method of the button (Follow the previous steps, but for button (Click on it -> Events -> Mouse category -> double click on MouseMove))
In newly created method write:
yourButton.Location = new Point(e.X + yourButton.Left - yourButton.Width / 2, e.Y + yourButton.Top - yourButton.Height / 2);
Hope this helped now)
Your Form1_Load method is only executed, as its name says, when the form is loaded.
You want to execute your code every time the mouse move, si you can do it like this (not tested):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MouseMove += Form1_MouseMove;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
button1.Location = Cursor.Position;
}
}
I'm trying to get it so when you click the button (which is START) it brings you two buttons, noob and medium. I can't figure out how to get the second one to show up. The ID is for button1 so I've tried renaming the second to button1 but won't work. How do I pass the button1 again to have it logically produce two buttons from one button?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace App2341
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Text = "Noob";
button1.Location = new Point(100, 100);
}
private void Button2_Click(object sender, EventArgs e)
{
button1.Text = "Medium";
button1.Location = new Point(100, 150);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Try to create the three buttons in the designer and give each one a name, then set the visibility of the start-button to visible and the visibility of the other two buttons to hidden. When you click the start button you set the visibility of the startbutton to hidden and the visibility of the other two buttons to visible.
To set the buttons visibility:
button1.Visible = true; //to show the button
button1.Visible = false; //to hide the button
I'm trying to use the FlowLayoutPanel with linkLabels in Visual Studio for a quick project. I've selected "TopDown" for direction and wrapping to false. When I launch the program; however, the direction always shows left to right. Is there a box or something that I haven't checked? Or is there any reason a linklabel would ignore the flow direction?
Here's my code and some screenshots of what I see.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace myProject
{
public partial class Form1 : Form
{
FlowLayoutPanel panel = new FlowLayoutPanel();
public Form1()
{
InitializeComponent();
linkLabel1.LinkClicked += linkLabel1_LinkClicked;
linkLabel2.LinkClicked += linkLabel2_LinkClicked;
linkLabel3.LinkClicked += linkLabel3_LinkClicked;
Controls.Add(panel);
panel.Controls.Add(linkLabel1);
panel.Controls.Add(linkLabel2);
panel.Controls.Add(linkLabel3);
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
panel.Controls.SetChildIndex(linkLabel1, 0);
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
panel.Controls.SetChildIndex(linkLabel2, 0);
}
private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
panel.Controls.SetChildIndex(linkLabel3, 0);
}
}
}
This is the control view before I've started the program.
This is what I see when I run the program - marked with the red arrow.
Because you are initializing your FlowLayoutPanel in the code-behind, you have to set the FlowDirection property of this new instance of FlowLayoutPanel in the same code-behind:
FlowLayoutPanel panel = new FlowLayoutPanel();
public Form1()
{
InitializeComponent();
panel.FlowDirection = FlowDirection.TopDown;
The FlowLayoutPanel that you declare in your code-behind is separate from the one you have in your layout, so the FlowDirection property is not set the same. I tested the code above and I believe it does what you were looking for.
After looking at Mousewheel event not firing and at MouseWheel event doesn't fire when using any control with scrolbars (in C# Windows Forms) and at MouseWheel Event With Picturebox?, I have coded the following fragment which, well .... doesn't work (i.e., mouse wheel won't fire in VS2013, Win7, x64). Appericate any help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace MyWinForm
{
class Program
{
private Form theForm;
private PictureBox thePictureBox;
static void Main(string[] args)
{
Program theProgram = new Program();
Application.Run(theProgram.theForm);
}
Program()
{
theForm = new Form();
thePictureBox = new PictureBox();
theForm.Controls.Add(thePictureBox);
thePictureBox.Image = Image.FromFile(#"D:\cameraman.bmp");
thePictureBox.Width = theImage.Width;
thePictureBox.Height = theImage.Height;
thePictureBox.MouseWheel += new MouseEventHandler(this.PictureBox_MouseWheel);
thePictureBox.MouseHover += new EventHandler(this.PictureBox_MouseHover);
}
private void PictureBox_MouseWheel(object sender, MouseEventArgs e)
{
Console.WriteLine("2 + 2 = 5");//Will never get here....
}
private void PictureBox_MouseHover(object sender, EventArgs e)
{
thePictureBox.Focus();
}
}
}
It works for me with mouseMove instead of mousehover:
pictureBox1.MouseMove += newEventHandler(this.PictureBox_MouseHover);
Just change the name now from Hover to move so it makes sense:p
In case someone else is looking for the solution.
To make the pictureBox1 fire MouseWheel event I added a MouseEnter event:
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
pictureBox1.Focus();
}
MouseWheel event is center mouse event. You have to scroll center mouse then MouseWheel event will be handled.
I am working on .NET 2.0 with C#. How to make focus the control to picture box after pressing the tab from text box ? Please, give me a solution.
Picturebox control is not selectable control hence it doesn't receive focus. Even if you try to set tabindex and tabstop properties on form load it doesn't get the focus.
Why do you want to set focus to picturebox? Are you using click event of this control as a button click event?
Can you provide some more detail on this, so that we can provide a proper solution for this?
Create a button1, then set its TabIndex less than pictureBox1's; put the button1 on top of pictureBox1. Then on runtime hide it behind pictureBox1. To give visual cue that pictureBox has the focus, set the BorderStyle to Fixed3d, set it to none when it loses focus.
Proof of concept:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestPicture
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.SendToBack();
pictureBox1.Click += button1_Click;
}
private void button1_Enter(object sender, EventArgs e)
{
pictureBox1.BorderStyle = BorderStyle.Fixed3D;
}
private void button1_Leave(object sender, EventArgs e)
{
pictureBox1.BorderStyle = BorderStyle.None;
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Test");
}
}
}
You need to enclose your PictureBox in a control that can receive click events.