I have added a GroupBox to my main Grid and am populating it dynamically with controls. I need to get a specific textbox within that GroupBox in an onClick event. I am able to loop through the GroupBox and fine, like this...
foreach (Control ctl in ((Grid)gpMccEngineProperties.Content).Children)
{
if (ctl.GetType() == typeof(TextBox))
{
TextBox textbox = (TextBox)ctl;
PropertyValue propertyValue = new PropertyValue();
propertyValue.Value = textbox.Text;
}
}
... but if i just want to access a specific TextBox i keep coming back with a null value. here is how i'm trying to get it...
TextBox txt = ((Grid)gpMccEngineProperties.Content).Children.OfType<TextBox>().Where(t => t.Name == "PropertyId_9") as TextBox;
... where PropertyId_9 is the name of a textbox that i added dynamically to the GroupBox. Any idea how i get that textbox so i can get it's value?
Thanks!
You're using the wrong Linq method. That code returns an IEnumerable of TextBoxes, not just the TextBox. Use Single or SingleOrDefault instead of Where:
TextBox txt = ((Grid)gpMccEngineProperties.Content).Children.OfType<TextBox>().Single(t => t.Name == "PropertyId_9");
Related
I am using a Grid to hold text boxes and combo boxes. I want to get the selected item from the combo boxes and the text from the text boxes. Is there a way to do this without having to cast the UIElement as Combo or Text box. Below is how I am currently doing this.
foreach (UIElement field in _fields)
{
string val="";
if (field is TextBox)
{
TextBox bx = field as TextBox;
val=bx.Text;
}
else if (field is ComboBox)
{
ComboBox bx = field as ComboBox;
val=bx.SelectedItem.ToString();
}
}
Thanks
The best way to access data in WPF is to use databinding or even use MVVM. A quick and dirty way could be to give your elements a name by assigning x:Name in your XAML. Then you do not need to cast the elements in code behind.
On my Visual C# Form application, I have a combobox inside a groupbox to help organize / look neat. However, once I put the combobox inside the groupbox, I am no longer able to find it by looping through all of the controls on my form.
For example, if I run this code with the Combobox inside the Groupbox I get a different result than if its outside the group box:
foreach (Control contrl in this.Controls)
{
richTextBox1.Text += "\n" + contrl.Name;
}
If the combobox is inside the groupbox, it won't find it.
I also noticed in the Form1.Designer.cs file that whenever I add the combobox inside the groupbox, the following line of code appears to the groupbox:
this.groupBox4.Controls.Add(this.myComboBox);
..
this.groupBox4.Location = new System.Drawing.Point(23, 39);
this.groupBox4.Name = "groupBox4";
... etc...
And this line will be removed:
this.Controls.Add(this.myComboBox);
If I try to edit it manually, it automatically switches back once I move the combobox back inside the groupbox.
Any help would be appreciated! Thanks!
Brian
As you said, you added combo box to group box, so it is added to Controls collection of group box and the designer generates this code:
this.groupBox4.Controls.Add(this.myComboBox);
So if you want to find the combo box programmatically, you can use this options:
Why not simply use: this.myComboBox ?
Use var combo = (ComboBox)this.Controls.Find("myComboBox", true).FirstOrDefault();
Use var combo = (ComboBox)this.groupBox4.Controls["myComboBox"]
Also if you want too loop, you should loop over this.groupBox4.Controls using:
foreach(Control c in this.groupBox4.Controls) {/*use c here */}
this.groupBox4.Controls.Cast<Control>().ToList().ForEach(c=>{/*use c here */})
Just like the Form object, the Group object can hold a collection of controls. You would need to iterate through the Group control's controls collection.
One more idea for getting at all or one ComboBox in a GroupBox, in this case groupBox1. Granted Resa's suggestion for using Find with FirstOrDefault would be best to access one combobox.
List<ComboBox> ComboBoxes = groupBox1
.Controls
.OfType<ComboBox>()
.Select((control) => control).ToList();
foreach (var c in ComboBoxes)
{
Console.WriteLine(c.Name);
}
string nameOfComboBox = "comboBox1";
ComboBox findThis = groupBox1
.Controls
.OfType<ComboBox>()
.Select((control) => control)
.Where(control => control.Name == nameOfComboBox)
.FirstOrDefault();
if (findThis != null)
{
Console.WriteLine(findThis.Text);
}
else
{
Console.WriteLine("Not found");
}
You can use the ControlCollections Find Method, it has a parameter that will search the parent and its Children for your control.
ComboBox temp;
Control[] myControls = Controls.Find("myComboBox", true); //note the method returns an array of matches
if (myControls.Length > 0) //Check that it returned a match
temp = (ComboBox)myControls[0]; //use it
I try to get data from the textboxex that is related to the ckeckboxex in the checkboxlist ..
in order to calculate the value of the selected box
this is my code :
foreach (ListItem item in listOthers.Items)
{
if (item.Selected)
{
sum += Convert.ToInt32(TextBox1.Text);//textbox of selected checkbox
}
}
lblSum.Text = sum.ToString();
What do I need to do to get the value of the textbox related to the checkbox?
Based on your comments, you have a CheckBoxList with a fixed size of 10 items and along with that 10 Textboxes (named TextBox1, TextBox2 and so on). The users marks some CheckBoxes and also enters a text into the corresponding Textboxes. You want to convert the Text of the Textboxes to an integer and calculate the sum of the marked entries.
You need to dynamically access the Textboxes by calling FindControl:
var index = 0;
foreach (ListItem item in listOthers.Items)
{
index++; // Increase here as the Textbox numbers start at 1
if (item.Selected)
{
var txt = FindControl("TextBox" + index.ToString()) as TextBox;
if (txt != null)
sum += Convert.ToInt32(txt.Text); //text of selected Checkbox
}
}
lblSum.Text = sum.ToString();
Please note that it is important to call FindControl on the container of the Textboxes. The call in the sample works if the Textboxes are located directly on the page. If they are located on a Panel named Panel1, you'd have to call:
var txt = Panel1.Findcontrol("TextBox" + index.ToString()) as Textbox;
An alternative to using a CheckBoxList that is prepared for variable sizes by design and having a fixed list of 10 TextBoxes next to it, would be to create a Repeater with a CheckBox and a TextBox in its ItemTemplate. Downsize is that you'd have to create some DTOs for DataBinding and also had to use some more dynamic control resolution (both for the CheckBox and the TextBox ).
I have a form with few radio buttons that suppose to represent different integer values.
1) Is there a built-in way to put a value "behind" a radio button?
an example:
RadioButton rad = new RadioButton();
rad.Value = 5; // This is what im trying to achieve.
2) I have few RadioButtons that are logically related to each other and i want to know which one was selected (without putting them inside a GroupBox control) and get the selected value for that RadioButton.
note: I would like to "Iterate" these 3 controls and get the selected one instead of doing 3 IF statements.
an example:
RadioButton radColor1 = new RadioButton();
RadioButton radColor2 = new RadioButton();
RadioButton radColor3 = new RadioButton();
// ...
RadioButton radSelected = ?? // Get selected Radio Button from the 3 above.
//here i can get to radSelected.Value
If you want to assign an arbitrary value to the control, use its Tag property:
radColor1.Tag = 5;
But why can't you simply use the Checked property?
if (radColor1.Checked)
//do something
if (radColor2.Checked)
//do something else
//...however many more you need to check
EDIT: iteration...
foreach (Control c in this.Controls)
{
if (c is RadioButton)
{
if (((RadioButton)c).Checked)
//do something
}
}
put these radio btns in a stackPanel and iterate to check If Checked & than use tag property to store the values of each radio button
foreach(var child in stack.Children)
{
if((child as RadioButton).Checked == true)
var value = (child as RadioButton).tag;
}
RadioButton radSelected = (from RadioButton rb in this.Controls
where rb.Checked
select rb).SingleOrDefault();
How does one target a control by its Type?
I have a Control collection "TargetControls"
List<Control> TargetControls = new List<Control>();
foreach (Control page in Tabs.TabPages)
{
foreach (Control SubControl in page.Controls)
TargetControls.Add(SubControl);
}
foreach (Control ctrl in TargetControls)...
I need to access each existing control (combobox,checkbox,etc.) by its specific Type with access to its specific properties. The way I'm doing it now only gives me access to generic control properties.
Can't I specify something like...
Combobox current = new ComboBox["Name"]; /// Referencing an Instance of ComboBox 'Name'
and then be given access to it's (already existing) properties for manipulation?
You can use the is keyword to check for a specific type of the control. If the control is of a specific type, do a typecast.
foreach (Control SubControl in page.Controls)
{
if (SubControl is TextBox)
{
TextBox ctl = SubControl as TextBox;
}
}
You can use the OfType<T> extension method:
foreach (var textBox = page.Controls.OfType<TextBox>()) {
// ...
}
You'll need to cast the control to the right type of control before accessing any specific parameters.
ComboBox c = ctrl as ComboBox;
If (c != null)
{
//do some combo box specific stuff here
}
Also you could add the controls to a generic dictionary<string, control> and use the control.name as the key there.
Ex.
Dictionary<string, Control> TargetControls = new Dictionary<string, Control>();
Assuming you can use LINQ, and you're looking for (say) a Button control:
var button = (from Control c in TargetControls
where c.Name == "myName" && c is Button
select c
).FirstOrDefault();
...which will give you the first Button control named "myName" in your collection, or null if there are no such items present.
What about the Find method?
Button btn = (Button)this.Controls.Find("button1", true)[0];
btn.Text = "New Text";
In order to access a control's specific properties, you have to cast it to its appropriate type. For example, if the item in your TargetControls collection was a textbox, you would have to say ((TextBox)TargetControls[0]).Text = 'blah';
If you don't know the types ahead of time, you can use reflection to access the properties, but I'd need to have a better example of what you're trying to do first...