I've a number of Devexpress controls on my form under layoutcontrol1. I used
the code below to iterate through each control and clear the existing data when users click on "Clear" button. However, it doesn't work on LookupEdit (set the EditValue to 0) and CheckedListBoxControl (uncheck all the selected items).
foreach (Control c in layoutControl1.Controls)
{
if (c.GetType() == typeof(TextEdit) || c.GetType()==typeof(MemoEdit))
c.Text = String.Empty;
if (c.GetType() == typeof(LookUpEdit))
c.EditValue = 0; //doesn't have EditValue property
if (c.GetType() == typeof(CheckedListBoxControl))
c.CheckedItems = CheckState.Unchecked; //doesn't have such property
}
Any suggestion?
Just try the following:
foreach(Control c in layoutControl1.Controls) {
var edit = c as DevExpress.XtraEditors.BaseEdit; // base class for DX editors
if(edit != null)
edit.EditValue = null;
var listBox = c as DevExpress.XtraEditors.CheckedListBoxControl;
if(listBox != null)
listBox.UnCheckAll();
}
Related
In my form I've 50 textboxes in visible=false state, when a user enter particular number , those many textboxes should be displayed and the remaining textboxes should remain in visible false state.
Should end up looking something like this:
foreach (var control in this.Controls)
{
var textbox = control as TextBox;
if (var != null) textbox.Visible = true;
}
You can loop throug all textbox controls like this:
foreach (Control item in this.form1.Controls)
{
System.Web.UI.HtmlControls.HtmlInputText tbx = item as System.Web.UI.HtmlControls.HtmlInputText;
if (tbx!= null)
{
if(tbx.Text == "some text")
tbx.Visible = false; // or true how ever you want it
else
tbx.Visible = true;
}
}
So if tbx is not null, item is textbox, actually:
<input type="text"/>
You can do this same trick with other HtmlControls.
Change form1 to that form you, which controls you want to loop through.
You can wrap all your control inside a Asp.net Panel Control.
int counter = 0;
int numberOfTextBoxtoShow = 4; // set by user
foreach (Control c in Panel1.Controls)
{
if (c is TextBox)
{
if (counter < numberOfTextBoxtoShow)
{
c.Visible = true;
counter++;
}
else c.Visible = false;
}
}
I need a way to dynamically gather all of the TextBoxes inside of a custom UserContorl in ASP.net WebForms, server-side
I thought this would work:
foreach (var control in Page.Controls)
{
var textBox = control as TextBox;
if (textBox != null && textBox.MaxLength > 0)
{
// stuff here
}
}
But it doesn't do what I thought it would, and I don't see how else to get that information.
So, how can I dynamically get all of the textboxes on the server-side of a custom UserControl in ASP.net webforms?
You need a recursive method, because not all level 1 children are necessarily text boxes (depends on the control/container hierarchy in your user control):
private IEnumerable<TextBox> FindControls(ControlCollection controls)
{
List<TextBox> results = new List<TextBox>();
foreach(var control in controls)
{
var textBox = control as TextBox;
if (textBox != null && textBox.MaxLength > 0)
{
results.Add(textBox);
}
else if(textBox == null)
{
results.AddRange(FindControls(control.Controls));
}
}
return results;
}
After you get the results you can iterate them and do whatever you need to do.
Looks like recursive is the way to go:
foreach (Control control in Page.Controls)
{
DoSomething(control);
}
// And you need a new method to loop through the children
private void DoSomething(Control control)
{
if (control.HasControls())
{
foreach(Control c in control.Controls)
{
DoSomething(c);
}
}
else
{
var textBox = control as TextBox;
if (textBox != null)
{
// Do stuff here
}
}
}
I want to add runat=server dynamically to a CheckBoxList so that it can be found by FindControl.
CheckBoxList cbl = new CheckBoxList();
cbl.ID = "cbl" + intQuestionCount.ToString();
// get choices from choice list
int intChoiceListId = Convert.ToInt32(detail.ChoiceListID);
var choiceList = (from cl in _svsCentralDataContext.SVSSurvey_ChoiceListItems
where cl.ChoiceListID == intChoiceListId
orderby cl.Description
select cl);
cbl.DataSource = choiceList;
cbl.DataTextField = "Description";
cbl.DataBind();
cbl.Visible = true;
cbl.CssClass = "PositionCol3";
questionsPanel.Controls.Add(cbl);
I have 2 recursive find control methods:
private HtmlControl FindHtmlControlByIdInControl(Control control, string id)
{
foreach (Control childControl in control.Controls)
{
if (childControl.ID != null && childControl.ID.Equals(id, StringComparison.OrdinalIgnoreCase)
&& childControl is HtmlControl
)
{
return (HtmlControl)childControl;
}
if (childControl.HasControls())
{
HtmlControl result = FindHtmlControlByIdInControl(childControl, id);
if (result != null)
{
return result;
}
}
}
return null;
}
private WebControl FindWebControlByIdInControl(Control control, string id)
{
foreach (Control childControl in control.Controls)
{
if (childControl.ID != null && childControl.ID.Equals(id, StringComparison.OrdinalIgnoreCase)
&& childControl is WebControl
)
{
return (WebControl)childControl;
}
if (childControl.HasControls())
{
WebControl result = FindWebControlByIdInControl(childControl, id);
if (result != null)
{
return result;
}
}
}
return null;
}
The screen is initially created dynamically (if !isPostback), based on an SQL record. The FindControl methods are used after this lot has been displayed, when the user clicks the 'Save' button.
Neither Find control method finds my CheckBoxList!!
You are adding controls through your code behind, they are already server side controls, you don't have to add runat="server". You are not finding them properly.
Make sure they are added to the page before you look for them.
I have written a method that loops through all the properties of an object and maps them to controls that have the same name (or prefix + name). The issue is that I have certain controls inside an update panel (drop down lists that change when a different option is selected) that are not being found when running through this method. I read this and adapted the method below to accommodate for that, but it still will not find the controls inside the update panel. All the controls have IDs and runat="server".
public static void MapObjectToPage(this object obj, Control parent, string prefix = "")
{
Type type = obj.GetType();
Dictionary<string, PropertyInfo> props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(info => prefix + info.Name.ToLower());
ControlCollection theControls = parent is UpdatePanel ? ((UpdatePanel)parent).ContentTemplateContainer.Controls : parent.Controls;
foreach (Control c in theControls)
{
if (props.Keys.Contains(c.ClientID.ToLower()) && props[c.ClientID.ToLower()].GetValue(obj, null) != null)
{
string key = c.ClientID.ToLower();
if (c.GetType() == typeof(TextBox))
{
((TextBox)c).Text = props[key].PropertyType == typeof(DateTime?)
|| props[key].PropertyType == typeof(DateTime)
? ((DateTime)props[key].GetValue(obj, null)).ToShortDateString()
: props[key].GetValue(obj, null).ToString();
}
else if (c.GetType() == typeof(HtmlInputText))
{
((HtmlInputText)c).Value = props[key].PropertyType == typeof(DateTime?)
|| props[key].PropertyType == typeof(DateTime)
? ((DateTime)props[key].GetValue(obj, null)).ToShortDateString()
: props[key].GetValue(obj, null).ToString();
}
//snip!
}
if (c is UpdatePanel
? ((UpdatePanel)c).ContentTemplateContainer.HasControls()
: c.HasControls())
{
obj.MapObjectToPage(c);
}
}
}
Try to add this two methods to a new or existing class:
public static List<Control> FlattenChildren(this Control control)
{
var children = control.Controls.Cast<Control>();
return children.SelectMany(c => FlattenChildren(c).Where(a => a is Label || a is Literal || a is Button || a is ImageButton || a is GridView || a is HyperLink || a is TabContainer || a is DropDownList || a is Panel)).Concat(children).ToList();
}
public static List<Control> GetAllControls(Control control)
{
var children = control.Controls.Cast<Control>();
return children.SelectMany(c => FlattenChildren(c)).Concat(children).ToList();
}
You can call the GetAllControls method with the updatePanel as parameter (or the main container). The method returns all the children of the 'control' parameter. Also, you can remove the Where clause to retrieve all the controls (not those of a certain type).
I hope this will help you!
UpdatePanel is directly access. You don't need to/can't use FindControl to find it. Use this
foreach (Control ctrl in YourUpdatepanelID.ContentTemplateContainer.Controls)
{
if (ctrl.GetType() == typeof(TextBox))
((TextBox)(ctrl)).Text = string.Empty;
if (ctrl.GetType() == typeof(CheckBox))
((CheckBox)(ctrl)).Checked = false;
}
I want to get values from a selected row of DataGridView and assign them into a few different
controls on a Form when a control's name match a column's name (there is TextBox, ComboBox and NumericUpDown).
This is how I am populating the controls currently:
Form myForm = new Form();
if (comboBoxTable.Text == "Client")
{
myForm = new EditClientDataWindow();
}
else if (comboBoxTable.Text == "Agency")
{
myForm = new EditAgencyDataWindow();
}
else if (comboBoxTable.Text == "Medicine")
{
myForm = new EditMedicineDataWindow();
}
string val;
foreach (Control c in myForm.Controls)
{
for (int i = 0; i < dataGridViewMDB.ColumnCount; i++)
{
val = dataGridViewMDB.SelectedRows[0].Cells[i].Value.ToString();
if (dataGridViewMDB.Columns[i].Name.ToString() ==
c.Name.ToLower().Replace(c.GetType().ToString().ToLower().Replace("system.windows.forms.", ""), ""))
{
if (c is NumericUpDown)
(c as NumericUpDown).Value = Convert.ToInt32(val);
else
c.Text = val;
}
}
}
With the exception of NumericUpDown, the other types of controls are correctly populated. For the NumericUpDown, I only ever get the default -1 value. I've also tried to use decimal.Parse() and Convert.ToDecimal() instead of Convert.ToInt32(), but there is no change in the result.
The range of NumericUpDown had been set to -1 and 999.
It's not an answer, but a way to reduce a space for error searching, because it's a lot of things going on under the hood.
Can you please change your code to
foreach (Control c in myForm.Controls)
{
if (c is NumericUpDown)
(c as NumericUpDown).Value = 12;
else
c.Text = "12";
}
After this all controls should be set to 12. Can you please test it and get back with the observations.