Table of label ASP.net - asp.net

i want to know if i can create an array of labels in the code Behind.
And then, if i can put label from the .aspx in the label Array with the id and manipulate it with this.
Thanks

With a page that looks something like this:
<body>
<form id="form1" runat="server">
<div id="labelSpace" runat="server">
<asp:Label ID="Label1" runat="server" Text="Label" Visible="false" >Label One</asp:Label><br />
<asp:Label ID="Label2" runat="server" Text="Label">Label Two</asp:Label><br />
<asp:Label ID="Label3" runat="server" Text="Label">Label Three</asp:Label><br />
<asp:Label ID="Label4" runat="server" Text="Label" Visible="false">Label Four</asp:Label></div><br />
<asp:Button ID="Button1" runat="server" Text="PostBack and Change Labels" />
</form>
this will get you an array of all of the labels in the <div id="labelSpace"> and none of the other controls:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)//This will only fire after button is clicked...
{
//This does [just as you ask] provide you with an array of labels
Label[] labels = this.labelSpace.Controls.OfType<Label>().ToArray<Label>();
//& Allows you to manipulate a label in the code behind
// by addressing it's index value;
labels[2].Text = "Modified In Code Behind";
//Something you may find more useful than an array is getting
// a list of labels like:
List<Label> listOfLabels = this.labelSpace.Controls.OfType<Label>().ToList<Label>();
//with a list you can identify an individual label easily like:
IEnumerable<Label> invisibleLabels = listOfLabels.Where(l => l.Visible == false);
//with an 'IEnemerable of invisible labels you can now manipulate those to make them all visible...
foreach (Label l in invisibleLabels)
{
l.Visible = true;
l.Text = "Made Visible";
}
//or, if you just want a single label where the id is "Label2"
var labelThree = labels.Where(p => p.ID == "Label2").First();
labelThree.Text = "selected by label id and then edited";
}
}
If you want to start at the page level you will need to build a recursive routine to drill into child controls to create a masterControlCollection and then call to ".OfType<T>..."
Once you have gotten this far you can use LINQ to select out a particular label or set of labels based on any property you want.

Yes you can. Labels from the .aspx part will have a corresponding object in the codebehind file. There's nothing special about them, they are just like any other .NET object. For example if you have markup that looks like this
<asp:Label runat="server" id="MyLabl1" Text="Some Text 1" />
<asp:Label runat="server" id="MyLabl2" Text="Some Text 2" />
<asp:Label runat="server" id="MyLabl3" Text="Some Text 3" />
<asp:Label runat="server" id="MyLabl4" Text="Some Text 4" />
The codebehind file will have something like
protected global::System.Web.UI.WebControls.Label MyLabl1;
protected global::System.Web.UI.WebControls.Label MyLabl2;
protected global::System.Web.UI.WebControls.Label MyLabl3;
protected global::System.Web.UI.WebControls.Label MyLabl4;
Depending on how your project was set up this may be in either the .cs file or the .designer.cs file. From there there's nothing stopping you from adding them to an array and working with them from there.
For example
var labels = new Label[] { MyLabl1, MyLabl2, MyLabl3, MyLabl4 };
will make an array called labels with the 4 labels in it and then you can do whatever you'd like to them. Then you can do labels[0] to get to the first one, etc. Is this what you had in mind?

Label[] labels = new Label[10];
labels[0] = new Label();
labels[0].Text = "blablabla";
...
labels[9] = new Label();
labels[9].Text = "blablabla";

Related

Bind data ObjectDataSource to Label

How do you bind data from an ObjectDataSource to a label form an Formview (Detailsview)?
This is my code from the DetailsView ()
Normally it shows the ID of Afstand (Distance) but it has to show instead of id=1 --> "5km"
ID_AFSTAND:
<asp:Label ID="ID_AFSTANDLabel" runat="server" DataSourceId="dtsrcAFstandKilometer" Text='<%# Bind("AFSTAND") %>' DataValueField="ID_AFSTAND" DataTextField="AFSTAND" AppendDataBoundItems="true" />
<asp:ObjectDataSource ID="dtsrcAFstandKilometer" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetDataAfstand" TypeName="InschrijvenTableAdapters.tblAfstandenTableAdapter"></asp:ObjectDataSource>
<br />
Personally I've never seen binding of a label to any type of data source done from the design view and I'm not sure whether it's even possible because the data sources generally contain multiple records and to bind to a label you would need to implement some kind of "top 1" type logic in the binding.But this can quite easily be done in the code behind, here's an exmple:
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataView afstande = dtsrcAFstandKilometer.Select() as DataView;
string firstID = afstande[0][0].ToString();
string firstKM = afstande[0][1].ToString();
ID_AFSTANDLabel.Text = firstKM;
}
.ASPX:
<asp:Label ID="ID_AFSTANDLabel" runat="server" />

