change the Label text in runtime inside a panel - c#

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";
}

Related

C# context menu for flowlayout panel

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);
}
}

Expanding Wrap Panels ony in Width and other shenanigans

I want to expand a Wrap Panel only in width also the Wrap Panel shall not draw over another Stack Panel that already exists. The Problem is probably with the standard configuration of Buttons which i added to the wrap panel also my lack of knowledge about auto sizing, so content or guides to this topic would be appreciated. The Button i add to wrap panel shall add text boxes to it, but how i said just in the width.
Edit.: is there a way to add a visual studio projekt to a post/comment?
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
stackPanel1.Width = Double.NaN;
stackPanel1.Height = Double.NaN;
stackPanel2.Width = Double.NaN;
stackPanel2.Height = Double.NaN;
AddWrapPanelMaster();
}
Button AddButtonSlave(Button but)
{
but.Click += new RoutedEventHandler(this.buttClickSlave);
return (but);
}
Button AddButtonMaster(Button but)
{
but.Click += new RoutedEventHandler(this.buttClickMaster);
return (but);
}
void buttClickMaster(Object sender, EventArgs e)
{
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
Button s = (Button)sender;
WrapPanel wp = (WrapPanel)s.Parent;
wp.Children.Add(txtB1);
}
void buttClickSlave(Object sender, EventArgs e)
{
Button s = (Button)sender;
if (s.Background != Brushes.Blue && s.Background != Brushes.Red && s.Background != Brushes.Green)
s.Background = Brushes.Red;
else
if (s.Background == Brushes.Green)
s.Background = Brushes.Red;
else
if (s.Background == Brushes.Blue)
s.Background = Brushes.Green;
else
if (s.Background == Brushes.Red)
s.Background = Brushes.Blue;
}
void AddTextBox(Button sender) {
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
WrapPanel s = (WrapPanel)sender.Parent;
s.Children.Add(txtB1);
// Add the buttons to the parent WrapPanel using the Children.Add method.
}
void AddWrapPanelSlave() {
WrapPanel myWrapPanel = new WrapPanel();
myWrapPanel.Background = System.Windows.Media.Brushes.Azure;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 200;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
// Define 3 button elements. The last three buttons are sized at width
// of 75, so the forth button wraps to the next line.
Button btn1 = new Button();
btn1 = AddButtonSlave(btn1);
btn1.Content = "Button 1";
btn1.Width = 75;
Button btn2 = new Button();
btn2.Content = "Button 2";
btn2.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1);
myWrapPanel.Children.Add(btn2);
this.stackPanel1.Children.Add(myWrapPanel);
}
void AddWrapPanelMaster()
{
WrapPanel myWrapPanel = new WrapPanel();
myWrapPanel.Background = System.Windows.Media.Brushes.Azure;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 200;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
// Define 3 button elements. The last three buttons are sized at width
// of 75, so the forth button wraps to the next line.
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
Button btn1 = new Button();
btn1 = AddButtonMaster(btn1);
btn1.Content = "Add";
btn1.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(txtB1);
myWrapPanel.Children.Add(btn1);
this.stackPanel2.Children.Add(myWrapPanel);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
AddWrapPanelSlave();
this.Show();
}
}
}

Add label under button in a flowLayoutPanel

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);
}

Dynamic button, textbox and picturebox creation

