I have a panel with 07 buttons that can move them left or right without problems using "drag and drop". My problem is that when I put a button on top of an existing one. I put the button where it already existed 43 button 45 and button 43 is below 45 as shown.
This is my code
private void panelAtalhos_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void panelAtalhos_DragDrop(object sender, DragEventArgs e)
{
//create the button - treeview item selected
Button bt = new Button();
if (createbutton) // createbutton is a global variable
{
bt.Width = 38;
bt.Height = 34;
bt.Top = 2;
bt.Left = panelAtalhos.Controls.Count * (bt.Width);
bt.FlatAppearance.BorderSize = 0;
DateTime data = DateTime.Now;
bt.Text = data.ToString("ss");
bt.FlatStyle = FlatStyle.Flat;
panelAtalhos.Controls.Add(bt);
bt.MouseDown += button_MouseDown;
createbutton = false;
}
else
{
int resto = (int)(System.Windows.Forms.Cursor.Position.X / 38);
((Button)e.Data.GetData(typeof(Button))).Left = resto * 38;
}
}
private void button_MouseDown(object sender, MouseEventArgs e)
{
(sender as Button).DoDragDrop(sender as Button, DragDropEffects.Move);
criarbotao = false;
}
What is missing in the code?
int resto = (int)(System.Windows.Forms.Cursor.Position.X / 38);
You have two problems. One is the Z-order, the other is this statement. It is not correct, you must map the absolute cursor position to the relative position for the button. Relative from the client area of its parent, the panel. Right now you're sending it off into the weeds, too far to the right. Easily far enough that it won't be visible anymore. Code ought to resemble:
var btn = (Button)e.Data.GetData(typeof(Button));
var pos = btn.Parent.PointToClient(Cursor.Position);
btn.Left = (pos.X / 38) * 38;
btn.BringToFront();
Related
I'm making a drag and drop game for my A level computing coursework. My drag and drop works fine, but I have 6 buttons/options and I want to reset the locations on the other 5 buttons when I move on the 1 button. The 6 buttons are named btnAnswer1, btnAnswer2, btnAnswer3, etc.
I already tried to search for a solution, and it still doesn't work
bool isDragged = false;
Point ptOffset;
private void buttonMouseDown(object sender, MouseEventArgs e) {
Button theButton = (Button)sender;
if (e.Button == MouseButtons.Left) {
isDragged = true;
Point ptStartPosition = theButton.PointToScreen(new Point(e.X, e.Y));
ptOffset = new Point();
ptOffset.X = theButton.Location.X - ptStartPosition.X;
ptOffset.Y = theButton.Location.Y - ptStartPosition.Y;
} else {
isDragged = false;
}
}
private void buttonMouseMove(object sender, MouseEventArgs e) {
Button theButton = (Button)sender;
if (isDragged) {
Point newPoint = theButton.PointToScreen(new Point(e.X, e.Y));
newPoint.Offset(ptOffset);
theButton.Location = newPoint;
}
}
private void buttonMouseUp(object sender, MouseEventArgs e) {
Button theButton = (Button)sender;
isDragged = false;
if ((theButton.Location.X >= 190 && theButton.Location.X <= 468) && (theButton.Location.Y >= 42 && theButton.Location.Y <= 236)) {
answerText = theButton.Text;
if (answerText == RandomQuestion[0].CorrectAnswerPosition) {
MessageBox.Show("Correct Answer");
}
else MessageBox.Show("Wrong Answer");
// disableDragDrop();
}
}
I don't know how to reset the locations of the other 5 buttons when I move 1 button.
You can change the button off postion this way
yourButton.Location = new Point(50, 50); //x and y cordinate off position
You should rest your 5 buttons positions in the method where you move 1 button with my method. Hope this helps.
How to move a pictureBox inside a Panel by Mouse.
Visual Studio 2015 C# Winsows Forms Application.
I've made a primitive slider to control the volume of my WindowsMediaPlayer.
A panel as the background and a pictureBox inside as the slider-knopf.
And it works well.
But purely visually it does not work that good.
I'v searched all around, but can't I find an answer to this little funny problem.
Here is my code:
int posY;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
posY = e.Y; ;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
PictureBox box = sender as PictureBox;
if (e.Button == MouseButtons.Left)
{
box.Top += e.Y - posY;
}
if (box.Top < 0)
{
box.Top = 0;
}
if (box.Top > 100)
{
box.Top = 100;
}
int n = box.Top;
n = n * - 1 + 100;
label1.Text = n.ToString();
}
When I move the pictureBox out of the edge of the little panel, the pictureBox somehow 'shrinks' in the panel.
But when I release the mouse, the pictureBox restore its size.
Slider.gif
Why is that.?
And how can I avoid it.?
Thanks.
I found a solution.
It's not optimal, but it can be used.
I changed the code to:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
dragging = true;
startPoint = e.Location;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
Debug.WriteLine("mousemove X: " + e.X + " Y: " + e.Y);
pictureBox1.Location = new Point(0, pictureBox1.Top + e.Location.Y - startPoint.Y);
if (pictureBox1.Location.Y < 0)
{
pictureBox1.Location = new Point(0, 0);
dragging = false;
}
if (pictureBox1.Location.Y > 100)
{
pictureBox1.Location = new Point(0, 100);
dragging = false;
}
this.Refresh();
}
int n = pictureBox1.Location.Y;
n = n * -1 + 100;
label1.Text = n.ToString();
mediaPlayer1.settings.volume = n;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
gif
I still need to put an 'if' to correct, when the pictureBox1 is pulled out of the panel.
And to avoid flicker, I have had to put a 'dragging = false'.
However, it results in the pictureBox1 is getting frozen to the edge, so I have to release the mouse, and re-click to continue.
But well - it's to live with.
Thanks.
I made a scrollable panel like this:
private void button3_Click(object sender, EventArgs e)
{
Form f2 = new Form();
f2.Size = new Size(400, 300);
f2.AutoScroll = false;
Panel pan = new Panel();
pan.Size = new Size(600, 100);
pan.AutoScroll = false;
for (int i = 1; i <= 10; i++)
{
Button b = new Button();
b.Text = "B" + (i);
b.Name = "button_" + (i);
b.Left = (b.Width + 12) * (i - 1);
b.Parent = pan;
pan.Parent = f2;
f2.Show();
}
}
private void panel1_MouseWheel(object sender, MouseEventArgs e)
{
Form2 frm = new Form2();
panel1.Top += e.Delta > 0 ? 10 : -10;
if (panel1.Top > 0)
panel1.Top = 0;
else if (panel1.Top <= panel1.Parent.Height)
panel1.Top = panel1.Parent.Height;
Console.WriteLine("panel2.top:" + panel1.Top);
}
This is the full code of that panel, panel1 = pan...
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
pPt = e.Location;
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
Console.WriteLine("panel2.top:" + panel1.Top);
if (e.Button.HasFlag(MouseButtons.Left))
{
Form2 frm = new Form2();
panel1.Top += e.Y - pPt.Y;
if (panel1.Top > 0)
panel1.Top = 0;
else if (panel1.Top <= panel1.Parent.Height)
panel1.Top = panel1.Parent.Height;
}
}
And you can scroll it by dragging the panel with the mouse but the problem is it looks like this:
And I want to don't go higher than button1 or lower than the last button.
Tweak this method: you need to "pin" the panel so it doesn't move below the top and above the bottom - because mouse wheel deltas are events you will continuously receive. You have to manually decide when to ignore them
private void panel1_MouseWheel(object sender, MouseEventArgs e)
{
Form2 frm = new Form2();
panel1.Top += e.Delta > 0 ? 10 : -10;
// tweak this
if (panel1.Top > 0) panel1.Top = 0;
else if (panel1.Bottom <= panel1.Parent.Height) panel1.Bottom = panel1.Parent.Height;
Console.WriteLine("panel2.top:" + panel1.Top);
}
Also, the above will work when the panel you are scrolling is "Taller" than the viewport (the form itself). You might need to tweak further when the panel is smaller than the form - so just test a few cases.
You also need to pay attention to the Resize event so your panel has the correct Top property when someone expands the container form.
We can Get or set the upper limit of values of the scrollable range with
ScrollBar.Maximum Property
An example is as follows.
The following example assumes that you have created a Form, added a PictureBox to the Form, and added a horizontal HScrollBar and a vertical VScrollBar to the PictureBox. This code example is part of a larger example provided for the ScrollBar class overview.
In this example, the Maximum property is set to the size of the Image plus the size of the scrollbar if it is visible plus an adjustment factor of the size of the LargeChange property.
You must add references to the System.Drawing and System.Windows.Forms namespaces to run this example.
public void SetScrollBarValues()
{
//Set the following scrollbar properties:
//Minimum: Set to 0
//SmallChange and LargeChange: Per UI guidelines, these must be set
// relative to the size of the view that the user sees, not to
// the total size including the unseen part. In this example,
// these must be set relative to the picture box, not to the image.
//Maximum: Calculate in steps:
//Step 1: The maximum to scroll is the size of the unseen part.
//Step 2: Add the size of visible scrollbars if necessary.
//Step 3: Add an adjustment factor of ScrollBar.LargeChange.
//Configure the horizontal scrollbar
//---------------------------------------------
if (this.hScrollBar1.Visible)
{
this.hScrollBar1.Minimum = 0;
this.hScrollBar1.SmallChange = this.pictureBox1.Width / 20;
this.hScrollBar1.LargeChange = this.pictureBox1.Width / 10;
this.hScrollBar1.Maximum = this.pictureBox1.Image.Size.Width - pictureBox1.ClientSize.Width; //step 1
if (this.vScrollBar1.Visible) //step 2
{
this.hScrollBar1.Maximum += this.vScrollBar1.Width;
}
this.hScrollBar1.Maximum += this.hScrollBar1.LargeChange; //step 3
}
//Configure the vertical scrollbar
//---------------------------------------------
if (this.vScrollBar1.Visible)
{
this.vScrollBar1.Minimum = 0;
this.vScrollBar1.SmallChange = this.pictureBox1.Height / 20;
this.vScrollBar1.LargeChange = this.pictureBox1.Height / 10;
this.vScrollBar1.Maximum = this.pictureBox1.Image.Size.Height - pictureBox1.ClientSize.Height; //step 1
if (this.hScrollBar1.Visible) //step 2
{
this.vScrollBar1.Maximum += this.hScrollBar1.Height;
}
this.vScrollBar1.Maximum += this.vScrollBar1.LargeChange; //step 3
}
}
Hope you can change the code accordingly to set the maximum scrollable space.:)
I'm trying to develop my applications to create buttons like so:
private void button1_Click(object sender, EventArgs e)
{
int top = 150;
int left = 150;
for (int i = 0; i < 1; i++)
{
Button button = new Button();
button.Left = left;
button.Top = top;
this.Controls.Add(button);
top += button.Height + 2;
}
}
This is working how I intend, to an extent. I want to be able to create these buttons with certain properties, but I don't know how to access individual buttons.
Now, I also want to be able to move these buttons by holding down the mouse button and dragging them, then releasing them where I want. Here's what I've got from certain online resources and whatnot.
public Form3()
{
InitializeComponent();
button1.MouseDown += button1_MouseDown;
}
private Point MouseDownLocation;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
button1.Left = e.X + button1.Left - MouseDownLocation.X;
button1.Top = e.Y + button1.Top - MouseDownLocation.Y;
}
}
Any help would be appreciated.
If you want to have access to individual buttons you can try to make global list:
List<button> buttons = new List<button>();
And add them in for like:
Button button = new Button();
button.Left = left;
button.Top = top;
this.Controls.Add(button);
top += button.Height + 2;
buttons.add(button);
Next, looking at function button1_MouseMove - it works only if mouse cursor is inside the button? Should it work like this?
If button is clicked you can look at the list to find which button is clicked and move it - your method looks ok.
I have an application in C# and using forms, I am placing a label each time I right click on the form. This label can be moved around, re-sized and modified its color.
So far so good, but I want to make a server that will receive everything I do and send this to other clients so they can see everything I do, and also they can do exactly the same things. I have made eventhandlers, but I have no idea how to send the information through the network, or what information to send to update the form for each client.
internal System.Windows.Forms.ContextMenu mnuForm;
internal System.Windows.Forms.MenuItem mnuNewSquare;
internal System.Windows.Forms.ContextMenu mnuLabel;
internal System.Windows.Forms.MenuItem mnuColorChange;
private void mnuNewSquare_Click(object sender, System.EventArgs e)
{
// Create and configure the "square".
Label newLabel = new Label();
newLabel.Size = new Size(40, 40);
newLabel.BorderStyle = BorderStyle.FixedSingle;
// To determine where to place the label, you need to convert the
// current screen-based mouse coordinates into relative form coordinates.
newLabel.Location = this.PointToClient(Control.MousePosition);
// Attach a context menu to the label.
newLabel.ContextMenu = mnuLabel;
// Connect the label to all its event handlers.
newLabel.MouseDown += new MouseEventHandler(lbl_MouseDown);
newLabel.MouseMove += new MouseEventHandler(lbl_MouseMove);
newLabel.MouseUp += new MouseEventHandler(lbl_MouseUp);
// Add the label to the form.
this.Controls.Add(newLabel);
}
// Keep track of when fake drag or resize mode is enabled.
private bool isDragging = false;
private bool isResizing = false;
// Store the location where the user clicked on the control.
private int clickOffsetX, clickOffsetY;
private void lbl_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
// Retrieve a reference to the active label.
Control currentCtrl;
currentCtrl = (Control)sender;
if (e.Button == MouseButtons.Right)
{
// Show the context menu.
currentCtrl.ContextMenu.Show(currentCtrl, new Point(e.X, e.Y));
}
else if (e.Button == MouseButtons.Left)
{
clickOffsetX = e.X;
clickOffsetY = e.Y;
if ((e.X + 5) > currentCtrl.Width && (e.Y + 5) > currentCtrl.Height)
{
// The mouse pointer is in the bottom right corner,
// so resizing mode is appropriate.
isResizing = true;
}
else
{
// The mouse is somewhere else, so dragging mode is
// appropriate.
isDragging = true;
}
}
}
private void lbl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
// Retrieve a reference to the active label.
Control currentCtrl;
currentCtrl = (Control)sender;
if (isDragging)
{
// Move the control.
currentCtrl.Left += e.X - clickOffsetX;
currentCtrl.Top += e.Y - clickOffsetY;
}
else if (isResizing)
{
// Resize the control.
currentCtrl.Width = e.X;
currentCtrl.Height = e.Y;
}
else
{
// Change the pointer if the mouse is in the bottom corner.
if ((e.X + 5) > currentCtrl.Width && (e.Y + 5) > currentCtrl.Height)
{
currentCtrl.Cursor = Cursors.SizeNWSE;
}
else
{
currentCtrl.Cursor = Cursors.Arrow;
}
}
}
private void lbl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
isDragging = false;
isResizing = false;
}
private void mnuColorChange_Click(object sender, System.EventArgs e)
{
// Show color dialog.
ColorDialog dlgColor = new ColorDialog();
dlgColor.ShowDialog();
// Change label background.
mnuLabel.SourceControl.BackColor = dlgColor.Color;
}
private void DrawingSquares_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.ContextMenu.Show(this, new Point(e.X, e.Y));
}
}
This is the code for form1.cs, and the next code is for form1.designer.cs
private void InitializeComponent()
{
// this.SuspendLayout();
//
// Form1
//
this.mnuForm = new System.Windows.Forms.ContextMenu();
this.mnuNewSquare = new System.Windows.Forms.MenuItem();
this.mnuLabel = new System.Windows.Forms.ContextMenu();
this.mnuColorChange = new System.Windows.Forms.MenuItem();
//
// mnuForm
//
this.mnuForm.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuNewSquare});
//
// mnuNewSquare
//
this.mnuNewSquare.Index = 0;
this.mnuNewSquare.Text = "Create New Square";
this.mnuNewSquare.Click += new System.EventHandler(this.mnuNewSquare_Click);
//
// mnuLabel
//
this.mnuLabel.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuColorChange});
//
// mnuColorChange
//
this.mnuColorChange.Index = 0;
this.mnuColorChange.Text = "Change Color";
this.mnuColorChange.Click += new System.EventHandler(this.mnuColorChange_Click);
//
// DrawingSquares
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(628, 426);
this.ContextMenu = this.mnuForm;
this.Name = "DrawingSquares";
this.Text = "DrawingSquares";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DrawingSquares_MouseDown);
}
This does the client side of the application, in which you can draw a label and modify its properties. I need some help on how to do the server side, any help is much appreciated, thank you in advance.
You might want to look at SignalR:
A client and server side library for .NET that provides messaging and an abstraction over a persistent connection.