asp.net: Use javascript set lable value but it doesn't save

This is my code:
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<input type="button" onclick="ontextchange();" />
<asp:Button ID="Button1" runat="server"
Text="Button" onclick="Button1_Click" />
</div>
function ontextchange() {
document.getElementById("Label1").innerText="New";
}
The problem is: I can change the lable value via javascript, but when I click the Button1, the lable value become the first one "Label". How can I get the new value when I click the asp.net button?
You may try to use a hidden field instead, but you need to keep them synchronized in your client-side script and your server-side event handler.
<asp:Hidden ID="Hidden1" runat="server" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
In JavaScript:
function ontextchange() {
// Set the label for the visual result
document.getElementById("Label1").innerText="New";
// Set the hidden input for the server
document.getElementById("Hidden1").value="New";
}
Server-side you can read the hidden input and update the label (again, keeping them synchronized):
protected void Button1_Click(object sender, EventArgs e)
{
// Set the label text to the value from the hidden input
string value = Hidden1.Value;
Label1.Text = value;
}

asp.net ajax like reorder list

I'm trying to create a draggable list to change the order some pictures are displayed in a product page. I wan't to be able to do this in the product edit page (same place where I add the pics and their description). So, when creating I have nothing inserted on the database and since the AJAX toolkit reorderlist only works with a datasource I was specifying the list as the source of the reorderlist and calling the databind method. In the item template of the reorder list I have a textbox to edit the pic description and a img that displays the photo. I can drag the items and the list gets reordered, however when I click save I can't get the updated text on the textbox and the order property on the picture doesn't get updated. I've tried manually getting the items in the reorderlist but they're always null even though the list shows 20 items the DataItem is empty. I've enabled viewstate and didn't help either.
Here's my code:
<ajaxToolkit:ReorderList ID="rdlPhotos" runat="server" SortOrderField="PhotoOrder" AllowReorder="true" PostBackOnReorder="true" ClientIDMode="AutoID" EnableViewState="true" ViewStateMode="Enabled">
<ItemTemplate>
<div>
<%--<eva:PhotoView ID="iPV" runat="server" Photo='<%# Container.DataItem %>' />--%>
<asp:Image ID="imgPhoto" runat="server" ImageUrl='<%# string.Format("http://eva-atelier.net/sparkle{0}", Eval("Path").ToString().Substring(1)) %>' Width="150" Height="150" />
<div class="formGrid">
<label class="formLabel">Title</label>
<asp:TextBox ID="txtTitle" runat="server" Text='<%#Bind("FileTitle") %>' />
<br />
<label class="formLabel">Description</label>
<asp:TextBox ID="txtDescription" runat="server" Text='<%#Bind("FileDescription") %>' />
<br />
</div>
<p>
<asp:Button ID="btnRemove" runat="server" Text="Remover" />
</p>
</div>
</ItemTemplate>
<ReorderTemplate>
<asp:Panel ID="pnlReorder" runat="server" />
</ReorderTemplate>
<DragHandleTemplate>
<div style="width:20px;height:20px;background-color:Red"></div>
</DragHandleTemplate>
</ajaxToolkit:ReorderList>
And below the C# code:
private void AddPhotosView()
{
if (_currentProduct.Photos != null && _currentProduct.Photos.Count > 0)
{
rdlPhotos.DataSource = _currentProduct.Photos;
rdlPhotos.DataBind();
}
}
I'm new to Asp.net I come from a large WPF background, sorry if I'm making basic question :)
Thanks
For updating order of ReorderList items add your handler for it's OnItemReorder event. In this case your handler may looks like this:
protected void ReorderHandler(object sender, ReorderListItemReorderEventArgs e)
{
var movedPhoto = _currentProduct.Photos[e.OldIndex];
_currentProduct.Photos.RemoveAt(e.OldIndex);
_currentProduct.Photos.Insert(e.NewIndex, movedPhoto);
_currentProduct.Photos.Save();
}
For updating FileTitle and FileDescription of single Photo it is easy to use OnUpdateCommand event of ReorderList and a button with attribute CommandName="Update" for each Photo.
And for updating all Photos at once just iterate through rdlPhotos.Items in next manner:
protected void SaveAllHandler(object sender, EventArgs e)
{
foreach (var riItem in rdlPhotos.Items)
{
var id = ((HiddenField)riItem.FindControl("itemID")).Value;
var title = ((TextBox)riItem.FindControl("txtTitle")).Text;
var description = ((TextBox)riItem.FindControl("txtDescription")).Text;
UpdatePhoto(id, title, description);
}
}
Remember that rdlPhotos.Items here are in initial order. And for identifying which Photo should be updated add hidden field with Photo.ID-value to ReorderList's ItemTemplate like this:
<asp:HiddenField runat="server" ID="itemID" Value='<%# Eval("ID") %>' />