Here I am doing a project where questions are presented in images. When the project loads, "start exam" button will be present in the screen. After pressing the button, it should create a picturebox, a textbox and a button for each image from specified path. Then users has to enter the answer in a textbox which is created dynamically. After the dynamic submit button is clicked for every image, the textbox values have to be stored in the listbox. I don't know how get the values from textbox. Can anyone help me out from this?
Here is my code:
PictureBox[] pics = new PictureBox[100];
TextBox[] txts = new TextBox[100];
Button[] butns = new Button[100];
FlowLayoutPanel[] flws = new FlowLayoutPanel[100];
private void button1_Click( Object sender , EventArgs e)
{
for (int i = 0; i < listBox1.Items.Count; i++)
{
flws[i] = new FlowLayoutPanel();
flws[i].Name = "flw" + i;
flws[i].Location = new Point(3,brh);
flws[i].Size = new Size(317,122);
flws[i].BackColor = Color.DarkCyan;
flws[i].BorderStyle = BorderStyle.Fixed3D;
pics[i] = new PictureBox();
pics[i].Location = new Point(953, 95 + brh);
pics[i].Name = "pic" + i;
pics[i].Size = new Size(300, 75);
pics[i].ImageLocation = "C:/" + listBox1.Items[i];
flws[i].Controls.Add(pics[i]);
txts[i] = new TextBox();
txts[i].Name = "txt" + i;
txts[i].Location = new Point(953, 186 + brh);
flws[i].Controls.Add(txts[i]);
butns[i] = new Button();
butns[i].Click += new EventHandler(butns_Click);
butns[i].Text = "submit";
butns[i].Name = "but" + i;
butns[i].Location = new Point(1100, 186 + brh);
flws[i].Controls.Add(butns[i]);
flowLayoutPanel1.Controls.Add(flws[i]);
brh += 130;
}
}
private void butns_Click(object sender, EventArgs e)
{
Button butns = sender as Button;
TextBox txts = sender as TextBox;
listBox2.Items.Add("text values " + txts.Text.ToString());
}
I would create a usercontrol to combine the controls.
Search for "custom usercontrol c#"
Regards.
Try this...
private void butns_Click(object sender, EventArgs e)
{
Button butns = sender as Button;
string btnName = butns.Name;
string Id = btnName.Substring(3);
string txtName = "txt" + Id;
listBox2.Items.Add("text values " + GetValue(txtName));
}
private string GetValue(string name)
{
TextBox txt = new TextBox();
txt.Name = name;
foreach (Control ctl in this.Controls)
{
if (ctl is FlowLayoutPanel)
{
foreach (Control i in ctl.Controls)
{
if (((TextBox)i).Name == txt.Name)
{
txt = (TextBox)i;
return txt.Text;
}
}
}
}
return txt.Text;
}

How to add controls in split container using for loop in windows form

I am developing a windows application containing 3 split containers(two panels each,
total 6 panels).
Now I want to add 3 labels dynamically in each panel.One solution I am trying to use for loop and access all splitcontainers and their panels but I dont know how to use for loop for accessing splitcontainer.
Can I use for loop for this? Also I want to add controls to all panels(6) at the same time. How to do this.
Thanks in advance..!!
This is what I have done...
foreach (SplitContainer sp in this.Controls)
{
Label tileTitle = new Label();
tileTitle.Text = "OneClick";
tileTitle.Visible = true;
tileTitle.Location = new Point(10, 10);
sp.Panel1.Controls.Add(tileTitle);
}
foreach (Control c in this.Controls)
{
if (c is SplitContainer)
{
Label tileTitle = new Label();
tileTitle.Text = "OneClick";
tileTitle.Visible = true;
tileTitle.Location = new Point(10, 10);
Label tileTitle2 = new Label();
tileTitle2.Text = "OneClick";
tileTitle2.Visible = true;
tileTitle2.Location = new Point(10, 10);
((SplitContainer)c).Panel1.Controls.Add(tileTitle);
((SplitContainer)c).Panel2.Controls.Add((tileTitle2));
}
}
Try to use the Controls.OfType extension to get only the controls of SplitContainer type
foreach (SplitContainer sp in this.Controls.OfType<SplitContainer>())
{
Label title = MakeLabel("OneClick", new Point(10, 10);
sp.Panel1.Controls.Add(title);
Label title1 = MakeLabel("OneClick", new Point(10, 10);
sp.Panel2.Controls.Add(title1);
}
private Label MakeLabel(string caption, Point position)
{
Label lbl = new Label();
lbl.Text = caption;
lbl.Location = position;
lbl.Visible = true;
return lbl;
}
edit
Steve, you add the same label to panel1 and panel2. i fixed the variable name in the add method of panel2.
i have done this in the same way as Steve did it, but i'm using a TableLayoutPanel to store all the splitcontainers, because you can add more than one SplitContainer with Dockstyle.Fill at the same time.
private void Form1_Load(object sender, EventArgs e)
{
foreach (SplitContainer sc in this.tableLayoutPanel1.Controls.OfType<SplitContainer>())
{
Label title = MakeLabel("OneClick", new Point(10, 10));
sc.Panel1.Controls.Add(title);
Label title1 = MakeLabel("TwoClick", new Point(10, 10));
sc.Panel2.Controls.Add(title1);
}
}
private Label MakeLabel(string caption, Point position)
{
Label lbl = new Label();
lbl.Text = caption;
lbl.Location = position;
lbl.Visible = true;
return lbl;
}
the solution works perfectly as seen here: http://imageshack.us/photo/my-images/838/splitcontainer.png/

Categories