Reputation: 1071
I have a few textboxes created dynamically , if i want to find the textboxes in the panels whats the best way to find it ?
i search online and some said through FindName we might be able to find our control but for that i need to give every of my textbox a name and in WPF , a name must come with letters not int even if i put int.ToString it will screw up . but if i put letters , it will be difficult for me to locate them by letters , numbers will be okay since i can start from 00 and +1 all the way but i can't do that .
I have textboxes dynamically created inside a dynamic created WrapPanel and i add the dynamic created WrapPanel inside a dynamic created stackPanel then i add that stackkpanel to a WrapPanel that i have created in the xaml side
if you ask me why i need so many panels because thats the only way i can make my look better because of the way i retrieve the information from db and display it .
Here is how my code looks like ( i cut it short because its too long):
private void PopulateQuestion(int activityID, int taskID)
{
IList<Model.questionhint> lstQuestionHints = qh.GetRecords(taskID, activityID);
StackPanel sp = new StackPanel();
foreach (Model.questionhint qhm in lstQuestionHints)
{
WrapPanel wp = new WrapPanel();
//some code ....
if (qhm.Option1.Trim().Length > 0 &&
qhm.Option2.Trim().Length > 0)
{
wp.Children.Add(space);
wp.Children.Add(tbox); //
}
sp.Children.Add(wp);// Adding wrap panel to stackpanel
} // end of for each loop.
WrapPanelTest.Children.Add(sp); // Adding stackpanel to WrapPanel ( in xaml)
}
WrapPanelTest is the panel i created in the xaml side . So now if i have a button , how should i find the textbox controls from those panels ?
i tried :
private void button1_Click(object sender, RoutedEventArgs e) // Check Button
{
int c = 0;
foreach (TextBox txtbox in WrapPanelTest.Children)
{
c++;
}
MessageBox.Show(c);
}
But it shows this error ( that points to TextBox txtbox in the foreach loop):
Upvotes: 0
Views: 4943
Reputation: 1117
I don't get your problem with naming the controls both with letters and numbers. Do it like this:
// This is the place where you dynamically create the textboxes, I skipped the part where u add it to wrap panel etc.
for( int numControls = 0; numControls < 30; numControls++)
{
Textbox box = new Texbox();
box.name = "textbox" + numControls.ToString();
}
And then u find it simply using
for(int numBoxes = 0;numBoxes < 30; numBoxes++)
{
Textbox box = WrapPanelTest.FindNyName("textbox" + numBoxes.ToString();
//operate on these
}
As in solution by Dick Schuerman: First, the helper class that will help us find children easier:
class ChildControls
{
private List<object> lstChildren;
public List<object> GetChildren(Visual p_vParent, int p_nLevel)
{
if (p_vParent == null)
{
throw new ArgumentNullException("Element {0} is null!", p_vParent.ToString());
}
this.lstChildren = new List<object>();
this.GetChildControls(p_vParent, p_nLevel);
return this.lstChildren;
}
private void GetChildControls(Visual p_vParent, int p_nLevel)
{
int nChildCount = VisualTreeHelper.GetChildrenCount(p_vParent);
for (int i = 0; i <= nChildCount - 1; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(p_vParent, i);
lstChildren.Add((object)v);
if (VisualTreeHelper.GetChildrenCount(v) > 0)
{
GetChildControls(v, p_nLevel + 1);
}
}
}
}
And you use it like this:
ChildControls ccChildren = new ChildControls();
foreach (object o in ccChildren.GetChildren(WrapPanelTest, 5))
{
if (o.GetType() == typeof(TextBox))
{
// Do something
}
}
The "5" in GetChildren means how many levels deep you want to dig. Example:
That would want you to set that property to 3.
Upvotes: 1
Reputation: 592
You should create a naming convention for those textboxes. For example:
int id=1;
tbox.Name="textbox_"+id.ToString();
and then create a function like:
TextBox getTextBoxById(int id)
{
TextBox myTextBox=WrapPanelTest.FindName("textbox_"+id.ToString()) as TextBox;
return myTextBox;
}
Upvotes: 1
Reputation: 947
In your loop you are trying to take all Controls in WrapPanelTest.Children as TextBox. try:
foreach (var control in WrapPanelTest.Children)
{
if(control.GetType() == typeof(TextBox))
c++;
}
Upvotes: 3