Add an additional label control to an <ItemTemplate> dynamically in certain cases

How can I add an extra label control dynamically (should be added only on certain conditions).
I am trying to do something like this:
<asp:DataGrid id="dg" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateColumn SortExpression="Column1">
<HeaderTemplate>
<asp:LinkButton Runat="server" text="Column1 Hdr" ID="col1Hdr">
</asp:LinkButton>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="col1Label" runat="server" Text='<%# Method1(DataBinder.Eval(Container.DataItem, "Column1").ToString(), DataBinder.Eval(Container.DataItem, "Column2").ToString()) %>' >
<asp:PlaceHolder ID="col2Holder" runat="server"></asp:PlaceHolder>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Alternatively, I tried putting the placeholder in a seperate template:
<EditItemTemplate>
<asp:PlaceHolder ID="col2Holder" runat="server"></asp:PlaceHolder>
</EditItemTemplate>
but to no avail.
Any tips on how I can create the Placeholder only in some cases (like for some values of Column1/Column2), rather than opt for a repeater approach...
I get a null reference exception but that was solved when I had to explicitly mention:
protected PlaceHolder col2Holder = new Placeholder();
instead of
protected PlaceHolder col2Holder;
But though method1 is able to set the 'Column1's text value correctly, it does nothing for the Column2's value...
Is there something I'm missing or is there a different way to do this?
Here's method1's defn:
public string Method1(string col1, string col2)
{
col1 += "Called method1";
Label col2label= new Label();
col2label.Visible = true;
col2label.Text = col2;
col2Holder.Controls.Add(col2label);
col2Holder.DataBind();
return col1;
}
Where and when do you need the extra control to be inserted?
You should most likely hookup a method to the OnItemDataBound event and in there decide whether to add a control or not. The event gives you a reference to the item being bound so you can say e.Item.Controls.Add(your_control)
Update
Ah, now i get it what you're asking for. You need to add another argument to your Method1 that takes a DataGridItem. When you call Method1 you add it like this Method1(Container) where Container refers to the DataGridItem in question. Then you can say in the Method1
public string Method1(DataGridItem item)
{
string col1 = DataBinder.Eval(item.DataItem, "Column1").ToString();
string col2 = DataBinder.Eval(item.DataItem, "Column2").ToString();
var col2label = new Label() { Visible = true, Text = col2 };
var col2Holder = item.FindControl("col2Holder");
col2Holder.Controls.Add(col2label);
return col1 + "Called method1";
}
Btw, you can't add any controls to a Label, your ItemTemplate should look like this
<ItemTemplate>
<asp:Label ID="col1Label" runat="server" Text="<%# Method1(Container) %>" />
<asp:PlaceHolder ID="col2Holder" runat="server" />
</ItemTemplate>
If you want the new Label to be nested inside the first label, you should do that explicit in the method, and leave out the placeholder:
<ItemTemplate>
<asp:Label ID="label" runat="server" Text="<%# Method1(Container) %>" />
</ItemTemplate>
public string Method1(DataGridItem item)
{
string col1 = DataBinder.Eval(item.DataItem, "Column1").ToString();
string col2 = DataBinder.Eval(item.DataItem, "Column2").ToString();
var label = item.FindControl("label");
var col2label = new Label() { Visible = true, Text = col2 };
col1Holder.Controls.Add(col2label);
return col1 + "Called method1";
}

