I use flowlayout panel for dynamically create labels. So I want to use righ click menu for this dynamic created labels but contextmenustrip just recognize flowlayoutpanel. For example I right click and get label.text but couldnt. Is there any way for right click menu for dynamic objects?
Label addlabel(int i)
{
Label L = new Label();
L.Name = "LBL" + i.ToString();
L.Text = "LBL" + i.ToString();
L.ForeColor = Color.Black;
L.BackColor = Color.Gray;
L.Width = 94;
L.Height = 21;
L.TextAlign = ContentAlignment.MiddleCenter;
L.Margin = new Padding(5);
return L;
}
for (int i = 0; i < 10; i++)
{
Label L = addlabel(i);
flowLayoutPanel1.Controls.Add(L);
}
Sure...just set the ContextMenuStrip property of the Labels as you create them:
L.ContextMenuStrip = contextMenuStrip1;
If you want to get the Label that was the "source" of the menu, then use code like this:
private void editToolStripMenuItem_Click(object sender, EventArgs e)
{
if (contextMenuStrip1.SourceControl is Label)
{
Label lbl = (Label)contextMenuStrip1.SourceControl;
MessageBox.Show(lbl.Text);
}
}
Related
I wanna change the Text properties of Label using Buttons just like in hangman; but after I created the Label, I became confused when I try to access the specific Label
// creating label
for (int i = 0; i < numericUpDown1.Value; i++)
{
Label l = new Label();
l.Text = "_";
l.Width = 20;
l.Height = 25;
l.Left = i * 20 + 510;
l.Top = 20;
l.BackColor = Color.Transparent;
groupBox2.Controls.Add(l);
}
// function to change the label text
// if I clicked the button
// the first label text will be changed to the text in the button i clicked
private void B_Click(object sender, EventArgs e)
{
var thsBtn = (Button)sender;
bool benar = false;
if (benar == false)
{
thsBtn.Text = " ";
thsBtn.Enabled = false;
}
else
{
thsBtn.Enabled = false;
}
}
You can organize created Labels into a collection, say, List<Label>:
private List<Label> m_CreatedLabels = new List<Label>();
...
// Remove all previous labels
foreach (Label lbl in m_CreatedLabels)
lbl.Dispose();
m_CreatedLabels.Clear();
// Create new ones
for (int i = 0; i < numericUpDown1.Value; i++) {
m_CreatedLabels.Add(new Label() {
Text = "_",
Width = 20,
Height = 25,
Left = i * 20 + 510,
Top = 20,
BackColor = Color.Transparent,
Parent = groupBox2
});
}
Now you have m_CreatedLabels collection to work with created Labels, e.g.
private void B_Click(object sender, EventArgs e) {
var thsBtn = sender as Button;
// you may want to add a condition into FirstOrDefault(), e.g.
// .FirstOrDefault(lbl => lbl.Text == "_")
// - first label with "_" Text
Label lblToProcess = m_CreatedLabels
.FirstOrDefault();
if (null != lblToProcess)
lblToProcess.Text = thsBtn.Text;
thsBtn.Enabled = false;
}
One option here is to give your dynamically created Label instances a Name. From there, you should be able to use ControlCollection.Find to find your Label instances by name.
private void CreateLabels()
{
for (int i = 0; i < numericUpDown1.Value; i++)
{
Label l = new Label();
l.Name = $"DynamicLabel{i}";
l.Text = "_";
l.Width = 20;
l.Height = 25;
l.Left = i * 20 + 510;
l.Top = 20;
l.BackColor = Color.Transparent;
groupBox2.Controls.Add(l);
}
}
private void DoSomethingWithADynamicLabel(int dynamicLabelIndex)
{
Label l = groupBox2.Controls.Find($"DynamicLabel{i}", true).FirstOrDefault() as Label;
if (l is null)
{
// Couldn't find the label...
return;
}
// Do something with l
}
When creating the Label instances inside CreateLabels, I'm simply appending the for loop's counter to the string "DynamicLabel". This gives you a bunch of Labels with names like "DynamicLabel0", "DynamicLable1", "DynamicLabel2", etc...
Then in DoSomethingWithADynamicLabel, assuming you have the index of the Label you want to deal with, you can use groupBox2.Controls.Find to actually find the Label you're interested in. ControlCollection.Find returns Control[], so calling FirstOrDefault will take the first item from the array or null if no Control with the given name exists.
I have a problem, because in my code I am dynamically creating new buttons, and after that, the window looks in that way:
This is code that I used for that:
private void DrawButtons()
{
for (int i = 0; i < 90; i++)
{
Button button = new Button();
button.Location = new Point(15 + 40 * i, 10);
button.Size = new Size(35, 30);
button.Parent = panel4;
button.Tag = i;
Controls.Add(button);
button.BringToFront();
}
}
I want to have scrollable panel, like there, where I created buttons manually:
What I must do to have this effect with programically created elements?
You can use the AutoScroll property. For Panel:
panel4.AutoScroll = true;
But you should also set this property:
button.Anchor = AnchorStyles.Left;
And also add the button to your Panel:
panel4.Controls.Add(button);
So this should be what you want:
private void DrawButtons()
{
for (int i = 0; i < 90; i++)
{
...
button.Anchor = AnchorStyles.Left;
...
panel4.Controls.Add(button);//Add this also
...
}
panel4.AutoScroll = true;
}
The result:
I am creating List of Panel. Each panel Contain a Label and Button . I have also a Button(button1). I want to change the label text of (panels[0]) when click button1. How can I do this.This is my c# code:
List<Panel> panels = new List<Panel>();
private void Panel()
{
var x = 0;
for (int i = 1; i < 5; i++)
{
x += 60;
var panel1 = new Panel() { Size = new Size(60, 140), Location = new Point(x, 100), BorderStyle = BorderStyle.FixedSingle };
panel1.Name = "pan" + i;
Label lbl = new Label();
lbl.Name = "lbl" + i;
lbl.Text = i.ToString();
lbl.Location = new Point(10, 20);
panel1.Controls.Add(lbl);
Button button = new Button();
button.Location = new Point(10, 90);
button.Size = new Size(40, 40);
button.Text = "Click";
panel1.Controls.Add(button);
panels.Add(panel1);
Controls.Add(panel1);
}
}
private void button1_Click(object sender, EventArgs e)
{
foreach (var p in panels)
{
}
}
Output:
But i want, When i Click button1 it will change Label text of zero index panels(I have pointed it using red mark).
Can anyone help me...
Ok, so you've got a button and a label within a panel. When you click a button of a panel, you wanna do something to the label in the same panel, right ?
So
private void BtnClick(object sender, EventArgs e) {
var button = (Button)sender;//you've got the button clicked
var panel = button.Parent;//you've got the panel.
//var label = panel.Controls.OfType<Label>().FirstOrDefault();//but don't think you get this in c# 3.0
var label = GetFirstLabel(panel);
if (label != null)
label.Text = "something";
}
private Label GetFirstLabel(Control parent) {
foreach (var control in parent.Controls) {
if (control is Label) return control as Label;
}
return null;
}
Usage
When you add your buttons, you can now do
Button button = new Button();
button.Location = new Point(10, 90);
button.Size = new Size(40, 40);
button.Text = "Click";
button.Click += BtnClick;
And this will work on all panels.
If you don't store reference to that Label then you can find it in controls of the first Panel by type for example:
panels[0].Controls.OfType<Label>().First().Text = "New Text";
or by name
panels[0].Controls.OfType<Label>().Single(l => l.Name == "lbl1").Text = "New Text";
you can do this with a simple method:
private void button1_Click(object sender, EventArgs e)
{
Label l = panels[0].Controls.Find("lbl1", false).FirstOrDefault() as Label;
l.Text = "TEXT";
}
I need to dynamically create buttons with labels under them in a flowLayoutPanel when i drop a file onto the form. But how do I set the label position to be under the button since the FLP is arranging the controls by itself.. ?
What I've tried:
void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
foreach (string s in fileList)
{
Button button = new Button();
button.Click += new EventHandler(this.button_Click);
fl_panel.Controls.Add(button);
Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(filename);
Bitmap bmp = icon.ToBitmap();
button.BackgroundImage = bmp;
button.Width = 60;
button.Height = 75;
button.FlatStyle = FlatStyle.Flat;
button.BackgroundImageLayout = ImageLayout.Stretch;
int space = 5;
int Yy = button.Location.Y;
int Xx = button.Location.X;
Label label = new Label();
label.Location = new Point(Yy + space, Xx);
//label.Margin.Top = button.Margin.Bottom;
fl_panel.Controls.Add(label);
}
}
The best idea I know of is to implement a custom control that contains both a button and a label that are arranged correctly. Then add the custom control to the FlowLayoutPanel.
public class CustomControl:Control
{
private Button _button;
private Label _label;
public CustomControl(Button button, Label label)
{
_button = button;
_label = label;
Height = button.Height + label.Height;
Width = Math.Max(button.Width, label.Width);
Controls.Add(_button);
_button.Location = new Point(0,0);
Controls.Add(_label);
_label.Location = new Point(0, button.Height);
}
}
You can then add to it like this:
for (int i = 0; i < 10; i++)
{
CustomControl c = new CustomControl(new Button {Text = "Button!"}, new Label {Text = "Label!"});
fl_panel.Controls.Add(c);
}
EDIT:
If you want to listen to button events, try this:
for (int i = 0; i < 10; i++)
{
var button = new Button {Text = "Button " + i};
CustomControl c = new CustomControl(button, new Label {Text = "Label!"});
button.Click += buttonClicked;
fl_panel.Controls.Add(c);
}
...
private void buttonClicked(object sender, EventArgs e)
{
MessageBox.Show(((Button) sender).Text);
}
Is there any way to dynamically create and display 'n' Labels with 'n' corresponding Textboxs when we know value of 'n' after for example, clicking "Display" button.
Let me know if anything make you don't understand my question. Thank you!
I am working with VS C# Express 2010 Windows Form.
I would create a user control which holds a Label and a Text Box in it and simply create instances of that user control 'n' times. If you want to know a better way to do it and use properties to get access to the values of Label and Text Box from the user control, please let me know.
Simple way to do it would be:
int n = 4; // Or whatever value - n has to be global so that the event handler can access it
private void btnDisplay_Click(object sender, EventArgs e)
{
TextBox[] textBoxes = new TextBox[n];
Label[] labels = new Label[n];
for (int i = 0; i < n; i++)
{
textBoxes[i] = new TextBox();
// Here you can modify the value of the textbox which is at textBoxes[i]
labels[i] = new Label();
// Here you can modify the value of the label which is at labels[i]
}
// This adds the controls to the form (you will need to specify thier co-ordinates etc. first)
for (int i = 0; i < n; i++)
{
this.Controls.Add(textBoxes[i]);
this.Controls.Add(labels[i]);
}
}
The code above assumes that you have a button btnDisplay and it has a onClick event assigned to btnDisplay_Click event handler. You also need to know the value of n and need a way of figuring out where to place all controls. Controls should have a width and height specified as well.
To do it using a User Control simply do this.
Okay, first of all go and create a new user control and put a text box and label in it.
Lets say they are called txtSomeTextBox and lblSomeLabel. In the code behind add this code:
public string GetTextBoxValue()
{
return this.txtSomeTextBox.Text;
}
public string GetLabelValue()
{
return this.lblSomeLabel.Text;
}
public void SetTextBoxValue(string newText)
{
this.txtSomeTextBox.Text = newText;
}
public void SetLabelValue(string newText)
{
this.lblSomeLabel.Text = newText;
}
Now the code to generate the user control will look like this (MyUserControl is the name you have give to your user control):
private void btnDisplay_Click(object sender, EventArgs e)
{
MyUserControl[] controls = new MyUserControl[n];
for (int i = 0; i < n; i++)
{
controls[i] = new MyUserControl();
controls[i].setTextBoxValue("some value to display in text");
controls[i].setLabelValue("some value to display in label");
// Now if you write controls[i].getTextBoxValue() it will return "some value to display in text" and controls[i].getLabelValue() will return "some value to display in label". These value will also be displayed in the user control.
}
// This adds the controls to the form (you will need to specify thier co-ordinates etc. first)
for (int i = 0; i < n; i++)
{
this.Controls.Add(controls[i]);
}
}
Of course you can create more methods in the usercontrol to access properties and set them. Or simply if you have to access a lot, just put in these two variables and you can access the textbox and label directly:
public TextBox myTextBox;
public Label myLabel;
In the constructor of the user control do this:
myTextBox = this.txtSomeTextBox;
myLabel = this.lblSomeLabel;
Then in your program if you want to modify the text value of either just do this.
control[i].myTextBox.Text = "some random text"; // Same applies to myLabel
Hope it helped :)
Here is a simple example that should let you keep going add somethink that would act as a placeholder to your winform can be TableLayoutPanel
and then just add controls to it
for ( int i = 0; i < COUNT; i++ ) {
Label lblTitle = new Label();
lblTitle.Text = i+"Your Text";
youlayOut.Controls.Add( lblTitle, 0, i );
TextBox txtValue = new TextBox();
youlayOut.Controls.Add( txtValue, 2, i );
}
Suppose you have a button that when pressed sets n to 5, you could then generate labels and textboxes on your form like so.
var n = 5;
for (int i = 0; i < n; i++)
{
//Create label
Label label = new Label();
label.Text = String.Format("Label {0}", i);
//Position label on screen
label.Left = 10;
label.Top = (i + 1) * 20;
//Create textbox
TextBox textBox = new TextBox();
//Position textbox on screen
textBox.Left = 120;
textBox.Top = (i + 1) * 20;
//Add controls to form
this.Controls.Add(label);
this.Controls.Add(textBox);
}
This will not only add them to the form but position them decently as well.
You can try this:
int cleft = 1;
intaleft = 1;
private void button2_Click(object sender, EventArgs e)
{
TextBox txt = new TextBox();
this.Controls.Add(txt);
txt.Top = cleft * 40;
txt.Size = new Size(200, 16);
txt.Left = 150;
cleft = cleft + 1;
Label lbl = new Label();
this.Controls.Add(lbl);
lbl.Top = aleft * 40;
lbl.Size = new Size(100, 16);
lbl.ForeColor = Color.Blue;
lbl.Text = "BoxNo/CardNo";
lbl.Left = 70;
aleft = aleft + 1;
return;
}
private void btd_Click(object sender, EventArgs e)
{
//Here you Delete Text Box One By One(int ix for Text Box)
for (int ix = this.Controls.Count - 2; ix >= 0; ix--)
//Here you Delete Lable One By One(int ix for Lable)
for (int x = this.Controls.Count - 2; x >= 0; x--)
{
if (this.Controls[ix] is TextBox)
this.Controls[ix].Dispose();
if (this.Controls[x] is Label)
this.Controls[x].Dispose();
return;
}
}