I made a custom FindControl function to find a control within all childs of one control I pass in parameter.
But I don't manage to have a hand over the button used to create a user ,in a CreateUserWizard Control.
I kept the default style, do anyone knows the name (ID) of this button?
I saw buttons like "ContinueButtonButton", "FinishButton", but they don't seem to be the one I am searching for, because I then have this line:
this.Form.DefaultButton = Tools.FindControl(CreateUserWizard1, "FinishButton").UniqueID;
And the create user event is not fired when I hit enter.
Any idea?
I finally found it, its ID is "StepNextButtonButton"
how about try something like
foreach (Control ctrl in this.form1.Controls)
{
if (ctrl.GetType() == typeof(Button) && (ctrl as Button).Text == "Button2")
{
this.form1.DefaultButton = ctrl.ID;
}
}
Related
I have tons of Buttons named like this x0y1
How do I access the variable name dynamically so I could loop all names by xiy1 or so.
in PHP it would be like ${"myString" . $randomvar}
I can't use a list or array because the the button already exist defined through the xaml
You can use:
var textbox =
this.Controls.OfType<TextBox>().Where(txb => txb.Name == "myString").FirstOrDefault();
This assumes you are in the context of your form (this.Controls).
And of course, don't forget to add using System.Linq;...
You can get all the textbox using this method
void AllTextBox(System.Windows.Forms.Control.ControlCollection ctrls)
{
foreach (Control ctrl in ctrls)
{
if (ctrl is TextBox)
{
if (ctrl.Name == "textBox1")
{
// do your stuf with textbox
}
}
}
}
You can create function that return control by name :
Control GetControlByName(string Name)
{
foreach(Control control in this.Controls)
if(c.Name == Name) return control ;
return null;
}
or Function with a specific control like that :
Button GetButtonByName(string Name)
{
foreach (Control c in this.Controls.OfType<Button>())
if (c.Name == Name) return c;
return null;
}
For wpf project...
Let's say you have a grid named MyGrid and there's lot of buttons on it.
You want to refer to the button named x0y1:
var btn = MyGrid.Children.OfType<Button>().Where(x=>x.Name=="x0y1");
Note: above code should work for flat structure (one level deep only).
You can achieve the same by using code provided in this thread: How can I find WPF controls by name or type?
Just call FindName("elementName"). FindName searches through all child elements of a FrameworkElement. To access any button by its name as string in a window, call the FindName() method of the window !
If your code is in a class inheriting from Window, just use:
Button button = (Button)FindName("xiy1");
If you write the code in a class not inheriting from Window but FrameworkElement, which is unlikely, use:
Window window = Window.GetWindow(this);
Button button = (Button)window.FindName("xiy1");
Check the MSDN documentation about Namescopes for more information about limitations.
I have listbox with Buttons. Every button have specific name -> button.Name = "button1".
I want to find specific button in listbox by Name.
I tried something like this:
if (listBox.Items.Contains(new Button().Name = "button2"))
{
MessageBox.Show("TEST");
}
But it doesnt work.
How to find it?
You need to check: 1. If the item is a Button 2. If its name is the same (use == not = as in your code)
foreach(var i in listBox.Items)
{
if (i is Button && (i as Button).Name=="button2")
{
MessageBox.Show("TEST");
}
}
If you have your ItemsControl item with you then you can iterate its Visualtree to reach to your button using VisualTreeHelper
Recursive find child is explained in this post How can I find WPF controls by name or type?
I'm good with Loading the control, using the LoadControl("~/vitrualPath"), so I have:
UserControl ctrl = (UserControl)LoadControl("~/controls/someControl.ascx");
this.Controls.Add(ctrl);
//plcCtrl.Controls.Add(ctrl);
The trouble is that I wish to then loop through all the controls in the usercontrol:
foreach (Label c in this.Controls.OfType<Label>())
{
// It's a label for an input
if (c.ID.Substring(0, 8) == "lblInput")
{
// Do some stuff with the control here
}
}
However, the added controls aren't part of this, but part of ctrl
Is there a way I can add the contents of the loaded control to this or a way to loop through both this and ctrl in one hit?
If you simply want to loop through both top-level labels and labels in ctrl, try this.Controls.Concat(ctrl.Controls).OfType<Label>() in your foreach loop.
You can also move your if into a LINQ Where call:
.Where(l => l.ID.Substring(0, 8) == "lblInput")
By using a recursive function you don't need to worry about controls within sub levels/ containers. Something like this should be OK (all you need to do is to pass the top level control along with the id substring that you are interested in). So if the conditions are met it will do whatever you have intended to do with the control and at any sub level.
public void ProcessControl(Control control, string ctrlName)
{
foreach (Label c in control.Controls.OfType<Label>())
{
// It's a label for an input
if (c.ID.Substring(0, 8) == ctrlName)
{
// Do some stuff with the control here
}
}
foreach (Control ctrl in control.Controls)
{
ProcessControl(ctrl, ctrlName);
}
}
You should write a recursive method that starts looping the controls in this.Controls and goes down the tree of controls. It will then also go in your user control and find your labels.
I don't think there is a way to loop through both like you want.
You can easily create a method that receives a Control as parameter and iterate though its controls. Something like this:
void Function(Control control)
{
foreach (Label c in control.Controls.OfType<Label>())
{
// It's a label for an input
if (c.ID.Substring(0, 8) == "lblInput")
{
// Do some stuff with the control here
}
}
}
You should be able to access the controls inside the user control by accessing the this.Controls[index].Controls I think, however it kind of depends what you are trying to achieve? Their might be a cleaner way of doing what you are trying to do?
I've got a web page where I am dynamically creating controls during Page_Load event (this is done so because I do not know how many controls I will need until session is active and certain variables are accessible)
I need to be able to loop through these controls to find Checkbox when a button click is processed. Looping through the Form.Controls does not appear to be sufficient. I would think that Request.Form might work but it does not appear to be accessible in my C# block?
What should code for Request.Form look like? OR
Has anyone done this before with dynamically created controls?
Any insight is appreciated.
Simplified Example from MSDN:
var myControl = FindControl("NameOfControl");
if(myControl != null)
{
//do something
}
else
{
//control not found
}
Hope this helps! ;)
Your controls will be accessible trough the Controls collection of their immediate parent. Unless you add them like Page.Form.Controls.Add (myControl);, you won't find it in Page.Form.Conttrols. If you add them to a place holder, you must find them in thePlaceHolder.Controls.
LinkButton myDynamicLinkButton = new myDynamicLinkButton ();
myDynamicLinkButton.ID = "lnkButton";
myPlaceHolder.Controls.Add (myDynamicLinkButton);
//........
LinkButton otherReferenceToMyLinkButton = myPlaceHolder.FindControl ("lnkButton");
As #David said in his comment, you should probably think about using a Repeater instead. It would probably simplify your case a lot.
Since the controls might be nested in other controls, you need to search recursively. You can use this method to find the control:
public Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
And you can implement it this way:
CheckBox check = FindControlRecursive(Page.Form, "CheckBox1");
You should have access to Request["xyz"] anywhere in your aspx.cs code. You can either find control as described above and read it's value or do so directly from Request using the Control.UniqueID property. For example if it's a checkbox that's within the repeater then the UniqueID would look like dtgData$ctl02$txtAmount
Thanks for the insight guys. I kind of took the discussion and ran with it and found my solution that worked best for me.
foreach(String chk in Request.Form)
{
if (chk.Contains("chkRemove"))
{
int idxFormat = chk.LastIndexOf("chkRemove");
objectname = chk.Substring(idxFormat);
}
}
Turned out really all I needed was the name. The string contained a number at the end which was needed to determine a position of datatable items. Thanks for the advice!
I have seen many others with similar problems but I cannot find the flaw in my logic here. Any help would be greatly appreciated.
I have a Panel which I have added numerous label and textbox controls to, ie:
myPanel.Controls.Add(txtBox);
These controls are created and added in a method called previous to the iteration method.
I want to iterate through each textbox and use its Text property as a parameter in another method but I am not having any luck. Here is my attempt to iterate:
public void updateQuestions()
{
try
{
foreach (Control c in editQuestionsPanel.Controls)
{
if (c is TextBox)
{
TextBox questionTextBox = (TextBox)c;
string question = questionTextBox.Text;
writeNewQuestionToTblQuestions(question);
}
}
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
The problem I am having is that the controls are not in the Panel when I arrive at this updateQuestions() method. Here is the process involved:
A commandButton is clicked and the questions are read from a DB, for each question a method is called which adds 2 labels and a textbox to editQuestionsPanel.Controls. This panel is inside a PlaceHolder which is then made visible.
When a button inside the PlaceHolder is clicked, the updateQuestions() method is called and the editQuestionsPanel.Controls.Count = 1. As there are approx 12 questions in the DB it should be around 36. The one control inside the Panel is of type:
System.Web.UI.LiteralControl
It contains no controls.
I am sure that somwhere in the lifecycle the Panel's controls are being cleared but I do not know how to step thru the life cycle. I have a Page_load method which is called as soon as a button is clicked but once the button which calls updateQuestions() is clicked the editQuestionsPanel.Controls.Count is already back to 1 so it must be cleared before this but I do not know how to correct this...
Any help you can give to help me solve this would be greatly appreciated - its killing me!
This selects from collection controls only that which are of type TextBox.
(the same as control is TextBox or (control as TextBox) != null)
If controls are contained in editQuestionsPanel.Controls:
using System.Linq;
IEnumerable<TextBox> textBoxes = editQuestionsPanel.Controls.OfType<TextBox>();
foreach (TextBox textBox in textBoxes)
{
// do stuff
}
To select all child controls use next extension method:
public static IEnumerable<T> GetChildControls<T>(this Control control) where T : Control
{
var children = control.Controls.OfType<T>();
return children.SelectMany(c => GetChildControls<T>(c)).Concat(children);
}
Using:
IEnumerable<TextBox> textBoxes = editQuestionsPanel.GetChildControls<TextBox>();
When you add controls dynamically, you need to do that on every request - asp.net doesn't do that for you!
Add the controls in the Init or Load phase, then they will get populated with the postback values.
A frequently made mistake: Container.Controls only contains the first level child controls in this container. That is: TextBox1 in PanelA, PanelA in PanelB, you can't get TextBox1 in PanelB.Controls.
My solution is to write an extension method:
public static IEnumerable<Control> AllControls(this Control ctl)
{
List<Control> collection = new List<Control>();
if (ctl.HasControls())
{
foreach (Control c in ctl.Controls)
{
collection.Add(c);
collection = collection.Concat(c.AllControls()).ToList();
}
}
return collection;
}
Now TextBox1 is in PanelB.AllControls(). To filter all controls with type, using PanelB.AllControls().OfType<TextBox>()
If the other answers don't help, try doing your code but add recursivity. Your code would not work if it's editQuestionsPanel => Panel => Textbox
You can do something like this instead:
var questions = from tb in editQuestionsPanel.Controls.OfType<TextBox>()
select tb.Text;
foreach(var question in questions)
{
writeNewQuestionToTblQuestions(question);
}
Try this
int Count = 0;
foreach (Control ctr in Panel1.Controls)
{
if (ctr is TextBox)
Count++;
}