I have multiple XAML TextBoxes, each of which manipulate a corresponding value in an array, when the value in the TextBox is changed, using a C# method which dynamically checks which TextBox has called the method.
<TextBox x:Name="_0_0" TextChanged="_x_y_TextChanged"/>
<TextBox x:Name="_0_1" TextChanged="_x_y_TextChanged"/>
<TextBox x:Name="_0_2" TextChanged="_x_y_TextChanged"/>
// And so on.....
each of which manipulate a corresponding value in an array, when the value in the TextBox is changed, using a C# method which dynamically checks which TextBox has called the method.
private void _x_y_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox current = (TextBox)sender;
string currentname = current.Name;
string rowstring = currentname.Substring(1, 1);
string columnstring = currentname.Substring(3, 1);
int row = Convert.ToInt32(rowstring);
int column = Convert.ToInt32(columnstring);
// I've then detected the name of the textbox which has called it...
So this information can be used to dynamically store information from a TextBox in a corresponding array index - or whatever you want to do with it...
My question however, is:
How can I create a method which uses index locations in my array, to call the relevant TextBox and update its text?
Use FindName(string) to find the text box by name as follows (where container is a control that contains all of the text boxes):
private void UpdateTextBox(int row, int column, string text)
{
TextBox textBox = container.FindName("_" + row + "_" + column) as TextBox;
if(textbox != null)
{
textbox.Text = text;
}
}
There are two ways you might go:
If you have a lot of data to manage, or if you can't predict the length of the array, it would be better to bind to a collection instead of manually poking data into and out of an array. If you create a class derived from ObservableCollection instead of using an array the data <> ui relationship is pretty trivial.
if you really need to do this manually, maybe it would be better to stick the index into the 'tag' field of your text boxes. You could (a) see it clearly in your xaml, (b) parse it easily and (c) if you used a variation on the formula here:
Find all controls in WPF Window by type
you could iterate over the textboxes in window and find the right one by looking at its tag index:
foreach (TextBox t in FindVisualChildren<TextBox>(this))
{
if ((int) t.Tag) == my_index )
{
t.Text = "my_text_goes_here";
}
}
I would go in the direction of the answer I gave on this question:
form anchor/dock
In short, I would create a class that holds the actual values and then create a collection that holds information classes.
Then I would not use the event "TextChanged" on the TextBoxes, rather "sniff" for changes on the Dependency Property used to hold the text. This can easily be done in the Dependency Property.
Last, I would use an ItemsControl or ItemsPresenter to show the controls. Number of controls will follow number of items in the collection.
I suggest using MVVM pattern, data template, and ItemsControl for handling this problem effectively.
Related
I have two sets of items in two listboxes. listBox1 has items listed out like:
red
yellow
blue
and listBox2 has items like:
1
2
3
There are many more than three items per listbox. I also have two textboxes, textBox1 and textBox2. I have been successful in having a random item from listBox1 show up in textBox1, and I am now trying to check, with a button, if the text in textBox2, manually entered by the user, matched the corresponding items in listbox2.
So far, I have:
Random random = new Random();
int a; int n;
private void button1_Click(object sender, EventArgs e)
{
n = listBox1.Items.Count;
a = random.Next(n);
textBox1.Text = listBox1.Items[a].ToString();
}
private void button2_Click(object sender, EventArgs e)
{
//unsure
}
I am trying to have button2 check for whether or not textBox2 has typed into it the correctly corresponding item in listBox2 and display a message of some sort if it is correct. I'm a beginner at this, but I think I adequately grasp how to if/else the message if I can get the code leading up to it correct.
How do I check for such a link?
Assuming it is a WPF application and you populated the list box with strings then you can get the Text property value of the text box and the Items property value of the list box. The Items property will returns an ItemCollection and you can use the Contains method like so: listBox2.Items.Contains(textBox2.Text) to return true or false.
Similar approach would work for a WinForms application also, just that the classes from the .NET framework that you use will be different, for example the list box Items property in this case returns a ListBox.ObjectCollection. Both of these libraries provide the relevant Text, Items and Contains properties/methods.
In both cases the MessageBox.Show() method can be used to display the appropriate method.
You will want to compare them with the if statement
if (thing1 == thing2) {
//do things
}
So we know thing1 is the currently selected item in the listbox2, and thing2 is the text of textbox2.
You can grab the text in both of them via text
if (textbox2.Text == listbox2.Text) {
//do stuff
}
If you want to check if the entered text is in any of the options, you'll want to use .contains
if (listbox2.items.contains(textbox2.Text) {
//do stuff
}
Hello i am working on some personal project,
I have lots of comboboxes in my project, which names are combobox1,combobox2 etc..
What i am trying to do is, getting combobox.text values respectively and do some work according to this.
Here is my code below;
for (i = 1; i <= geneList.Length; i++)
{
baserequest = "/" + comboBox[i].Text + ".docx";
sources.Add(new Source(new WmlDocument(basesource + geneList[i] + baserequest), false));
baserequest="";
DocumentBuilder.BuildDocument(sources, Path.Combine(tempDi.FullName, "Output.docx"));
}
so that actually not work. I searched but i think i missearching something because all i can get is about iterating through items, but what i want to do is exactly this;
comboBox[i].Text
Thank you very much.
If your comboboxes are named comboBox1, comboBox2 .... then you can't refer to comboBox2 using a syntax like comboBox[2]. This syntax means .. give me the third combobox stored in an array of comboboxes (and that should contain at least 3 elements)
So if you really want to use this syntax you need to create that combobox array somewhere in your code. After the call to InitializeComponent for example
public class Form1: Form
{
// declare the array as a global variable
private ComboBox[] combobox;
public Form1()
{
// Create and initialize all the elements of your form
// according to the properties set in the WinForms Designer
InitializeComponent();
// Choose all the individual comboboxes that you want to use
// inside your loops in the remainder of your code
combobox = new ComboBox[] { comboBox1, comboBox2, comboBox3 };
}
// all the code of your Form1 follows.....
}
A final note: You use a different array to create your loops. This array is named geneList and it should be kept in sync with the combobox array. Meaning the two arrays should have the same number of elements otherwise (if the geneList array is bigger than the combobox one you will get an ArgumentOutOfRangeException). Also array indexing start at index 0 not 1 so the usual loop is created with this syntax
for (i = 0; i < geneList.Length; i++)
Otherwise if you start from 1, as you do now, you skip the first element in the array and the last loop searches for an element that doesn't exist.
I have multiple text blocks I want to compare the text values of with whatever the current random value is in my array, so I can "gray out" the text block when it gets "opened".
This code works for 1 text block, but I was wondering how I could do it for all 26 of my blocks w/o having to type out each one? Is there a way I can reference all my blocks, kind of like using the same click event for all my buttons?
if (money[turns]==Convert.ToInt32(tb0.Text))
{
tb0.Foreground = Brushes.Gray;
}
As addition to Alexei, if you want only compare specific TextBlock, first you can insert your TextBlock into a List
List<TextBlock> listTextBlock = new List<TextBlock>();
list.Add(tb0);
list.Add(tb1);
... so you just using loop to check each TextBlock.
foreach(TextBlock item in listTextBlock)
{
if (money[turns]==Convert.ToInt32(item.Text))
{
item.Foreground = Brushes.Gray;
}
}
If Windows.Forms you can iterate through all your controls of type TextBox and compare your text to the one in each TextBox. The code should like this:
bool exists = GetAll(this, typeof(TextBox)).Any(t => t.Text.Equals(yourText));
As already suggested, it would be better to use databinding and do the search in your objects, rather than into your interface.
I'm trying to create my custom control for:
(numeric updown)
I want to use the value in the control to offset the position of a certain element (which is set using "targetElement" on the control's properties). But since settings are stored as strings, I only have the string value.
For example: If the user sets "targetElement" as label1, I want to offset the position of label1 using BobbyUpDown1.targetElement.Location.x, but since targetElement is storing a string of the ID of the element, it won't let me do that.
How can I grab the reference to the label1 (that the user input) from the targetElement property?
Do this:
Control c = this.Controls["YourLabelName"];
if (c != null)
{
c.Location = new Point(newXLocationForYourLabel, c.Location.Y);
}
Here this is the Form
A user has provided me with an Excel document that has textboxes in a few of the cells. I have the usual setup code to load the Excel application, get the worksheet, and then start iterating the used range. When I try to get the value of the cell that contains the textbox, the value is null.
foreach (Range row in usedRange.Rows) {
object[,] valueArray = (object[,])row.get_Value(XlRangeValueDataType.xlRangeValueDefault);
var value = valueArray[1,10]; // This is null for textbox cells
}
Is there a special method I should use to get the value of the textbox that appears in an Excel worksheet?
Edit with fix and explanation
Stewbob's suggestion of iterating the shapes got me in the right direction. But using the following code, I was getting null exceptions:
for (int i=1; i<shapes.Count;i++){
var item = shapes.Range[i].Item(1);
string myString = item.TextFrame2.TextRange.Characters.Text.ToString();
}
After looking at the object in Quickwatch, I noticed something odd about the shape. It was of type msoOLEControlObject. It turns out the values on this Excel document are cut and pasted into Excel from a webpage. Excel was not creating textboxes but OLE boxes. The OLE box did have a 'Value' property so I could access the textboxes value as such:
var shapes = ws.Shapes;
for (int i=1; i<shapes.Count;i++){
var item = shapes.Range[i].Item(1);
var myText = item.OLEFormat.Object;
if (myText.Object != null) {
if (myText.Object.Value != null) {
Console.WriteLine(myText.Object.Value.ToString());
}
}
}
So make sure if you are dealing with pasted objects that you check the value property and not the TextRange property.
If you know the name of the Text Box, you can reference it this way:
ActiveSheet.Shapes.Range(Array("TextBox 1")).Select
If you don't know the name, you can use ActiveSheet.Shapes to iterate through all the shapes on the worksheet.
Getting to the actual text in the TextBox is not very straightforward in VBA. The following code iterates through all the Shape objects on the active worksheet:
Dim shp As Shape
Dim myText As String
For Each shp In ActiveSheet.Shapes
myText = shp.TextFrame2.TextRange.Characters.Text
Next
Though I see that you are working in C#, so the above code will be a little different, but it at least gives you the object model to get to the text inside the TextBox.
Well, the TextBox isn't actually inside any cell (although it may appear to be).
Instead, you have to get it from the Shapes collection in the WorkSheet.