Why does my dynamic textbox not remove on first click? - c#

I started this question and was able to get an answer to my original question. Now the textbox gets removed but only the second time I click the remove button. Here is what I have tried
protected void btnRemoveTextBox_Click(object sender, EventArgs e)
{
foreach (Control control in PlaceHolder1.Controls)
{
var tb = new TextBox();
tb.ID = "Textbox" + counter;
if ((control.ID == tb.ID.ToString()) && (control.ID != null))
{
controlIdList.Remove(tb.ID);
ViewState["controlIdList"] = controlIdList;
}
}
}
When I step through using breakpoints and error debugging the code runs through twice without error however on the second time through it removes the button.

Because you created and added textboxes in LoadViewState method (earlier in the the page's life cycle), and here only remove an id from controlIdList but not from the control tree. Note: you do not need to create new TextBox instances in btnRemoveTextBox_Click method.
protected void btnRemoveTextBox_Click(object sender, EventArgs e)
{
foreach (Control control in PlaceHolder1.Controls)
{
string id = "Textbox" + counter;
if (control.ID == id)
{
controlIdList.Remove(id);
PlaceHolder1.Controls.Remove(control);
break;
}
}
}

Related

MouseHover event on custom usercontrol c#

I created a usercontrol textbox named ucTextBox contains a label, a textbox and two buttons. I put it many in my form.
Now I want to attach a MouseHover event on each ucTextBox,TextBox and MaskedTextBox in my form.
I do this :
public void AttachHoverEvent(Control CTrl)
{
foreach (Control c in CTrl.Controls)
{
if (c is TextBox || c is MaskedTextBox)
{
c.MouseHover += new EventHandler(afficheDictionnaireChamp);
c.MouseLeave += new EventHandler(desafficheDictionnaireChamp);
continue;
}
if (c is ucTextBox)
{
c.MouseHover += new EventHandler(afficheDictionnaireChamp);
c.MouseLeave += new EventHandler(desafficheDictionnaireChamp);
continue;
}
if (c.HasChildren)
{
AttachHoverEvent(c);
}
}
}
Note : I put ucTextBox in other condition to put a breakpoint and the condition is true.
My code works correctly for TextBox and MaskedTextBox but don't work on my
ucTextBox (Nothing happen).
I try to add this in my ucTextBox class :
private void txbValeur_MouseHover(object sender, EventArgs e)
{
if (this.MouseHover != null)
this.MouseHover(this, e);
}
This my target events function :
public void afficheDictionnaireChamp(object sender, EventArgs e)
{
Dictionnaire dico = new Dictionnaire();
Control snd = (Control)sender;
string table = dico.getNomTable(this.Name, snd.Name);
string champ = dico.getNomChamp(this.Name, snd.Name);
if (table != "" && champ != "")
Globals.FormMain.tslTable.Text = table + " - " + champ;
else
Globals.FormMain.tslTable.Text = "";
}
public void desafficheDictionnaireChamp(object sender, EventArgs e)
{
Globals.FormMain.tslTable.Text = "";
}
If someone got an idea where the problem can from ?
Thanks in advance !
Thomas
Try to set your parent controls background to "Transparent"

Search function for controls at run time

I have a tab control where I can add custom controls made from a button and a label underneath. I want to add a search function to my project so that when a user type a name of a control, it will show all controls where the name (label) starts with the letters typed. Also typing in a textbox will do the job.. Is there an easy way to do this?
You can search controls within parent control collection:
foreach(Control c in ParentControl.Controls)
{
if(c.Name == "label1")
{
//add to your list
}
}
You can also check using StartsWith("stringVal")
if(c.Name.StartsWith("l"))
{
//add to your list
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
foreach (Control control in this.Controls)
{
// Skip, if the control is the used TextBox
if (control == textBox1) { continue; }
// Show all controls where name starts with inputed string
// (use ToLower(), so casing doesnt matter)
if (control.Name.ToLower().StartsWith(textBox1.Text.Trim().ToLower()))
{
control.Visible = true;
}
// Hide objects that doesn't match
else { control.Visible = false; }
}
}
This toggles the controls' visibility, and hide's all items, that doesn't match the given input. Also casing doesn't matter.
Done when adding the text to search in a textbox.
private void textBox1_TextChanged(object sender, EventArgs e)
{
foreach (Control c in fl_panel.Controls)
{
if (c.Name.ToUpper().StartsWith(textBox1.Text.ToUpper().ToString()) && textBox1.Text != "")
{
Control[] ctrls = fl_panel.Controls.Find(textBox1.Text.ToString(), true);
c.Visible = true; // to restore previous matches if I delete some text
}
else if(textBox1.Text == "")
{
c.Visible = true;
}
else
{
c.Visible = false;
}
}
}
you can try this to find the controls that matches a text typed in the textbox, after that you can do whatever you want with it.
private void textBox1_TextChanged(object sender, EventArgs e)
{
var controlMatchesCriteria = from c in this.Controls.OfType<TextBox>()
where c.Name == textBox1.Text
select c;
}

Changing CSS of dynamically created controls in ASP.Net

I am creating a web application where I need to change the CSS class of one of the button that I have created dynamically using C# code.
The code that I am using is this
public void createbuttons()
{
for (int i = 1; i <= 200; i++)
{
Button b = new Button();
b.ID = "Button" + i.ToString();
b.Text = i.ToString();
PanelQuestionPallette.Controls.Add(b);
b.CssClass = "buttongrey";
}
}
protected void Page_Load(object sender, EventArgs e)
{
createbuttons();
}
protected void ButtonChangeCss_Click(object sender, EventArgs e)
{
foreach (Control c in PanelQuestionPallette.Controls)
{
if (c.GetType() == typeof(Button) && c.ID == ("Button" + Convert.ToInt32(Session["QuestionCounter"])).ToString())
{
//c.Attributes.Add("class", "buttonpurpgreen");
}
}
}
}
I tried to change the CSS from "buttongrey" to "buttonpurpgreen".
Here the Session["QuestionCounter"] is a counter which is getting incremented.
I would suggest a template based approach like a repeater control, and instead rely on data binding for setting these values. You can then on post back set your bound properties to reflect the current css class.

