I am generating dynamic textbox controls on drop down selected index change event.
protected void ddlCategories_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (Attributes attribute in getAllAttributes(Convert.ToInt32(ddlCategories.SelectedValue)))
{
Panel div = new Panel();
div.Attributes.Add("class", "form-group");
HtmlGenericControl lbl = new HtmlGenericControl("label");
lbl.Attributes.Add("class", "col-lg-2 control-label");
lbl.InnerText = attribute.Name;
Panel innerdiv = new Panel();
innerdiv.Attributes.Add("class", "col-lg-10");
TextBox txt = new TextBox();
txt.ID = attribute.ID.ToString();
txt.Attributes.Add("class", "form-control");
innerdiv.Controls.Add(txt);
div.Controls.Add(lbl);
div.Controls.Add(innerdiv);
CustomAttributes.Controls.Add(div);
}
}
Now after the user fill up the values in the form i want to get the values of the dynamically generated controls. But CustomAttributes.findControls("") doesn't work for me. it gives null all the time.
I also tried
var textBoxesInContainer = CustomAttributes.Controls.OfType<TextBox>();
but it also doesnt work.
Can any one please tell me what is going wrong here.
Thanks
Finally i found the reason after googling the issue. The issue in this question is a view state.
In asp.net when the page post back it loses the viewstate for the dynamically generated controls. So to get over this issue i recreated the controls in the page load event when it is post back. in that way controls will be added back to the current page and i can find those controls in the button on click event.
thanks all for your time and guidence.
Panel div = new Panel();
Panel innerdiv = new Panel();
TextBox txt = new TextBox();
innerdiv.Controls.Add(txt);
div.Controls.Add(innerdiv);
CustomAttributes.Controls.Add(div);
Your CustomAttributes holds Panel.
Try this :
var textboxes = CustomAttributes.Controls.OfType<Panel>()
.Select(p => p.Controls.OfType<Panel>().First())
.Select(p => p.Controls.OfType<TextBox>().First())
Related
TLDR; Looking for a method to retrieve all radiobuttons by means of something like this... (psudo)
List<RadioButton> btn = new List<RadioButton>;
btn = stackPanel.getAllRadioButtons()
I am currently building a little quiz application in C#. I have functions that add the required GUI elements to a groupbox. I would like to know if there is any way that I can loop through the created elements (for instance radio buttons) to see which are checked.
Here is one of the functions along with how they are added to the window.
private void tfQ(string questionBody)
{
StackPanel questionPanel = new StackPanel{Orientation = Orientation.Vertical};
questionPanel.Children.Add(new Label { Content = questionBody });
GroupBox group = new GroupBox();
RadioButton trueRadio = new RadioButton();
trueRadio.Content = "True";
RadioButton falseRadio = new RadioButton();
falseRadio.Content = "False";
questionPanel.Children.Add(trueRadio);
questionPanel.Children.Add(falseRadio);
group.Content = questionPanel;
mainStack.Children.Add(group);
}
Constructor:
public quiz()
{
tfQ("This is a true/false question");
Window w = new Window();
w.Content = mainStack;
w.Show();
}
I have found many ways to do it in the C# scripting format
(using the Control function ...)
var checkedButton = container.Controls.OfType<RadioButton>()
.FirstOrDefault(r => r.Checked);
but I have not yet found a "programmatic" way of doing it. I have considered changing the type of void tfQ to a StackPanel, but that only helps me to easier loop through the stack panels, althought that only partly solves me problem - allows me to easier loop through the StackPanels but I still don't know how to get the RadioButtons on a panel.
P.S I am very new to C# - with experience in Java/C/C++/Python
I made use of the following code to cast the content into a new groupbox and stackpanel, respectively.
if (child is GroupBox)
{
if ((child as GroupBox).Content is StackPanel)
{
StackPanel d = (StackPanel)((GroupBox)child).Content;
}
}
This allowed me to cast the content into a local copy of a control. It may not be the best way - I'm sure it is very inefficient to be honest. Solved the problem.
I'm dynamically creating controls on my page (aspx) using the code below, but when the asynchronous postback triggers the radio button doesn't retain it's selection and the method uptheup doesn't get called. I'm guessing it's to do with the view state not returning the values, but I thought if the control ID was the same and it's created in Page_Init the in Page_Load the value should automatically be set from view state??
What I want is if someone selects No for the textbox to become visible. The control IDs are set from a database and are the same each time it loads as the code is used several times (I've replaced the IDs for easy reading below)
the following is called from Page_Init
RadioButtonList rbtnl = new RadioButtonList();
rbtnl.ID = "rbl_1";
rbtnl.Items.Add("Yes");
rbtnl.Items.Add("No");
rbtnl.AutoPostBack = true;
rbtnl.EnableViewState = true;
rbtnl.SelectedIndexChanged += new EventHandler(uptheup);
rbtnl.ClientIDMode = System.Web.UI.ClientIDMode.AutoID;
scriptmanager1.RegisterAsyncPostBackControl(rbtnl);
TextBox tbx = new TextBox();
tbx.ID = "tb-1";
tbx.CssClass = "form-control";
tbx.Visible = false;
UpdatePanel upx = new UpdatePanel();
upx.ID = "up-1";
upx.ContentTemplateContainer.Controls.Add(rbtnl);
upx.ContentTemplateContainer.Controls.Add(tbx);
upx.UpdateMode = UpdatePanelUpdateMode.Always;
upx.EnableViewState = true;
upx.ChildrenAsTriggers = true;
plcEvalBody.Controls.Add(upx);
OK so the code is fine and it works well, the issue was me assuming the IDs weren't the issue - they are - NEVER USE $ in control ID's. I'd used this to separate two sections of the ID and it is not valid.
I'm a newbie in c# and probably going to ask a very easy question, but I've not been able to find anything on the web to help.
I have a tabControl with a TabPage which is containing a TextBox object; this object, when the event "Text changed" is invoked, will perform the change of the parent tabPage's name.
The textbox where I typed "text changed by me" has a method which is managing changing the name of the tabPage:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (this.textBox1.Text != "")
this.tabControl2.SelectedTab.Text = this.textBox1.Text;
else
this.tabControl2.SelectedTab.Text = "(no name)";
}
Into the current page menu is contained a control to add a new page, which runs this method when the user click on it:
private void addNewPageToolStripMenuItem_Click(object sender, EventArgs e)
{
int numPagine;
string strPagine;
numPagine = this.tabControl2.TabCount;
strPagine = numPagine.ToString();
this.tabControl2.TabPages.Add("new page" + strPagine);
}
...and here is the output, which is expected since I'm just asking to add a new empty tabPage:
So, my question is: how can I make possible that when the user is clicking on "Add new page", rather than creating an empty new tabPage the program is rather creating a page like the first one (i.e. containing a textbox into the same position which has a method to change the text of the parent tabPage that I have just created?
Here is an example.
//..
// create the new page
TabPage tpNew = new TabPage("new page..");
// add it to the tab
this.tabControl2.TabPages.Add(tpNew);
// create one labe with text and location like label1
Label lbl = new Label();
lbl.Text = label1.Text;
lbl.Location = label1.Location;
// create a new textbox..
TextBox tbx = new TextBox();
tbx.Location = textBox1.Location;
tpNew.Controls.Add(lbl);
tpNew.Controls.Add(tbx);
// add code to the new textbox via lambda code:
tbx.TextChanged += ( (sender2, evArgs) =>
{
if (tbx.Text != "")
this.tabControl2.SelectedTab.Text = tbx.Text;
else
this.tabControl2.SelectedTab.Text = "(no name)";
} );
For more complicated layout you may want to consider creating a user control..
You also may want to create the first page with this code; the, of course with real values for text and positions!
For creating a UserControl you go to the project tag and right click Add-UserControl-UserControl and name it, maybe myTagPageUC. Then you can do layout on it like on a form. A rather good example is right here on MSDN
The problem is that is has no connection to the form, meaning you'll have to code all sorts of references to make it work..
I'm not really sure if you may not be better off writing a complete clonePage method instead. It could work like the code above, but would loop over the Controls of the template page and check on the various types to add the right controls..
It really depends on what is more complicated: the Layout or the ties between the pages and the form and its other controls..
I have a problem, im making me own custom SharePoint webpart.
everything is going well, but the problem is that i can't figure out how to change the location of the textboxes and labels.
anyone knows how i can change the locations?
I am trying to accomplish it in C#.
problem SOLVED.
With the help of component ids. set position of that particular component.
"How to change the location of the textboxes and labels"
In this example i'm using a Button (Action performed on Button Click) and i am also adding how to Generate a TextBox and a Label (When you press this Button).
Just because this is usually a common process within setting locations to a control.
private void button1_Click(object sender, EventArgs e)
{
// Settings to generate a New TextBox
TextBox txt = new TextBox(); // Create the Variable for TextBox
txt.Name = "MyTextBoxID"; // Identify your new TextBox
// Create Variables to Define "X" and "Y" Locations
var txtLocX = txt.Location.X;
var txtLocY = txt.Location.Y;
//Set your TextBox Location Here
txtLocX = 103;
txtLocY = 74;
// This adds a new TextBox
this.Controls.Add(txt);
// Now do the same for Labels
// Settings to generate a New Label
Label lbl = new Label(); // Create the Variable for Label
lbl.Name = "MyNewLabelID"; // Identify your new Label
// Create Variables to Define "X" and "Y" Locations
var lblLocX = lbl.Location.X;
var lblLoxY = lbl.Location.Y;
//Set your Label Location Here
lblLocX = 34;
lblLoxY = 77;
// Adds a new Label
this.Controls.Add(lbl);
}
}
Note: This is just an example and will not work after postback.
I hope this answers to your and everyone's question.
For my C# Windows Form Application, I have created a flowlayoutpanel that contains several panels. Inside the panel, I have a button "Clear" for each and every single panel.
How do I write the event handler for the code for the button "Clear" such that once I have click the button, the panel would sort of be "Removed" from the flowlayoutpanel.
This is a short part of the code of the adding of panels to the flowlayoutpanel.
nFlowPanel.Controls.Add(createNotificationPanel());
nFlowPanel.Controls.Add(createNotificationPanel());
nFlowPanel.Controls.Add(createNotificationPanel());
nFlowPanel.Controls.Add(createNotificationPanelImpt());
nFlowPanel.Controls.Add(createNotificationPanelImpt());
and this is the code for the button "Clear"
Button btnClear = new Button
{
Text = "Clear",
Name = "btnClear",
Location = new Point(416, 17)
};
p.Controls.Add(btnClear);
btnClear.Click += new EventHandler(buttonClear_Click);
So what should i write in the following method to have the effect of removing e.g. the second panel that was added in the first part of code I have written?
void buttonClear_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
EDIT
the code for creating my panel is
var p = new Panel
{
BorderStyle = BorderStyle.FixedSingle ,
Size = new Size(506,100),
Name = "notifyPanel"
};
and the code for creating my FlowLayoutPanel is
var nFlowPanel = new FlowLayoutPanel
{
FlowDirection = FlowDirection.TopDown,
WrapContents = false,
AutoScroll = true,
Size = new Size(530, 377),
Location = new Point(13, 145)
};
and the code for my button clear is
void buttonClear_Click(object sender, EventArgs e)
{
var button = (Control)sender;
var panel = button.Parent.Controls["notifyPanel"];
panel.Dispose();
}
however it gives the error
Object reference not set to an instance of an object.
on the panel.Dispose() line.
anyone can help?
The Controls.Remove() method is very dangerous, it doesn't dispose the control. Which will live on, moved to the so-called parking window, using up both Windows and managed resources. After a bit less than 10,000 times doing this it crashes your program when Windows is no longer willing to let you create any more windows.
Call the control's Dispose() method instead. That also automatically removes the control from its container.
void buttonClear_Click(object sender, EventArgs e)
{
var panel = nFlowPanel.Controls["notifyPanel"];
panel.Dispose();
}
You can do it like this:
nFlowPanel.Controls.Remove((sender as Button).Parent);
I will suggest you to use List for this. Before adding Panels in the FlowLayoutpanel, add them in the List. Then just remove the indexed panel from the flowlayoutpanel.
Panel pnlTemp = (panel)list[index];
nFlowPanel.Controls.Remove(pnlTemp);
To get the index of the button you have to add your buttons also to your list and after clicking any button, search the button in the list and get the index of the button where it is saved in the list. If my code is unclear, let me know. but I feel your task is that complex. I am not sure but this link may be of some help.
Hope it helps.