c# programmatically add controls adjacently? - c#

When I do this in form load
TextBox tb1 = new TextBox();
TextBox tb2 = new TextBox();
this.Controls.Add(tb1);
this.Controls.Add(tb2);
It puts one textbox over another (not vertically or horizontally, but covering each other), which is not what I want.
I could manually try to position them programmatically, but is there a way where I can have each control appear adjacently when I add them?

You can use a FlowLayoutPanel.
Here a short example code that you can test using Linqpad
Form f = new Form();
FlowLayoutPanel flp = new FlowLayoutPanel();
flp.Dock = DockStyle.Fill;
flp.FlowDirection = FlowDirection.LeftToRight;
f.Controls.Add(flp);
TextBox t1 = new TextBox();
flp.Controls.Add(t1);
TextBox t2 = new TextBox();
flp.Controls.Add(t2);
f.Show();

Related

Change text of a TextBox clicking a Button with Controls created at run-time

I'm trying to change the text of a TextBox when I click a Button: both Controls are dynamically created as run-time.
The Buttons and the TextBoxes are created every time I click on another Button.
The Name Property for each control is specified by the User, using a TextBox.
For example, the user inputs "Test1", then the Button is named btn_Test1, and the TextBox is named txt_Test1.
The Button should open a FolderBrowserDialog and after a selection has been made, the TextBox shows the path selected.
I'm using the following code:
protected void button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
folderBrowserDialog.ShowDialog();
string TextName = button.Name.Replace("btn_", "txt_");
TextBox selectText = new TextBox();
selectText = this.Controls[TextName] as TextBox;
selectText.Text = folderBrowserDialog.SelectedPath;
}
however this part gives me null:
selectText = this.Controls[TextName] as TextBox;
I did check with the debugger when I create the controls, so TextName is setting the correct Name.
The Buttons and TextBoxes are inserted in a TabControls, the Tab Name is set to the value the user inputs, so the main TabControl gets 2 controls.
I'm using a hidden TabControl named "TabFolders" that will be the main reference for creating tab clones
I'm using this code:
private void CreateDynamicPathButtons(string TabName)
{
TabPage MyNewTab = new TabPage(TabName);
TabPage TabCopy1;
tabControlEmpresas.TabPages.Add(MyNewTab);
TabControl tc = new TabControl();
tc.Location = new System.Drawing.Point(6, 6);
tc.Size = TabFolders.Size;
for (int i = 0; i < TabFolders.TabCount; i++) {
TabFolders.SelectTab(i);
TabCopy1 = new TabPage(TabFolders.SelectedTab.Text);
foreach (Control c in TabFolders.SelectedTab.Controls) {
Control cNew = (Control)Activator.CreateInstance(c.GetType());
cNew.Text = c.Text;
cNew.Size = c.Size;
cNew.Location = new System.Drawing.Point(c.Location.X, c.Location.Y);
cNew.Visible = true;
if (cNew is TextBox) {
cNew.Name = "txt_" + MyNewTab.Text + "_" + TabFolders.SelectedTab.Text;
}
if (cNew is Button) {
cNew.Name = "btn_" + MyNewTab.Text + "_" + TabFolders.SelectedTab.Text;
cNew.Click += new EventHandler(button_Click);
}
TabCopy1.Controls.Add(cNew);
}
tc.TabPages.Add(TabCopy1);
}
MyNewTab.Controls.Add(tc);
}
After many attempts I did find a very simple solution.
TextBox selectText = new TextBox();
selectText = button.Parent.Controls[TextName] as TextBox;
The button parent hast all the controls.
Assuming that button is the Button control you're creating at run-time you mentioned, you're creating a TextBox control but you're not adding it to the Form.Controls collection (this.Controls.Add([Control])).
Also, you should assign a Location, using a logic that fits your current Layout, to position the newly created Controls. Otherwise, all new controls will be positioned one on top of the other. In the example, the new Control position is determined using a field (int ControlsAdded) that keeps track of the number of Controls created at run-time and add some basic layout logic.
But, if you want to keep a reference of these new Controls, you should add them to a List<Control> or some other collection that allows to select them if/when required.
int ControlsAdded = 0;
protected void button_Click(object sender, EventArgs e)
{
TextBox selectedText = new TextBox();
selectedText.Size = new Size(300, this.Font.Height);
selectedText.Location = new Point(100, ControlsAdded * selectedText.Height + 30);
ControlsAdded += 1;
this.Controls.Add(selectedText);
selectedText.BringToFront();
using (var fBD = new FolderBrowserDialog()) {
if (fBD.ShowDialog() == DialogResult.OK)
selectedText.Text = fBD.SelectedPath;
}
}
with selectText = this.Controls[TextName] as TextBox;, you are trying to find button with replaced name which is not available in this case, and hence it returns null. This is logical mistake.
also string TextName = button.Name.Replace("btn_", "txt_"); does not replace button name, it just assigns replaced string to TextName.
The proper implementation would be
protected void button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
folderBrowserDialog.ShowDialog();
button.Name = button.Name.Replace("btn_", "txt_");
TextBox selectText = new TextBox();
selectText = this.Controls[button.Name] as TextBox;
selectText.Text = folderBrowserDialog.SelectedPath;
}