.Net Webform losing data

I am having problems getting my page to maintain state. View state is enabled by default but everytime I click a button it resets the form. This is the code I have
protected void Page_Load(object sender, EventArgs e)
{
Levels loadGame = new Levels(currentGame);
int [] gameNums = loadGame.getLevelNums();
int inc = 1;
foreach(int i in gameNums){
if (i != 0)
{
TextBox tb = (TextBox)FindControl("TextBox" + inc);
tb.Text = i.ToString();
tb.Enabled = false;
}
else {
//leave blank and move to next box
}
inc++;
}
This is the initial load
protected void NormalButton_Click(object sender, EventArgs e)
{
clearBoxes();//clear boxes first
setCurrentGame("normal");//setting to normal returns normal answers
Levels loadGame = new Levels(returnCurrentGame());
int[] gameNums = loadGame.getLevelNums();
int inc = 1;
foreach (int i in gameNums)
{
if (i != 0)
{
TextBox tb = (TextBox)FindControl("TextBox" + inc);
tb.Text = i.ToString();
tb.Enabled = false;
}
else
{
//leave blank and move to next box
}
inc++;
}
}
Clicking this button changes the numbers in different boxes.
protected void Button1_Click(object sender, EventArgs e)
{
}
Then I have this empty button but everytime I click it, it resets the form even though I havent set it to do anything yet. I would like the boxes to stay the same and I would also like to keep the objects alive. I'm not sure what I'm missing but please point me in the right direction. Thanks in advance
The Page_Load event occurs every time the page is loaded, including event-driven postbacks (button clicks, etc).
It looks like initialization code is in your Page_Load, so when you click the button it runs again.
There are two options:
Put everything that you want to happen only on the FIRST load in a n if statement:
Move your initialization to Page_Init.
Code sample for the first option:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack) // Teis is the key line for avoiding the problem
{
Levels loadGame = new Levels(currentGame);
int [] gameNums = loadGame.getLevelNums();
int inc = 1;
foreach(int i in gameNums){
if (i != 0)
{
TextBox tb = (TextBox)FindControl("TextBox" + inc);
tb.Text = i.ToString();
tb.Enabled = false;
}
else {
//leave blank and move to next box
}
inc++;
}
}
}
Also, recommended reading: The ASP.NET Page Lifecycle

Adding different controls having same names in C# Windows Form

I am working in C# windows forms application in which I am adding 3 different controls having same name (a button, a textBox & a Label) to my form.
Why there is error in button4_Click?
CODE:
private void button1_Click(object sender, EventArgs e)
{
TextBox myControl = new TextBox();
myControl.Name = "myControl";
this.Controls.Add(myControl);
}
private void button2_Click(object sender, EventArgs e)
{
Button myControl = new Button();
myControl.Name = "myControl";
this.Controls.Add(myControl);
}
private void button3_Click(object sender, EventArgs e)
{
Label myControl = new Label();
myControl.Name = "myControl";
this.Controls.Add(myControl);
}
private void button4_Click(object sender, EventArgs e)
{
((ComboBox)this.Controls["myControl"]).Text = "myCombo"; // works
((TextBox)this.Controls["myControl"]).Text = "myText"; // error
((Label)this.Controls["myControl"]).Text = "myLabel"; // error
}
The Controls[string] indexer returns the first control whose name matches the string. It will be hit and miss with your code but you probably have a ComboBox already added to the form with that same name. The next statements go kaboom because you cannot cast a ComboBox to a TextBox.
Of course, do try to do the sane thing, give these controls different names.
this.Controls["myControl"] returns the first control named myControl.
This is a TextBox, not a Label.
Instead of accessing them through the Controls collection, you should store your controls in fields in the form class (perhaps using List<T>s).
Here is one idea that might help you:
void SetControlText(Type controlType, string controlName, string text) {
foreach (var ctl in this.Controls.OfType<Control>()) {
if (ctl.GetType() == controlType && ctl.Name == controlName) {
ctl.Text = text;
break;
}
}
}
Or with LINQ only:
var item = this.Controls.OfType<Control>().Where(j => j.GetType() == controlType && j.Name == controlName).FirstOrDefault();
if (item != null)
item.Text = text;
Simply call the above function like so:
SetControlText(typeof(Button), "myButton", "Text was set!");
This function will iterate through all of the controls on the form, and when it finds the control type you specify with the name you specify, it will update the controls .Text field.

Categories