I have a TableCell "cell", where "cell.Text" contains something like
"<input type=\"checkbox\" tabindex=\"-1\" style=\"height:17px\" checked=\"checked\" />".
Goal is to remove the style property "height"!
Plse. note that the "style" attribute can contain some other properties (like "backgroundColor", etc.)
and that whitspaces can be used between "height:" and the value (here "17px")
and that it can (but must not) be terminated with a ";"
etc ...
So it makes no sense to me to parse it (using ".Substring(...)" etc.).
Another possible way would be to create a WebControl and to use ".Remove(...)".
Nice idea, but not working:
var control = Page.ParseControl(cell.Text);
var tmpPage = new Page();
tmpPage.Controls.Add(control);
var webControl = tmpPage.Controls[0] as WebControl; // this return null because "Control" could not be casted to WebControl
var before = webControl.Style;
webControl.Style.Remove(HtmlTextWriterStyle.Height);
var after = webControl.Style;
But this doesnt work. See my comment.
How to reach my goal?
Thx in advance.
Related
I've got a for loop to read line by line of a stream reader. This works very well. Now I've problems with reading the file of the stream reader. It's a csv file that contains two columns with information. The first one (A) contains a C# element like a textbox or a label (just like "label_1_title"), which is declared in my project. The second one (B) contains a normal simple string like "Hello".
Now I want to convert the string content of column A to the real existing element. Example: I've got "label_1_title" written in column A and that's an element, that exists in my project. Now I want to use this element to (for example) change it's content to the content of the column B of that line.
public void SetSprachpaket(string Sprachpaket)
{
StreamReader StreamReader = new StreamReader(Sprachpaket, Encoding.UTF8);
string Inhalt = StreamReader.ReadLine();
for (int i = 1; Inhalt != null; i++)
{
var Items = Inhalt.Split(new Char[] { ';' });
object Element = Items[0].GetType(); // Convert the string content of Items[1] to the existing object
Element = Items[1]; // Take this existing object and give it the string content of Items[2]
Inhalt = StreamReader.ReadLine();
}
StreamReader.Close();
}
I hope you can help me. Thanks in advance. Kind regards.
EDIT:
object Element = Items[0].GetType(); // Get (let's say) the string "myString"
Element = Items[1]; // --> myString = ...
Please don't rely on internal naming within your project. You should have some kind of explicit mapping between elements and the column data.
Dump the CSV file into a Dictionary<string, string> of Column A => Column B. On the element containing all the elements you want to populate, set the DataContext to the dictionary. Define your labels like this:
<Label Content="{Binding [label_1_title]}" />
For more details, see Data Binding Overview. This will look up the dictionary key "label_1_title" and set the content to the value when the label loads.
In case you want to use additional data binding other than the label dictionary, I recommend you use a custom object for the DataContext, that stores the dictionary in a property such as LabelDictionary. In this case the binding should be:
<Label Content="{Binding LabelDictionary[label_1_title]}" />
Simply by using foreach
foreach(control x in this.Control)
{
if(x.Name == A) // For A means the name of the object
{ x.Text = B; } // For B means the string
}
This is not ideal, you'll need to play around with it, but somewhere in the direction you are looking for I think.
while (Inhalt != null)
{
switch (Items[0])
{
case "label"
element = new Label();
element.Text = Items[1];
break;
case "textbox"
element = new Textbox();
element.Text = Items[1];
break;
case "numericUpDown"
element = new NumericUpDown();
element.Value = Item[1];
break;
}
}
Edit : if you are not wanting to populate the form from scratch, use this.Controls.Find() to find the control with that name.
If the items[0] is the name of the control you can do this to find the Control
this.Controls.Find(items[0])
you might then have to cast it to the appropriate type depending on which property you wish to assign to
control.Text = items[1];
Assuming that the first column is the name of a field in the same class and not the name of a control you could do this
var field = this.GetType().GetField(items[0],
BindingFlags.Instance
| BindingFlags.NonPublic);
var control = (Control)field.GetValue(this,null);
control.Text = items[1];
I don't know how to say this, I have 3 datagridview control (named datagridview1, datagridview2 & datagridview3). My question is can I concatenate the name of those control?
I mean is there a way that I can call it like this: datagridview(n) or datagridview + n
I'm using winforms.
Thanks in advance!
I think what you want is to find the control with a dynamic name?
Something like this perhaps:
Control match = ParentControl.Controls["datagridview" + n];
So if for example all your data grid are in a single panel called "MyPanel", then you can do this:
DataGridView match = MyPanel.Controls["datagridview" + n] as DataGridView;
If however, your data grids do not all belong to the same parent control, then you can find them using the Controls.Find method:
DataGridView match = this.Controls.Find("datagridview" + n, true)[0] as DataGridView;
NOTE: The Controls.Find method returns an array, so you need to select the first element (assuming your control name is unique), it may also be worth checking if the array has any values before trying to access the first element too.
If you want to wrap that in a function, you can do this:
public DataGridView GetDataGridViewForTabNumber(int n){
Control[] matches = this.Controls.Find("datagridview" + n, true);
if(matches.length == 0)
return null;
return matches[0] as DataGridView;
}
and call it like so:
DataGridView dgv = GetDataGridViewForTabNumber(1);//gets datagridview1
NOTE: This is a perfectly valid method if you are creating DataGridView controls dynamically at run time. If however, you are creating them in the designer then, like Tim said, you should give them a more meaningful name and reference them directly.
Try This
DataGridView dg = (DataGridView)this.Controls.Find("datagridview"+n.ToString(), true);
I have an interface with something like 20 textboxes that I wish to parse (comma separated lists expected).
To avoid writing 20 functions, I'd like to write one function that returns me a string[], which would accept as argument the variable name of the textboxes.
Is that possible without too much hassle ?
The variable name isn't the way to go, you can probably assign an identifier that is known at runtime to the textbox. I don'tknow what UI toolkit this is (WinForms? ASP.NET? WPF? Silverlight?) but you usually have access to an Id or Tag for the control.
TextBox ageTextBox = new TextBox();
nameTextBox.Tag = "Age";
TextBox shoeSizeTextBox = new TextBox();
shoeSizeTextBox.Tag = "ShoeSize";
Then later
foreach(var ctrl in Controls.OfType<TextBox>.Where(tb => tb.Tag == someTag))
{
Debug.WriteLine(tb.Tag+" = "+tb.Text); // or output to file etc.
}
I am creating a TextBox with the following code:
TextBox textBox = new TextBox();
textBox.Name = propertyName;
textBox.Text = value;
textBox.Width = FormControlColumnWidth;
textBox.SetResourceReference(Control.StyleProperty, "FormTextBoxStyle");
sp.Children.Add(textBox); //StackPanel
FormBase.Children.Add(sp);
On a button click, I want to get the text value of that text box, but I can't specify in code:
string firstName = FirstName.Text;
since "FirstName" will be defined at runtime. So how do I get the text value of the Textbox without knowing the name of the textbox at compile time?
The following is what I have so far but it says that it can't find "FirstName" even though it gets defined at runtime:
private void Button_Save(object sender, RoutedEventArgs e)
{
using (var db = Datasource.GetContext())
{
var item = (from i in db.Customers
where i.Id == TheId
select i).SingleOrDefault();
item.FirstName = ((TextBox)FindResource("FirstName")).Text;
db.SubmitChanges();
}
}
REPRODUCABLE EXAMPLE:
I posted a full reproducable example of this problem here: Why can't I access a TextBox by Name with FindName()?, perhaps easier to analyze.
The simplest solution would probably to keep a reference to your textbox somewhere in your code. Just add a
private TextBox _textbox
at the top of your class and set it to the TextBox you add in your code. Then you can refer to it in your Button_Save event handler.
You can retrieve it like this:
TextBox tb=(TextBox)Children.First(w=>w.Name=="FirstName");
Not sure what that sp in your code is, but if you really need the 2nd level of controls, you could run a foreach loop over the first level then search by name on the second level.
The answer to this question is you have to use this.RegisterName("FirstName", textBox); which is explained here: Why can't I access a TextBox by Name with FindName()?
You can find any element using FindName:
var c = (FrameworkElement)this.FindName("somename");
I can't write comments, so this is as a reply to your comment.
Why not use a
Dictionary<string, TextBox>
as a class property?
that way you can keep references to an indefinite number of textbox instances in the class AND access them easily by name in the dictionary?
I'm trying to find a way to to do something that I think must be possible but I'm just missing the point on - so hopefully someone can give me a bit of a nudge :)
I'm utilising databinding in ASP.NET (viewstate turned off - so using controlstate for a few things here and there) to render a repeater (repeaterPriceClasses) that has a repeater within each itemtemplate (repeaterPriceBands). Basically this renders a table out of some text and a dropdownlist in each cell.
I'm trying to find a way to enumerate the repeaterOuter inside the event handler of a button to give me a list of all of the originally bound elements that have now got a dropdownlist with a value of >0, along with what that value is.
public Dictionary<Price, int> SelectedPrices
{
get
{
var sel = new Dictionary<Price, int>();
foreach(RepeaterItem itemClass in repeaterPriceClasses.Items)
{
var repeaterPriceBands = itemClass.FindControl("repeaterPriceBands") as Repeater;
foreach(RepeaterItem itemBand in repeaterPriceBands.Items)
{
var context = (Price)itemBand.DataItem;
var listQty = itemBand.FindControl("listQty") as DropDownList;
if(listQty.SelectedValue.ToInt32() > 0)
{
sel.Add(context, listQty.SelectedValue.ToInt32());
}
}
}
return sel;
}
}
Now this fails because the itemBand.DataItem is always null after databinding has finished.
What technique should I use to get around this?
Hidden field with primary keys in it
(not ideal as can be abused and adds
weight to the page)
Lookup from
original cached data based on indexes
(just seems wrong)
or something
else/better...?
EDIT: Is there any more information that I could provide to help this get answered?
You can try adding extra attributes to your HTML elements in the ItemDataBound event when DataItem is available.
ddlSomething.Attributes["Attribute1"] = dataItemObject.PropertyName;
[Edit]
Apart from using attributes, you can render some array containing JSON objects like this, for each row.
var repeaterItemAttributes = [ { Prop1: val1, Prop2: val2, ... }, { ... }, ... ]
So, by using this, you won't have to render the attributes, and your code will be XHTML compliant too (tho its not required). You can then loop through the object array and read any property you like. You can also apply the light encryption you were talking about to the property values.
[/Edit]