I have a form which contains a dynamically added TableLayoutPanel, which contains some dynamically added Labels, TextBox, CheckBox. I am obtaining exactly the visualization I would like to have, but I am struggling to get the "tab key" to work for moving from one control to the other.
I have tried to add a:
control.TabIndex = tabIndex++;
control.TabStop = true;
But this doesn't seem to have any impact...
This is the (tested) stub code:
class MyForm : Form
{
public MyForm()
{
InitializeComponent();
string[] titles = {"first","second"};
var myLayout = new TableLayoutPanel();
myLayout.AutoSize = true;
int myTabIndex = 1; //Not really necessary
int rowNumber = 0;
foreach (var title in titles)
{
var label = new Label();
label.Text = title;
myLayout.Controls.Add(label, 0, rowNumber);
var control = new TextBox();
control.TabIndex = myTabIndex++; //Not really necessary
myLayout.Controls.Add(control, 1, rowNumber);
rowNumber++;
}
this.Controls.Add(myLayout);
}
}
This is the window I get, and I am not able to navigate from first to second field using the tab key.
Update:
Applying Visual Studio 2013 Update 5 did not help.
Something must have been corrupted in my project. The best I could do is to move on with a new clean Windows Form project, and everything now is working.
Related
I'm working on an inventory program and have finished the main functionality as a command line console app. I am now working on a version for winforms. I want to enable it to dynamically generate a Groupbox that holds some textboxes. I'd rather not design 50+ lines of multiple textboxes. Keep in mind I'm rather new to programming, having started with C# a year ago. I know next to nothing on Winforms.
I've tried to use dynamic item = new Groupbox();as a similar method allowed generation of objects at runtime. In the command line app, the way it works is that based on information given, a certain amount of objects are passed into the list _AllItems. I was thinking of generating the Groupboxes by using:
private void InitializeGroupBox()
{
foreach (Product product in Product._AllItems)
{
dynamic Item = new GroupBox();
}
}
But I have the feeling I'm nowhere near the correct method. Thanks to anybody who helps.
You will need to learn a bit more, but here is what I usually do to achieve what you asked.
internal class DynamicForm : Form
{
private FlowLayoutPanel mFlowLayoutPanel;
public DynamicForm()
{
mFlowLayoutPanel = new FlowLayoutPanel();
mFlowLayoutPanel.Dock = DockStyle.Fill;
// Add to this Form
this.Controls.Add(mFlowLayoutPanel);
InitializeGroupBox();
}
private void InitializeGroupBox()
{
mFlowLayoutPanel.SuspendLayout(); // Performance
for (int i = 1; i <= 20; i++) {
var groupBox = new GroupBox();
groupBox.Text = "GroupBox #" + i;
groupBox.Size = new Size(200, 50);
var textBox = new TextBox();
textBox.Dock = DockStyle.Fill;
// Add the TextBox to GroupBox
groupBox.Controls.Add(textBox);
// Add to this Form
mFlowLayoutPanel.Controls.Add(groupBox);
}
mFlowLayoutPanel.ResumeLayout(); // after suspend, resume!
}
}
I'm new working with C# and I'm asking on here because I didn't find a solution searching in google and other questions on SO, I will explain what my example application does:
When I run it it display a form with a textbox by default, this textbox always will be shown, after type some text and press enter it will generate a new textbox and a new button (all the controls even the default textbox are inside a panel), and the new textboxes have the same functionality as the default textbox, when I click on the button generated next to its textbox it removes the button itself and the textbox but after that if I remove some random textboxes it leaves a space between these controls, how can reorganize this content to dont let space between them?
As you can see in the image, can you tell me how can fix this or give me an advice to achieve this? thank you, by the way this is the method I use to generate the buttons and textboxes
private void GenerarTextBox()
{
panelContenedor.VerticalScroll.Value = panelContenedor.VerticalScroll.Minimum;
TextBox tb = new TextBox();
tb.Text = "Prueba " + id;
tb.Name = "txtBox" + id;
tb.KeyDown += new KeyEventHandler(TextBox_Keydown);
Button bt = new Button();
bt.Cursor = Cursors.Hand;
bt.Text = "X";
bt.Name = "btnPrueba" + id;
bt.Click += new EventHandler(ClickBotones);
Point p = new Point(20, 30 * id);
Point pb = new Point(130, 30 * id);
tb.Location = p;
bt.Location = pb;
panelContenedor.Controls.Add(tb);
panelContenedor.Controls.Add(bt);
tb.Focus();
id++;
}
And this to remove the textboxes and the buttons
private void ClickBotones(object sender, EventArgs e)
{
Button bt = sender as Button;
string nombreBoton = bt.Name;
string idBoton = nombreBoton.Substring(9);
string nombreTextBox = "txtBox" + idBoton;
foreach (Control item in panelContenedor.Controls.OfType<Control>())
{
if (item.Name == nombreTextBox)
{
panelContenedor.Controls.Remove(item);
panelContenedor.Controls.Remove(bt);
}
}
}
You could place your dynamic controls on a FlowLayoutPanel. Either directly or grouped together in a Panel or UserControl.
Set the FlowDirection property of the FlowLayoutPanel to TopDown. The FlowLayoutPanel will then arrange your controls automatically. You can also set the WrapContents property to False and AutoScroll to true to make the scroll bar appear.
Alternatively you can use FlowDirection = LeftToRight, place the text box and the button directly on the FlowLayoutPanel and let the child controls wrap (WrapContents = True). In the child controls, a new property FlowBreak appears. It can be set to True for the last control to appear in a row and let the next one wrap independently of the width of the FlowLayoutPanel.
You can also play with the Margin property of the child controls to control their layout in the FlowLayoutPanel as the Location property becomes useless.
The FlowLayoutPanel (as well as the Panel) is available in the Toolbox in the section "Containers".
When you delete the controls, you need to do a recalc of the positions. So when you have added them in sequence, you can go with:
bool repos = false;
Point p;
foreach (Control item in panelContenedor.Controls.OfType<Control>())
{
if (repos)
{
Point tmp = item.Location;
item.Location = p;
p = tmp;
}
if (item.Name == nombreTextBox)
{
panelContenedor.Controls.Remove(item);
panelContenedor.Controls.Remove(bt);
repos = true;
p = item.Location;
}
}
I have a user control that uses a textbox and a list box. List box isn't visible, it only becomes visible when user starts typing or click in text box.
I have added the user control to a group box which is on the form.
Now when the listox becomes visible, it stays inside the group box, and can't see the full height. I wan't it float on top so that i can see the full height.
I have looked around, implemented some solutions but nothing worked for me.
Constructor for the user control
namespace YarCustomControl
{
public partial class YarCustom : TextBox
{
public YarCustom()
{
InitializeComponent();
_code = "";
_id = -1;
//list box handling
listBox = new ListBox();
listBox.Visible = false;
listBox.Font = this.Font;
listBox.Location = this.Location;
listBox.BorderStyle = BorderStyle.Fixed3D;
listBox.Resize += new EventHandler(listBox_Resize);
//listBox.SelectedValueChanged += new EventHandler(listBox_SelectedValueChanged);
listBox.KeyDown += new KeyEventHandler(listBox_KeyDown);
listBox.Click += new EventHandler(listBox_Click);
//test => no affect on listbox
this.Controls.Add(listBox);
listBox.Visible = false;
}
}
}
and the following method makes the listbox visible. Both SetchildIndex (commented and not commented) throw an error
private void makeListBoxVisible()
{
Form parentForm = (this.FindForm() as Form);
//parentForm.Controls.SetChildIndex(listBox, 0);
this.Controls.SetChildIndex(listBox, 0);
listBox.Visible = true;
listBox.BringToFront();
}
What is the best approach for handling something like this?
My environment is VS2010 and WinForms.
Now when the listox becomes visible, it stays inside the group box,
and can't see the full height. I wan't it float on top so that i can
see the full height.
Simply put it directly on the Form.
I am creating a simple application that keeps track of coins. I have a button that creates a new tab in a tabcontrol container. I am wanting to add some textboxes to the newly added tabs. The below code adds a textbox to my main tab called "Control". I have tried playing around with that field, but it always adds it to the main page called control. How would I do this? I have the following code:
string name = txtName.Text;
//validate information
try { }
catch { }
//create new tab
string title = name;
TabPage myTabPage = new TabPage(title);
tabControl1.TabPages.Add(myTabPage);
//Add text boxes
TextBox tb = new TextBox();
tb.Location = new System.Drawing.Point(250, 75);
tb.Name = "TextBoxName";
tb.Size = new System.Drawing.Size(184, 20);
Control.Controls.Add(tb);
//put data inside of textboxes
tb.Text = txtCoin.Text;
myTabPage.Controls.Add(tb);
You need to add the text box to the controls collection of the new tab:
//Control.Controls.Add(tb); //Replace this line
myTabPage.Controls.Add(tb);
change
Control.Controls.Add(tb)
to
tabControl1.TabPages.Last().Controls.Add(tb)
tabControl1.TabPages.OfType<TabPage>().Last().Controls.Add(tb)
I have a program that I want each person to have their own tab, each tab would be identical, however I would like to remove a tab if I need to.
private void addPerson(string name)
{
TabPage tmp = new TabPage();
ListView tmpList = new ListView();
Button tmpButton = new Button();
this.SuspendLayout();
this.tabFrame.SuspendLayout();
tmp.SuspendLayout();
tmpList.SuspendLayout();
tmpButton.SuspendLayout();
...
//build the controll itself
tmp.Controls.Add(tmpButton);
tmp.Controls.Add(tmpList);
tmp.Location = new System.Drawing.Point(4, 22);
tmp.Name = name.Replace(' ', '_');
tmp.Padding = new System.Windows.Forms.Padding(3);
tmp.Size = new System.Drawing.Size(284, 240);
tmp.TabIndex = 3;
tmp.Text = name;
tmp.UseVisualStyleBackColor = true;
//add it to frame
this.tabFrame.Controls.Add(tmp);
tmpButton.ResumeLayout(true);
tmpList.ResumeLayout(true);
tmp.ResumeLayout(true);
this.tabFrame.ResumeLayout(true);
this.ResumeLayout(true);
{
Name will be in the form "Scott Chamberlain" so I remove the spaces and use underscores for the name field. I can add tabs fine, they show up correctly formated, however when I try to remove the tab using the code:
private void removePerson(string name)
{
this.SuspendLayout();
this.tabFrame.SuspendLayout();
this.tabFrame.Controls.RemoveByKey(name.Replace(' ', '_'));
this.tabFrame.ResumeLayout(true);
this.ResumeLayout(true);
}
The tab does not disappear from my program. What am I missing to remove a tab?
(source: codinghorror.com)
Creating a simple TabPage with a specific Name and adding it to Controls or TabPages works and so does removing it with RemoveByKey on both Controls and TabPages.
Is there any code that might later change the name?
Use tabFrame.TabPages instead of tabFrame.Controls, for both the Add() and RemoveByKey() operations.
TabPages is a more specified version of Controls, and if such a situation occurs you are better of with the more specialized option.