I have some buttons which is created dynamically in my winform , on which the first button should be selected by default and the rest of the buttons should be selected clicking the down and up arrows.
for (int i = 0; (i < 5); i++)
{
Button btn = new Button();
btn.Width *= 2;
btn.Height *= 2;
yPos = yPos + btn.Height + space;
Point p = new Point();
p.X = xPos;
p.Y = yPos;
btn.Location = p;
this.Controls.Add(btn);
}
the buttons is displayed in a row style and clicking on down arrow should select the next immediate button and like that.
Please help me what can i write in the keypress event
Add your Button to a List<Button> BtnList, define a index int current = 0.
When keypress
if(current == BtnList.Length)
{
current = 0;
}
else
{
BtnList[current].Focus();
current += 1;
}
Related
I am writing a program code for creating graphs from graph theory.
Clicking on a grid generates a graph node with the corresponding index. Buttons are generated on the right. I want the nodes to be connected by an edge when the button is clicked. For example, when you click on the button on line 1 and column 2, an edge will be drawn connecting circles 1 and 2.
enter image description here
Button generation code
List<Button> btnList = new List<Button>();
for (int z = 1; z <= count; z++)
{
for (int x = 1; x <= count; x++)
{
Button btn = new Button();
btn.Text = 0.ToString();
btn.Location = new Point(z*30, x*30);
btn.Size = new System.Drawing.Size(30, 30);
btn.BackColor = System.Drawing.Color.White;
btn.MouseClick += new System.Windows.Forms.MouseEventHandler(btnClick);
panel1.Controls.Add(btn);
btnList.Add(btn);
}
}
The code of the event describing the click of the button
public void btnClick(object sender, EventArgs e)
{
Button button = (Button)sender;
button.Text = (int.Parse(button.Text)+1).ToString();
Graphics g = Graphics.FromImage(bmp);
Pen pen = new Pen(Color.Black);
//g.DrawLine(pen, );
pictureBox1.Image = bmp;
}
Maybe the question is very stupid, but I do not understand how to refer to the indexes of the pressed button in the btnClick function.
You have, for every object in C#, a Tag property which is free. You can use it to store the coordinates of your button.
So, insert before you add the btn to the panel1.Controls, something like:
btn.Tag = new Point(z, x);
Then, in the btnClick delegate, to get back your coordinates, you use something like:
Button button = sender as Button;
Point p = button.Tag;
int z = p.X;
int x = p.Y;
You can keep the Button button = (Button)sender; The only difference is that casting can throw an exception but the keyword 'as' can't.
As I am writing this, I see the new comments and your reply. Tag isn't in the delegates like KeyDown but with the properties like Location, Size, Text, etc.
You already store z and x:
btn.Location = new Point(z*30, x*30);
You can do this in the click handler to retrieve them:
int z = button.Location.X / 30;
int x = button.Location.Y / 30;
Thanks for answers.
I add code when generation buttons
btn.Tag = new Point(z, x);
and i use btn.Tag when click on button
Point p = (Point)button.Tag;
int z = p.X;
int x = p.Y;
I'm making a program that will make buttons on the screen from a for loop. This is important because the user needs to have access to the number of buttons, and could change with every run. This is the code i have so far:
public Form1()
{
InitializeComponent();
int top = 5;
int left = 5;
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Height = 50;
button.Left = left;
button.Top = top;
this.Controls.Add(button);
left += button.Width + 2;
}
}
What i want is basically something like this:
Button b+i = new Button();
Its like when combining two strings, i want the name of the button on the first run in the loop to be b0, then b1, then b2, and so on.
I use Visual Studio, and InitializeComponent() goes to the editor generated code to make the window and stuff. nothing but the window is made there.
Thank you for your help!
Worrying about the variable names is the wrong way to approach this problem. There are several alternatives:
Use a list
List<Button> buttons;
public Form1()
{
InitializeComponent();
buttons = new List<Button>();
int top = 5;
int left = 5;
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Height = 50;
button.Left = left;
button.Top = top;
this.Controls.Add(button);
buttons.Add(button);
left += button.Width + 2;
}
}
//now instead of 'b1', it's 'buttons[1]'
Which you could also create with the OfType() method:
var buttons = this.Controls.OfType<Button>().ToList();
These can be done in combination with a FlowLayoutPanel or TableLayoutPanel to simplify the code:
public Form1()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Height = 50;
FlowLayoutPanel1.Controls.Add(button); //panel handles Left/Top location
}
}
The panel also has the advantage of helping your app scale at different dpi's or screen/window sizes.
Any of which could also be adapted to start thinking in terms of connecting to a datasource (and reduce the code):
var buttons = Enumerable.Range(0, 10).Select(b => new Button {
Height = 50,
Left = 5 + ( b * (BUTTONWIDTH + 2) ),
Top = 5,
Name = String.Format("Button{0}", b)
});
//buttons.ToList()
//or
//this.Controls.AddRange(buttons.ToArray())
//or
//FlowLayoutPanel1.Controls.AddRange(buttons.ToArray()) //Remove Left/Top code
But all of this is meaningless until you can get the buttons to actually do something. You need an event handler for (at least) the Click event:
foreach (var b in butons)
{
b.Click += (s,e) =>
{
//click code for all of the buttons goes here
// you can tell the buttons apart by looking at the "s" variable
};
}
since people (rightly) said 'use an array' here is code
public Form1()
{
InitializeComponent();
int top = 5;
int left = 5;
var buttons = new Button[10];
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Height = 50;
button.Left = left;
button.Top = top;
this.Controls.Add(button);
left += button.Width + 2;
buttons[i] = button;
}
}
C#.I have 18 buttons to select, but before I will choose a selection. How to enlarge Button with BackgroundImage when mouse point in it? It's like ToolTip, when you point the cursor it will show the Text. But in my case, it will enlarge the Button. Thanks
Button[] ButtonSelect = new Button[17];
for (i = 1; i <= 18; i++)
{
ButtonSelect[i] = new Button();
ButtonSelect[i].BackgroundImage = Properties.Resources.SelectImages[i];
}
Make the size of the Button grow larger in MouseEnter event:
Button btn = (Button)sender;
int width = btn.Size.Width;
int height = btn.Size.Height;
int larger = 10;
btn.Size = new Size(width + larger, height + larger);
Then in the MouseLeave event do the opposite by shrinking the button size.
You can hook up the events like this:
for (i = 1; i <= 18; i++)
{
ButtonSelect[i] = new Button();
ButtonSelect[i].BackgroundImage = Properties.Resources.SelectImages[i];
ButtonSelect[i].MouseEnter += new System.EventHandler(Btn_MouseEnter);
ButtonSelect[i].MouseLeave += new System.EventHandler(Btn_MouseLeave);
}
Looking through the way for create buttons dynamically on a panel
I tried this.
int top = 50;
int left = 100;
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Left = left;
button.Top = top;
this.Controls.Add(button);
top += button.Height + 2;
}
but I don't know how to put them on panel
Instead of adding buttons to form controls, add them to panel controls (I believe this is your form or user control):
int top = 50;
int left = 100;
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Left = left;
button.Top = top;
panel.Controls.Add(button); // here
top += button.Height + 2;
}
UPDATE: for handling button click events, you should subscribe all buttons for single event handler (when you create button):
button.Click += Button_Click;
And in event handler you can use sender to see which button raised event:
private void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
// you have instance of button
// ...
}
I want to create 10 buttons on my form when I click on button1. No error with this code below but it doesnt work either.
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < buttons.Capacity; i++)
{
this.Controls.Add(buttons[i]);
}
}
You aren't creating any buttons, you just have an empty list.
You can forget the list and just create the buttons in the loop.
private void button1_Click(object sender, EventArgs e)
{
int top = 50;
int left = 100;
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Left = left;
button.Top = top;
this.Controls.Add(button);
top += button.Height + 2;
}
}
It doesn't work because the list is empty. Try this:
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < 10; i++)
{
Button newButton = new Button();
buttons.Add(newButton);
this.Controls.Add(newButton);
}
}
You could do something like this:
Point newLoc = new Point(5,5); // Set whatever you want for initial location
for(int i=0; i < 10; ++i)
{
Button b = new Button();
b.Size = new Size(10, 50);
b.Location = newLoc;
newLoc.Offset(0, b.Height + 5);
Controls.Add(b);
}
If you want them to layout in any sort of reasonable fashion it would be better to add them to one of the layout panels (i.e. FlowLayoutPanel) or to align them yourself.
Two problems- List is empty. You need to add some buttons to the list first. Second problem: You can't add buttons to "this". "This" is not referencing what you think, I think. Change this to reference a Panel for instance.
//Assume you have on your .aspx page:
<asp:Panel ID="Panel_Controls" runat="server"></asp:Panel>
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < buttons.Capacity; i++)
{
Panel_Controls.Controls.Add(buttons[i]);
}
}
use button array like this.it will create 3 dynamic buttons bcoz h variable has value of 3
private void button1_Click(object sender, EventArgs e)
{
int h =3;
Button[] buttonArray = new Button[8];
for (int i = 0; i <= h-1; i++)
{
buttonArray[i] = new Button();
buttonArray[i].Size = new Size(20, 43);
buttonArray[i].Name= ""+i+"";
buttonArray[i].Click += button_Click;//function
buttonArray[i].Location = new Point(40, 20 + (i * 20));
panel1.Controls.Add(buttonArray[i]);
} }
I had the same doubt and came up with the following contribution:
int height = this.Size.Height;
int width = this.Size.Width;
int widthOffset = 10;
int heightOffset = 10;
int btnWidth = 100; // Button Widht
int btnHeight = 40; // Button Height
for (int i = 0; i < 50; ++i)
{
if ((widthOffset + btnWidth) >= width)
{
widthOffset = 10;
heightOffset = heightOffset + btnHeight
var button = new Button();
button.Size = new Size(btnWidth, btnHeight);
button.Name = "" + i + "";
button.Text = "" + i + "";
//button.Click += button_Click; // Button Click Event
button.Location = new Point(widthOffset, heightOffset);
Controls.Add(button);
widthOffset = widthOffset + (btnWidth);
}
else
{
var button = new Button();
button.Size = new Size(btnWidth, btnHeight);
button.Name = "" + i + "";
button.Text = "" + i + "";
//button.Click += button_Click; // Button Click Event
button.Location = new Point(widthOffset, heightOffset);
Controls.Add(button);
widthOffset = widthOffset + (btnWidth);
}
}
Expected Behaviour:
This will generate the buttons dinamically and using the current window size, "break a line" when the button exceeds the right margin of your window.
First, you aren't actually creating 10 buttons. Second, you need to set the location of each button, or they will appear on top of each other. This will do the trick:
for (int i = 0; i < 10; ++i)
{
var button = new Button();
button.Location = new Point(button.Width * i + 4, 0);
Controls.Add(button);
}
You can't add a Button to an empty list without creating a new instance of that Button.
You are missing the
Button newButton = new Button();
in your code plus get rid of the .Capacity