I have on my winform an usercontrol and I create multiple usercontrols at every button click(at runtime).My usercontrol has an textbox. Also,on winform I have a simple textbox . I want ,when I select an usercontrol,the text from the dynamical textbox to appear also in the simple textbox. In my code it says that the textbox from usercontrol is not in the current context. My code:
private void Gettext()
{
int i = 0;
Control[] txt = Controls.Find("txtBox" + i.ToString(), true);//here I search for the dynamical textbox
foreach (Control c in panel1.Controls)
{
if (c is UserControl1)
{
if (((UserControl)c).Selected)
txtSimple.Text= txtBox[0].Text ;
}
i++;
}
I don't know if I understood your question correctly:
The structure of your form looks something like this:
Your form has a Panel panel1 that has many UserControls of the type UserControl1, created on runtime, and one TextBox txtSimple.
Every UserControl has a TextBox named ["txtBox" + i]
on select you want to synchronize texts of txtSimple and TextBox of selected UserControl
Then:
int i=0;
foreach (Control c in panel1.Controls)
{
if (c is UserControl1)
{
if (((UserControl)c).Selected)
{
TextBox dynTxtBox = (TextBox)c.Controls["txtBox" + i];
txtSimple.Text= dynTxtBoxe.Text;
}
}
i++;
}
If you can't find your TextBox this way, it probably means that its name is not set correctly.
Also, if you have only one TextBox on your UserControl then there's normally no need to name it in such a specific way (I mean from your code I assumed you have txtBox0 on your first user control, txtBox1 on your second and so on). You can simply name it "txtBox", then access it like this:
txtSimple.Text = selectedUserControl.Controls["txtBox"].Text;
Control names are unique in a Controls collection of a Control, UserControl and Form.
Control[] txt = ...
txtSimple.Text= txtBox[0].Text ;
May be replace txtBox[0].Text to txt[0].Text ?
Well for a start
Control[] txt = Panel1.Controls.Find("txtBox" + i.ToString(), true)
Then
foreach (Control c in txt) // txt???
{
UserControl1 uc = c as UserControl1;
if (uc != null)
{
if (uc.Selected) txtSimple.Text= uc.Text ;
}
}
Then if if you are are testing for UserControl1, you should also cast to UserControl1 not UserControl
UserControl1 is an extremely bad name for it..
I'm not even going to mention the assumption that all controls have a name starting with txtBox and that no other controls have...
And the entire thing dies if more than one control is selected when it runs.
you need to have a Selected event on your UserControl.
//in UserControl
public event EventHandler Selected;
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
if(Selected!=null)
Selected(this,null);
}
now subscribe to Selected event of UserControl when you dynamically create it. Like this:
UserControl control = new UserControl();
control.Selected += myControl_Selected;
private void myControl_Selected(object sender, EventArgs e)
{
UserControl control = (UserControl)sender;
textBox2.Text = control.Text;
}
I hope this helps.
Related
I have two Buttons in my Form and two TextBoxes inside a TabControl.
I'm not sure how I can save to the Clipboard the text of the TextBoxes using the Buttons.
To do this, we tried to assigned the same AccessibleName to the controls.
I worked on the code but I do not know how to access the TabPages of the TabControl.
Finally, does someone know of a better way to do that?
public partial class Form1 : Form
{
private void SaveNumBot(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
{
if (c.AccessibleName == ((Control)sender).AccessibleName)
{
if (c is TextBox)
{
Clipboard.SetDataObject(c.Text);
}
}
}
}
Use pattern matching:
if (c is TextBox textBox)
{
Clipboard.SetDataObject(textBox.Text);
}
You could modify your foreach loop:
foreach(TabPage tabPage in yourTabControl.Controls)
{
foreach (TextBox textBox in tabPage.Controls.OfType<TextBox>().Where(x=>x.AccessibleName == ((Control)sender).AccessibleName))
{
Clipboard.SetDataObject(textBox.Text);
}
}
with this loop you only search for Controls which are from the type Textbox.
Use OfType method to avoid InvalidCastExceptions.
If you have other Controls which inherit from TextBox in your Form I would recommend to add the line x.GetType()==typeof(TextBox) to the Where() method.
With the Where() method we only choose the items which have to same AccessibleName like our sender.
But if you have more textboxes with the same AccessibleName, this loop will run through all items and only choose the last text.
In this case i would recommend:
Clipboard.SetDataObject(yourTabPage.Controls.OfType<TextBox>()
.Where(x=>x.AccessibleName ==((Control)sender).AccessibleName))
.ToList()
.FirstOrDefault().Text);
Here we are going to have 1 text from the first texbox found in the Control. you could also select the Last()entry.
I have Window Application and have one popup dialog(Form) with some input controls(TextBox, ComboBox) and other controls like PictureBox, Label. My form have two Mode 1) Add or Edit mode 2) View Mode. In View Mode user can only see details and also can copy input value(e.g user can copy TextBox value).
If form mode is View then I want to set read only property to true for all Input controls of form with Iterate One by one control of my Forma(using for each). But I don't have idea about How can I know particular control is a Input type control. System.Windows.Forms.Control does not have ReadOnly property. I found that I can use Enable property for my solution but problem is that user can not copy text value from TextBox if Enable set to false.
Can any one help me How can I know particular control is a Input type Control.
Thanks.
System.Windows.forms.clipboard.clear();
try this.
This code may help you:
foreach(Control ctl in form.Controls)
{
if (ctl is TextBox)
{ }
if (ctl is CheckBox)
{ }
if (ctl is ComboBox)
{ }
/* etc */
}
I usually cycle through all the controls on the form and then assess each by type. A little bit of work to start with but once in place you can add more controls without having to worry about setting them individually.
foreach (Control c in formMain.Controls)
{
if(c.GetType()==typeof(ComboBox))
{
ComboBox cb = (ComboBox) c;
//do something
}
else if(c.GetType()==typeof(TextBox))
{
TextBox t = (TextBox) c;
t.ReadOnly = true;
}
}
I also use the same process for setting generic event handlers e.g. saving a control value to settings on text change. So if you create settings with the same name as your control you can put something like this in the event handler ...
private void TextBoxTextchanged(object sender, EventArgs e)
{
TextBox t = (TextBox) sender;
Settings.Default[t.Name] = t.Text;
Settings.Default.Save();
}
I think TextBoxBase could be the input type Control:
foreach (TextBoxBase txt in this.Controls.OfType<TextBoxBase>())
{
txt.ReadOnly = true;
}
Dynamic 10 textbox create all text value how to access in button click event in windows form application
The most simple way to do this is create a list to keep textbox's references.
List<TextBox> textBoxList = new List<TextBox>();
for (int index = 0; index < 10; index++)
{
var textBox = new TextBox();
textBoxList.Add(textBox);
// do the rest of work.
}
You can get its reference inside click event handler like below.
// inside button's click event.
foreach (var textBox in textBoxList)
{
// get text and do the work.
}
The simplest way assign something to the tag property that help you to identify the textbox. For example a number or an enum value.
Then casting the click event sender to a text box and look in the tag which one is it.
TextBox txt = new TextBox();
txt.Text = "ABC";
this.Controls.Add(txt);
private void btnOk_Click(object sender, EventArgs e)
{
foreach (Control ctl in this.Controls)
{
if (ctl.GetType() == typeof(TextBox))
MessageBox.Show(ctl.Text);
}
}
You can create an array of 10 text boxes dynamically place all the text boxes
You can access the text value based on the array values (0-9) of it
If I have multiple TextBoxes and other text insertion controls and I want to create some buttons that insert special characters into whichever TextBox is in focus, what is the best control for this and what properties should be set?
Requirements for the buttons:
Buttons do not steal focus when clicked.
Buttons can insert text (e.g. special characters) into any control that accepts keyboard input.
The cursor should move as if the user had entered the text on the keyboard.
If #2 is not possible, it will suffice to limit the controls to only TextBoxes.
NOTE: I do not want to make the buttons unfocusable, only such that they do not steal focus when clicked.
I'm not aware of any button that is not stealing focus when it is clicked, but in button click event handle you can return focus to previous owner. If I had to implement this I'd create an behavior that is attached to parent panel of all special textboxes and all buttons that are to insert some text.
<StackPanel>
<i:Interaction.Behaviors>
<local:TextBoxStateTracker/>
</i:Interaction.Behaviors>
<TextBox />
<Button Content="description" Tag="?" />
</StackPanel>
For sample simplicity I've put text that is to be inserted to textbox in Tag property.
public class TextBoxStateTracker : Behavior<Panel>
{
private TextBox _previouslySelectedElement;
private int _selectionStart;
private int _selectionLength;
protected override void OnAttached()
{
//after control and all its children are created find textboxes and buttons
AssociatedObject.Initialized += (x, y) =>
{
var textBoxElements = FindChildren<TextBox>(AssociatedObject);
foreach (var item in textBoxElements)
{
item.LostFocus += new RoutedEventHandler(item_LostFocus);
}
var buttons = FindChildren<Button>(AssociatedObject);
foreach (var item in buttons)
{
item.Click += new RoutedEventHandler(item_Click);
}
};
}
private void item_Click(object sender, RoutedEventArgs e)
{
if (_previouslySelectedElement == null) return;
//simply replace selected text in previously focused textbox with whatever is in tag property
var button = (Button)sender;
var textToInsert = (string)button.Tag;
_previouslySelectedElement.Text = _previouslySelectedElement.Text.Substring(0, _selectionStart)
+ textToInsert +
_previouslySelectedElement.Text.Substring(_selectionStart + _selectionLength);
_previouslySelectedElement.Focus();
_previouslySelectedElement.SelectionStart = _selectionStart + textToInsert.Length;
}
private void item_LostFocus(object sender, RoutedEventArgs e)
{
//this method is fired when textboxes loose their focus note that this
//might not be fired by button click
_previouslySelectedElement = (TextBox)sender;
_selectionStart = _previouslySelectedElement.SelectionStart;
_selectionLength = _previouslySelectedElement.SelectionLength;
}
public List<TChild> FindChildren<TChild>(DependencyObject d)
where TChild : DependencyObject
{
List<TChild> children = new List<TChild>();
int childCount = VisualTreeHelper.GetChildrenCount(d);
for (int i = 0; i < childCount; i++)
{
DependencyObject o = VisualTreeHelper.GetChild(d, i);
if (o is TChild)
children.Add(o as TChild);
foreach (TChild c in FindChildren<TChild>(o))
children.Add(c);
}
return children;
}
}
This does more or less what you described but it is far from perfect I think it is enough to get you started.
You need to do override the template of a Label and a TextBox.
requirements 1 and 2 - can be done inside the template for the Label which will act as a button.
requirement 3 - can be done inside the the template for the Textbox.
It's not easy...
you might need to learn alot of WPF styling, XAML and overriding the Control Template. maybe even creating a custom control.
I am building a page with asp.net. I have a form with a table that contains TextBoxes and a submit button. When the form is submitted, I want to grab all the text that was entered into the TextBoxes and operate on them. To do this, I have the following method:
protected void Button1_Click(object sender, EventArgs e)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (Control c in this.Controls)
{
if (c.GetType().Name == "TextBox")
{
TextBox tb = (TextBox)c;
sb.AppendLine(tb.Text);
}
}
Label1.Text = sb.ToString();
}
The problem with this is that the controls apparently doesn't include any of my textboxes. When I iterate through the controls and print out their names, the only one I get is "site_master." (I also tried Controls and Page.Controls instead of this.Controls).
Is there something wrong with my iterator? Is there another way in which I could iterate through all of the textboxes in the table or page? What is the best way to accomplish this?
Would it be too much to build a List<Textbox>, given you know all your textbox controls?
List<Textbox> txtBoxes = new List<Textbox>();
txtBoxes.Add(tb1);
txtBoxes.Add(tb2);
//etc..
Then you have a nice list to work with
If I knew the controls were all in a given containing control, I would simply poll the controls of that control. For example, this.Form.Controls. However, if they could be nested within other child controls, then you could recursively explore the depths from a common outer container.
private IEnumerable<T> FindControls<T>(Control parent) where T : Control
{
foreach (Control control in parent.Controls)
{
if (control is T)
yield return (T)control;
foreach (T item in FindControls<T>(control))
yield return item;
}
}
So this would allow you to retrieve all TextBox children.
List<TextBox> textBoxes = this.FindControls<TextBox>(this).ToList();
string output = string.Join(",", textBoxes.Select(tb => tb.Text));
I'm going to assume that you are using web forms ASP.NET. Typically you declare your controls on the aspx page using something similar to
<asp:TextBox ID="someId" runat="server/>
If you have done this then in your code behind your should just be able to reference the variable someId and the property Text to get/set the text in the control.
If you are building the controls dynamically on the server you should be able to stick them in a list and iterate through it. Make sure you are creating the controls and adding them to the table during the correct part of the page lifecycle. When you add them to a cell in the table you could also keep a reference to the control in a list and just enumerate through that list in your event handler.
Maybe something along the lines of (I didn't compile this so there are probably issues):
public class MyPage: Page
{
private List<TextBox> TxtBoxes = new List<TextBox>();
//registered for the preinit on the page....
public void PreInitHandler(object sender, EventArgs e)
{
for(var i = 0; i < 2; i++)
{
var txtBox = new TextBox{Id = textBox+i};
//...add cell to table and add txtBox Control
TxtBoxes.Add(txtBox);
}
}
}