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
Related
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.
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.
I am looking for a way to highlight some search terms inside my custom ListView control. I have a bunch of TextBlocks (one for each property of each row). For example the artist name, title and genre of each song.
Now, if someone searches for "Emi" then I want the artist field to show up like <b>Emi</b>nem, if the value of the binding is Eminem.
I have looked around a bit but didn't get much wiser. I figure I need some combination of a converter and using Inlines (which I've never used before) and/or InlineExpressions (or are those only for ASP?).
All bindings and templates are created on-the-fly in C# and not XAML.
Thanks!
Yes, you are right about using converter(actually it will may be even multiconveter) and Inlines collection of a TextBlock.
So let's say you are passing search item(in your case word 'Emi') to the converter. You will also need to manipulate the TextBlock with resulting text somehow. For simplicity let's assume that TextBlock's Tag property(not Text) contails the whole string being searched(word 'Eminem').
class HighlightPartOfTextConverter : IValueConverter {
public object Convert(object value/*this is TextBlock*/, Type type, object parameter/*this is 'Emi'*/, CultureInfo ci){
var textBlock = value as TextBlock;
string str = textBlock.Tag as string;
string searchThis = parameter as string;
int index = str.IndexOf(searchThis);
if(index >= 0){
string before = str.Substring(0, index);
string after = str.Substring(index + searchThis.Length);
textBlock.Inlines.Clear();
textBlock.Inlines.Add(new Run(){Text=before});
textBlock.Inlines.Add(new Run(){Text=searchThis, FontWeight = FontWeights.Bold});
textBlock.Inlines.Add(new Run(){Text=after});
}
return "";
}
public object ConvertBack(...) {...}
}
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.
in WPF It it possible to change a text box's font size during runtime?
i tried to do that:
foreach (Control ctrl in gridArray[i].Children)
{
if(ctrl.GetType() == typeof(TextBox))
{
(TextBox)ctrl.FontSize = (double)5;
}
}
but it didnt work
The cast does not have a high precedence, your code effectively tries to cast the value in ctrl.FontSize to TextBox, you need to add parenthesis (and the double cast is superfluous):
((TextBox)ctrl).FontSize = 5;
Further the way you check the type of the control is not such a good idea, use is instead. Otherwise sublasses of TextBox are not included.
if (ctrl is TextBox)
Further as you do not only care about the type and cast as well to interact with the TextBox class interface you may as well use as:
var textBox = ctrl as TextBox;
if (textBox != null)
textBox.FontSize = 5;
This also conveniently gets rid of the parenthesis jungle.