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);
Related
Is it possible to add a control like CheckBox to ContextMenuStrip?
I want to be able to tick a few options BEFORE I select the menu option.
This what I do now, but I have commented out where I try to add chkBox - as it does not work:
DataGridView gridView = sender as DataGridView;
ContextMenuStrip my_menu = new ContextMenuStrip();
int colIndex = gridView.HitTest(e.X, e.Y).ColumnIndex;
Globals.PlotColumnIndex = colIndex;
my_menu.Items.Add("New plot").Name = "New plot";
my_menu.Items.Add("New trades plot").Name = "New trades plot";
my_menu.Items.Add("Add to existing plot").Name = "Add to existing plot";
my_menu.Items.Add("Add to existing plot Y2").Name = "Add to existing plot Y2";
CheckBox chkBox = new CheckBox();
chkBox.Text = "Option 1";
//my_menu.Controls.Add(chkBox);
my_menu.Show(gridView, new Point(e.X, e.Y));
my_menu.ItemClicked += new ToolStripItemClickedEventHandler(my_menu_ItemClicked);
Using a ToolStripControlHost is one option:
var cb = new CheckBox();
cb.Text = "Checkbox 1";
var tch = new ToolStripControlHost(cb);
menu.Items.Add(tch);
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();
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);
}
I have three drop down lists and depending on the values selected in the lists I create dynamic controls accordingly. Everything displays properly but when I click on the dynamically created button the events are not firing. I am using the Page_LoadComplete to create the dynamic controls because I need to the values from the DDL's. Is this the reason for my button events not firing?
protected void Page_LoadComplete(object sender, EventArgs e)
{
queries = new clsFormQueries();
if (HttpContext.Current.User.IsInRole("Admin"))
{
if (!Page.IsPostBack)
{
List<Sport> sports = ComboBoxOptions.getSports();
DropDownList temp = (DropDownList)loginView2.FindControl("Sport");
temp.DataSource = sports;
temp.DataTextField = "Name";
temp.DataValueField = "id";
temp.DataBind();
DropDownList teamsDD = (DropDownList)loginView2.FindControl("Team");
List<Team> teamsList = ComboBoxOptions.getTeamsBySportId(Convert.ToInt32(temp.SelectedValue));
teamsDD.DataSource = teamsList;
teamsDD.DataTextField = "fullName";
teamsDD.DataValueField = "teamId";
teamsDD.DataBind();
DropDownList existingPlayers = (DropDownList)loginView2.FindControl("ExistingPlayers");
List<Player> players = ComboBoxOptions.getPlayersBySport(Convert.ToInt32(temp.SelectedValue), Convert.ToInt32(teamsDD.SelectedValue));
existingPlayers.DataSource = players;
existingPlayers.DataTextField = "fullName";
existingPlayers.DataValueField = "playerid";
existingPlayers.DataBind();
//if (existingPlayers.SelectedValue != "" && temp.SelectedValue != "")
//{
// DataTable updates = queries.GetPlayerUpdate(Convert.ToInt32(existingPlayers.SelectedValue), Convert.ToInt32(temp.SelectedValue));
// if (updates.Rows.Count > 0)
// CreateUpdatesHTML(updates);
//}
}
DropDownList temp2 = (DropDownList)loginView2.FindControl("Sport");
DropDownList existingPlayers2 = (DropDownList)loginView2.FindControl("ExistingPlayers");
if (existingPlayers2.SelectedValue != "" && temp2.SelectedValue != "")
{
DataTable updates = queries.GetPlayerUpdate(Convert.ToInt32(existingPlayers2.SelectedValue), Convert.ToInt32(temp2.SelectedValue));
if (updates.Rows.Count > 0)
CreateUpdatesHTML(updates);
}
}
}
private void CreateUpdatesHTML(DataTable updates)
{
foreach (DataRow update in updates.Rows)
{
int playerUpdateId = (int)update["playerUpdateId"];
string updateText = update["PlayerUpdate"].ToString();
TextBox tb = new TextBox();
tb.ID = "UpdateText" + playerUpdateId;
tb.TextMode = TextBoxMode.MultiLine;
tb.Rows = 5;
tb.Text = updateText;
tb.CssClass = "span5";
Button btnDelete = new Button();
btnDelete.Click += new EventHandler(btnDelete_Click);
btnDelete.ID = "Delete"+playerUpdateId.ToString();
btnDelete.Text = "Delete";
btnDelete.CssClass = "btn btn-info";
Button btnUpdate = new Button();
btnUpdate.Click += new EventHandler(btnUpdate_Click);
btnUpdate.ID = "Update"+playerUpdateId.ToString();
btnUpdate.Text = "Update";
btnUpdate.CssClass = "btn btn-info";
HtmlGenericControl div2 = new HtmlGenericControl("div");
div2.Attributes.Add("class", "pull-right span5");
div2.Controls.Add(btnDelete);
div2.Controls.Add(btnUpdate);
HtmlGenericControl hr = new HtmlGenericControl("hr");
HtmlGenericControl br = new HtmlGenericControl("br");
existingUpdates.Controls.Add(tb);
existingUpdates.Controls.Add(div2);
existingUpdates.Controls.Add(br);
existingUpdates.Controls.Add(hr);
}
}
My guess is that since you have wrapped the logic for your Page_LoadComplete event inside of a n if(!Page.IsPostBack), since the click of the button causes a postback, your dynamically created controls are not recreated properly (read: no click event handling is wired up). You need to have logic on every invocation of Page_LoadComplete (non-postback or postback) that recreates the dynamic controls and wires up their events.
So I am trying to make a dynamic form builder where people can add a new form and add fields to that form (the add field brings up several textboxes & dropdown options for that new field). Is there any way to append to a placeholder control when clicking 'add new field'? Also, what is the best way to get the values from those dynamically added controls?
A few simple steps...
1) Create a new instance of the control. Populate any desired properties.
2) Add it to the PlaceHolder using the PlaceHolder's .Controls.Add method.
3) Add the control's event handler. By using a delegate, as shown, you can access the control's values.
DropDownList ddl = new DropDownList();
ListItem li0 = new ListItem(string.Empty, "0");
ListItem li1 = new ListItem("Hello", "1");
ListItem li2 = new ListItem("World", "2");
ddl.Items.Add(li0);
ddl.Items.Add(li1);
ddl.Items.Add(li2);
ddl.AutoPostBack = true;
PlaceHolder1.Controls.Add(ddl);
ddl.SelectedIndexChanged += delegate(object snd, EventArgs evt) { DoSomething(ddl.SelectedValue); };
public void DoSomething(string SelectedValue)
{
//Do something spectacular here...
}
This is the other option (appending to a Literal Control). Each time the user clicks a button, a new field is created. I don't know how to add those dynamic fields to the database. Should I do a foreach?
protected void Button1_Click(object sender, EventArgs e)
{
var thisstring = new StringWriter();
var writer = new HtmlTextWriter(thisstring);
var formLabel = new TextBox();
formLabel.Text = idValue.ToString();
writer.Write("Field Label:");
formLabel.RenderControl(writer);
var typeOptions = new DropDownList();
typeOptions.DataSource = getfieldtypes();
typeOptions.DataTextField = "description";
typeOptions.DataValueField = "id";
typeOptions.DataBind();
writer.Write("Field Type:");
typeOptions.RenderControl(writer);
writer.WriteBreak();
Literal1.Text += thisstring;
}