I am new to WPF and I am struggling with following thing:
I am creating dynamically buttons and adding them to grid, then I want to give them contextmenu which i am doing, but here is the thing contextmenu consists of integers and now when I click integer from contextmenu, I would like to update buttons content with number chosen from this contextmenu how do I achieve it?
Help and explainations will be greatly appreciated.
Here is my code:
List<int> a = new List<int>();
for (int i = 0; i < boardSize; i++)
a.Add(i + 1);
ContextMenu menu = new ContextMenu();
menu.ItemsSource = a;
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
btn = new Button() {ContextMenu=menu };
btn.Width = 25;
btn.Height = 25;
btn.VerticalAlignment = VerticalAlignment.Center;
btn.SetValue(Grid.ColumnProperty, j);
btn.SetValue(Grid.RowProperty, i);
btn.HorizontalAlignment = HorizontalAlignment.Stretch;
btn.Background = new SolidColorBrush(Colors.Blue);
MyGrid.Children.Add(btn);
}
}
You need do 4 steps to archieve it :
Add a member variable to record which button you right click to show
contextmenu:
private Button currentBtn;
Add event to record the current right click button:
btn.MouseRightButtonUp += (cbtn, e2) => { currentBtn = cbtn as Button; };
Define menuitem:
List<MenuItem> a = new List<MenuItem>();
for (int i = 0; i < boardSize; i++)
{
var item = new MenuItem();
item.Header = (i + 1).ToString();
item.Click += item_Click;
a.Add(item);
}
Add click event to menuitem:
void item_Click(object sender, RoutedEventArgs e)
{
if (currentBtn != null)
{
var i = sender as MenuItem;
Dispatcher.Invoke(() => { currentBtn.Content = i.Header; });
}
}
Related
Say if I want to create a multiple button on my form based on a loop value of 3 then 3 buttons should be created into that form, in my case I have this textbox input that should determine the loop value on button click. What I've tried:
void Button4Click(object sender, EventArgs e)
{
int get_col_range = Convert.ToInt32(textBox3.Text);
for(int i=0; i<get_col_range; i++) {
Button btn = new Button();
btn.Text = Convert.ToString(i);
this.Controls.Add(btn);
}
}
I put on value of 2 on the TextBox input as test value but turned out that nothing happened why?.
Try the following on a form with no controls in a button click event.
int top = 10;
int heightPadding = 30;
for (int index = 0; index < 3; index++)
{
var button = new Button()
{
Text = $"Button {index}",
Name = $"Button{index}",
Location = new Point(10, top)
};
Controls.Add(button);
top += heightPadding;
}
Hey I would like to create a stack panel with multiple buttons in it and when I press one, it tells me which button it is. Like when I press the second button from the top, I get the number 2 back and so on.
The buttons are created with this loop:
for (int i = 0; i < LBresponse.Items.Count; i++)
{
System.Windows.Controls.Button BTclear = new Button();
BTclear.Content = "Clear";
BTclear.Width = 50;
BTclear.Height = 20;
BTclear.HorizontalAlignment = HorizontalAlignment.Right;
BTclear.Click += Button_Click;
BTclear.IsEnabled = true;
STPresponse.Children.Add(BTclear);
}
I could do it with the location of the button but I hope there is a better solution.
One Idea would be to put the number into the context when the button is created but this would not be pretty.
You could store the number or index somewhere, for example in the Tag property:
for (int i = 0; i<LBresponse.Items.Count; i++)
{
System.Windows.Controls.Button BTclear = new Button();
BTclear.Tag = i;
BTclear.Content = "Clear";
BTclear.Width = 50;
BTclear.Height = 20;
BTclear.HorizontalAlignment = HorizontalAlignment.Right;
BTclear.Click += (ss, ee) =>
{
MessageBox.Show(((Button)ss).Tag.ToString());
};
BTclear.IsEnabled = true;
STPresponse.Children.Add(BTclear);
}
I have the code that creates a grid of buttons from an array. I need to get their possitions in array on mouse clicked event. Any ideas or links to some other post/articles would be very helpful.
The code for creating the grid:
// Creating buttons array for 5x5 grid
Button[] tiles25 = new Button[25];
// Generating 5x5 button grid
void Spawn5x5Grid()
{
// position of the firts tile
int x = 35, y = 55;
// current tile index
int count = 0;
for (int i = 1; i < 6; i++)
{
for (int j = 1; j < 6; j++)
{
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y)
};
// Adding buttons from array to the form
Controls.Add(tiles25[count]);
count++;
x = x + 24;
}
x = 35;
y = y + 24;
}
lblSize.Text = "5 x 5";
currentGrid = Grids.grid5x5;
}
I suggest scanning tiles25 array in the Click event handler
...
Controls.Add(tiles25[count]);
tiles25[count].Click += (o, ee) => {
Button button = o as Button;
int index = Array.IndexOf(tiles25, button);
//TODO: Put relevant code here: "button" clicked which is at "index" position
};
count++;
x = x + 24;
...
Register an event handler for each of your button click events and then extract the Location property from the sender object:
// Generating 5x5 button grid
void Spawn5x5Grid()
{
// position of the firts tile
int x = 35, y = 55;
// current tile index
int count = 0;
for (int i = 1; i < 6; i++)
{
for (int j = 1; j < 6; j++)
{
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y)
};
// Adding buttons from array to the form
Controls.Add(tiles25[count]);
tiles25[count].Click += Tiles25_Click;
count++;
x = x + 24;
}
x = 35;
y = y + 24;
}
lblSize.Text = "5 x 5";
currentGrid = Grids.grid5x5;
}
private void Tiles25_Click(object sender, EventArgs e)
{
var bt = sender as Button;
MessageBox.Show("X = " + bt.Location.X + "; Y = " + bt.Location.Y);
}
You need to set up an event handler for when the button is clicked. Right now, all you're doing is creating the buttons and adding them to the list of controls at a given position. Now, all you have to add is the event handler for the click event!
//...
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y),
};
tiles25[count] += new EventHandler(this.Tile_Click);
//...
void Tile_Click(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
//...
}
Then inside of the Tile_Click() event handler, you can use whatever code necessary to get the position with the clickedButton object.
If I'm not wrong VoidWalker, you are trying to get the position(index) of the item in the source array and not the actual position of the button on screen. If the former case is true read on, for the latter we have some good answers above.
What you need to do is to mark each button with an identifier that would be used to infer the position. A simple yet damn efficient approach.
At the time of creating the button:
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y)
};
// Add the current index to the name field of the Button
tiles25[count].Name = "Grid5-Btn" + count.ToString();
// Adding buttons from array to the form
Controls.Add(tiles25[count]);
Then on button click you can simply do
void Tile_Click(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
var index = int(clickedButton.Name.Split("Grid5-Btn")[0]);
//...
}
This way you can add multiple pieces of informatio such as the hierarchy of grids on the page. You can exactly pinpoint which element to access without running any loops, which would be the case with Array.IndexOf
i have an array label name title[i], and link[i].
Label[] title = new Label[100];
Label[] link = new Label[100];
for (int i = 0; i < 10; i++)
{
title[i] = new Label();
link[i] = new Label();
}
when i click the label title, i can get the link label information too.
title[i].MouseClick += new EventHandler(hover_title);
i try this code doesnt work.
public void hover_title(object sender, EventArgs e)
{
title[i].text=link[i].text;
}
how i can get the label link text when i click the title label.
Something like following should solve your problem.
public void hover_title(object sender, EventArgs e)
{
var label = sender as Label;
int i = (title as IList).IndexOf(label);
label.Text = link[i].Text;
}
And remember, after you create a control you must give it a new location, in case of Label set a text, a new size (in case of Label you can set AutoSize property to true), and add it to parent control's Controls collection.
You can do this:
Label[] title = new Label[100];
Label[] link = new Label[100];
for (int i = 0; i < 10; i++)
{
var j = i;
title[j] = new Label();
link[j] = new Label();
title[j].MouseClick += (s, e) => title[j].Text = link[j].Text;
}
Hello I try to add multiple Buttons on a panel on form and next to each other but instead it put them above each other.
I am using the following function.
the Code:
private void CreatBtn()
{
Point[] p = new Point[6];
string log = "";
Form2 frm2 = new Form2();
Button[] btn = new Button[6];
for (int i = 0; i < btn.GetLength(0); i++)
{
btn[i] = new Button();
btn[i].Height = 65;
btn[i].Width = 80;
p[i] = new Point();
p[i].X = i * 83;
p[i].Y =0;
log +=p.ToString() +"\n";
btn[i].PointToClient(p[i]);
btn[i].Show();
}
panel1.Controls.AddRange(btn);
}
Add a Left value to your buttons
btn[i] = new Button();
btn[i].Height = 65;
btn[i].Width = 80;
btn[i].Left = i * 83; //Now they'll be next to each other.
You may also consider using the FlowLayoutPanel.
Use flowLayoutPanel in the panel of it'll but the next to each other until the button reach the end of it, then it will make an new raw
Point[] p = new Point[6];
string log = "";
Button[] btn = new Button[6];
for (int i = 0; i < btn.GetLength(0); i++)
{
btn[i] = new Button();
btn[i].Height = 65;
btn[i].Width = 80;
p[i] = new Point();
p[i].X = i * 83;
p[i].Y = 0;
log += p.ToString() + "\n";
btn[i].PointToClient(p[i]);
btn[i].Show();
}
FlowLayoutPanel pan = new FlowLayoutPanel();
pan.Width=500;//width of all buttons
pan.Height = 100;
pan.Controls.AddRange(btn);
panel1.Controls.Add(pan);