Render a string[] as a series of editable controls?

I have a string[] containing individual words parsed out of a paragraph of text. I need to display each word in its own cell, and have each cell be assigned a dynamic width based on the word's length. I want to be able to have as many words as possible within the maximum width of each row.
In short, I'm trying to take a given paragraph of text and present it as a series of editable controls in a way which resembles how it might appear as a plain text document, with each word consuming only its required space on each "line".
I first tried using a DataList with RepeatLayout in Table mode and RepeatColumns to a set value of 10, with a Repeater within containing a Label control; this resulted in 10 words per row but each cell with a fixed width.
I've considered using a GridView with a single column which I would cram with as many words (in the form of Label controls) per row as will fit, adding new rows as necessary until the entire paragraph is built.
Could anyone please share an elegant way to do this?
The magic you're looking for is the "contenteditable" attribute. Works in IE, Firefox and Chrome.
I'm not sure what the hell you're doing with this, lmao... but this ought to work:
Your Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
//creating some bogus collection of strings.
string[] parts = { "this", "is", "a", "test", "of", "the", "goofiest", "ui", "ever" };
//bind it to the repeater.
rptr.DataSource = parts;
rptr.DataBind();
//now we'll add them to a JavaScript array we can access client side.
StringBuilder sb = new StringBuilder();
sb.Append("document.stringItems = new Array();");
for (int i = 0; i < parts.Length; i++)
sb.AppendFormat("document.stringItems[{0}] = '{1}';", i, parts[i]);
ScriptManager.RegisterClientScriptBlock(this, GetType(), "someKey", sb.ToString(), true);
}
protected void btnTest_Click(object sender, EventArgs e)
{
//display the result just so we can see it's working.
lblResult.Text = hdnResult.Value;
}
Your .ASPX:
<asp:Repeater ID="rptr" runat="server">
<ItemTemplate>
<span contenteditable="true" style="border: solid 1px;" onkeyup="updateItem(event, <%#Container.ItemIndex%>)">
<%#Container.DataItem%></span>
</ItemTemplate>
</asp:Repeater>
<asp:HiddenField ID="hdnResult" runat="server" />
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
<script type="text/javascript" language="javascript">
//<![CDATA[
function updateItem(e, index) {
//get the source element. (magic here for cross browser lameness)
var src;
if(window.event) {
e = window.event;
src = e.srcElement;
}else{
src = e.target;
}
//update our item in our array.
document.stringItems[index] = src.innerHTML;
//update our hidden field.
var s = '';
var space = false;
for (var i = 0; i < document.stringItems.length; i++) {
if (space)
s += ' ';
else
space = true;
s += document.stringItems[i];
}
var hdnResult = document.getElementById('<%=hdnResult.ClientID%>');
hdnResult.value = s;
}
//]]>
</script>
<asp:Label ID="lblResult" runat="server"></asp:Label>
You'll have to add some javascript for the onkeypress too to make sure they're not adding carriage returns or spaces or whatever it is you don't want them putting in... but this is the basic idea.
I hope that helps. Good luck.
I'll start off by saying that, from a user interface perspective, I'm not entirely sure as to why you would need to do this, but if it must be done you'd do something along these lines:
Start off with your string[]
Create a List<List<string>>
Loop through your original array, adding the strings to a new List<string>
Once you've reached your desired total character length, add the List<string> to your List<List<string>> (which contains your lines)
Repeat these steps until you've gone all the way through your original array
Once this is done, you bind the list o' list to a repeater like this below (pseudo code; might be off a bit):
<asp:Repeater id="rpt1" runat="server">
<ItemTemplate>
<div>
<asp:Repeater id="rpt2" runat="server" DataSource='<%# Container.DataItem %>'>
<ItemTemplate>
<asp:TextBox id="txt1" runat="server" Text='<%# Container.DataItem %>' Width='<%# MyWidthAlgorithm(Container.DataItem) %>'
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
Best way I can think of approaching something like this is to simply use a repeater and float everything left.
<asp:Repeater runat="server" id="rptr">
<ItemTemplate>
<span style="float:left; height:22px; line-height:22px;"><%# Eval("Word") %></span>
</ItemTemplate>
</asp:Repeater>

Resources