Can I remove a label, richtextbox in c#? when a button is clicked?

I have a dynamically created Label, RichTextBox via a button that is constructed via array.
Label dateLabel = new Label();
dateLabel.Text = dateArray[i];
dateLabel.Name = "date" + i;
dateLabel.Location = new Point(154, 5 + (50 * i));
dateLabel.Tag = dateLabel;
dateLabel.Size = new System.Drawing.Size(91, 20);
panel1.Controls.Add(dateLabel);
RichTextBox placeTravelLabel = new RichTextBox();
placeTravelLabel.Text = placeTravelArray[i];
placeTravelLabel.Name = "placeTravel" + i;
placeTravelLabel.Location = new Point(272, 5 + (50 * i));
placeTravelLabel.Tag = placeTravelLabel;
placeTravelLabel.Size = new System.Drawing.Size(148, 45);
placeTravelLabel.ReadOnly = true;
panel1.Controls.Add(placeTravelLabel);
Button clearButton = new Button();
clearButton.Name = "clearButton" + i;
clearButton.Text = "Remove";
clearButton.Location = new Point(1200, 5 + (30 * i));
clearButton.Click += new EventHandler(this.clearButton_Click);
panel1.Controls.Add(clearButton);
Now I want them to be remove something like this.
public void clearButton_Click(object sender, EventArgs e)
{
dateLabel.Remove();
placeTravelLabel.Remove();
}
Is this possible?
Yes, it is. Try
panel1.Controls.Remove(dateLabel);
panel1.Controls.Remove(placeTravelLabel);
You obviously need to hold the references to them when you create them (i.e. declare them as fields in your class) or mark them somehow (e.g. in Tag property) and enumerate panel1.Controls to find them later.
I think it should also be possible to use closure on local instances by defining button's click event as lambda to avoid declaring those controls as fields. I do not recommend this, as typical flow is more readable and straightforward. Having said that:
Label dateLabel = new Label();
//...
panel1.Controls.Add(dateLabel);
RichTextBox placeTravelLabel = new RichTextBox();
//...
panel1.Controls.Add(placeTravelLabel);
Button clearButton = new Button();
//...
clearButton.Click += new EventHandler((s, e) =>
{
panel1.Controls.Remove(dateLabel);
panel1.Controls.Remove(placeTravelLabel);
});
panel1.Controls.Add(clearButton);
This is pseudo code built up with LinqPad but should give you enough to work with.
I assume that you are working WinForms as there is no tag to say if it is Winforms of WPF, but this is the code that you need that would remove the label for you.
var frm = new Form();
var lbl = new Label();
lbl.Name = "myLable"
frm.Controls.Add(lbl)
frm.Controls.Remove(lbl)
if you ignore the first two lines of the declarations, you simply need `FormName.Controls.Remove(LabelName)

Use WPF expander in Winforms with more than one control

My problem is that I want to use WPF expander object to host some winforms control. And the position that I'm going to use this is in my application's setting form. But, what I couldn't find is to add more than one control to it.
After a lot of searching for solution to my problem I just found this simple code that only add one control to the WPF expander object (I require more than one control to be added):
private void Form1_Load(object sender, EventArgs e)
{
System.Windows.Controls.Expander expander = new System.Windows.Controls.Expander();
expander.Header = "Sample";
WPFHost = new ElementHost();
WPFHost.Dock = DockStyle.Fill;
WindowsFormsHost host = new WindowsFormsHost();
host.Child = new DateTimePicker();
expander.Content = host;
WPFHost.Child = expander;
this.Controls.Add(WPFHost);
}
In this code the expander only hosts one control.
How should I customize it to host more than one control ?
Please help
Using a System.Windows.Forms.Panel as a container will help:
private void Form1_Load(object sender, EventArgs e)
{
System.Windows.Controls.Expander expander = new System.Windows.Controls.Expander();
System.Windows.Controls.Grid grid = new System.Windows.Controls.Grid();
expander.Header = "Sample";
ElementHost WPFHost = new ElementHost();
WPFHost.Dock = DockStyle.Fill;
Panel panel1 = new Panel();
DateTimePicker dtPicker1 = new DateTimePicker();
Label label1 = new Label();
// Initialize the Label and TextBox controls.
label1.Location = new System.Drawing.Point(16, 16);
label1.Text = "Select a date:";
label1.Size = new System.Drawing.Size(104, 16);
dtPicker1.Location = new System.Drawing.Point(16, 32);
dtPicker1.Text = "";
dtPicker1.Size = new System.Drawing.Size(152, 20);
// Add the Panel control to the form.
this.Controls.Add(panel1);
// Add the Label and TextBox controls to the Panel.
panel1.Controls.Add(label1);
panel1.Controls.Add(dtPicker1);
WindowsFormsHost host = new WindowsFormsHost();
host.Child = panel1;
expander.Content = host;
WPFHost.Child = expander;
this.Controls.Add(WPFHost);
}

Add Controls to Control.Collection

I´m trying to create new Controls (TextBox, ComboBox and CheckBox) to a Control.ControlCollection, but it doesn´t work. Normally my WinForm would pass its controls to that method, but now I´m trying to write a unit test for it.
Here´s the code:
TestClass target = new TestClass();
Control.ControlCollection controls = null;
CheckBox checkBox = new CheckBox();
checkBox.Name = "SomeCheckBox";
checkBox.Checked = true;
ComboBox comboBox = new ComboBox();
comboBox.Name = "SomeComboBox";
checkBox.Text = "Some text in CB";
TextBox count = new TextBox();
count.Name = "CountTextBox";
count.Text = "20";
TextBox date = new TextBox();
date.Name = "DateNow";
date.Text = System.DateTime.Now.ToString("dd.MM.yyyy");
controls.AddRange(new Control[] {checkBox, comboBox, count, date });
string actual;
actual = target.saveEverything(controls);
Test fails in the AddRange-Row. What mistake did I make?
Ok, I´m stupid. I forgot to initilize controls.
Control con = new Control();
Control.ControlCollection controls = new Control.ControlCollection(con);

add a tab programically, c# tab control

hi everybody
i want to ask :
How to add a tab programmically.
for my problem
i have a tab control, as default only one tab. and i have a button when i click that button will add one other tab. so will be two tab.
please help me using c# and xaml.
tabControl.Items.Add(yourNewTabItem);
Try this way:
tabControl1.TabPages.Add("tab 3");
Some more code to create and modify tabPages manually:
public partial class Form1 : Form
{
TabControl tc;
public Form1()
{
InitializeComponent();
tc = new TabControl();
tc.TabPages.AddRange(new TabPage[]
{
new TabPage("tabPage 1"),
new TabPage("tabPage 2")
});
tc.Location = new Point(20, 20);
tc.Size = new Size(300, 200);
this.ClientSize = new Size(350, 250);
this.Controls.Add(tc);
//renaming:
this.tc.TabPages[0].Text = "1st tab";
this.tc.TabPages[1].Text = "2nd tab";
//changing background:
this.tc.TabPages[0].BackColor = Color.Yellow;
this.tc.TabPages[1].BackColor = Color.YellowGreen;
//adding some controls to each tab:
TextBox tb = new TextBox();
tb.Location = new Point(20, 20);
tb.Size = new Size(130, 20);
tb.Text = "This textBox is on 1st tab";
Label lb = new Label();
lb.Location = new Point(20, 20);
lb.Text = "This label is on 2nd tab";
lb.ForeColor = Color.Red;
this.tc.TabPages[0].Controls.Add(tb);
this.tc.TabPages[1].Controls.Add(lb);
}
}

Categories

Resources