Dynamically accessing array variables from Code Behind in ASPX - asp.net

Due to the nature of the current file system I am working with I have to dynamically access array variables in ASPX page from the code-behind page. I got it to the point where I am able to pull any one explicitly stated variable, but cannot seem to pull them dynamically.
Code Behind:
public partial class some_class : System.Web.UI.Page {
public string[] array123 = new string[100];
....
protected void Button1_Click(object sender, EventArgs e) {
someFunction();
}
protected void someFunction() {
int i = 1;
_TempDt = Locator._New_Locator(value)
foreach (DataRow _TempDR in _TempDt.Rows) {
array123[i] = Server.UrlEncode(address);
i++;
}
}
}
ASPX:
....
<asp:Repeater ID="DataList" runat="server">
<ItemTemplate>
<label onClick="javascript:popup('page.aspx?key=<%= array123[1] %>')">Get link</label>
</ItemTemplate>
</asp:Repeater>
This only pulls the stated (2nd) value in the array and it needs to be dynamic with the repeater.
Thanks.

I think this is what you are looking for:
<p><%# array123[Container.ItemIndex] %></p>

Try this:
< %#DataBinder.Eval(Container, "ItemIndex", "")%>

Related

List of controls in code behind

How can I add to a list<> some controls of my dashboard? I do something like List<String> NewList = new List<Strings>(){} but this throw me errors
I'm trying to add some linkButtons into the list.
I'm tying to do something like this but is wrong
protected void listLink(){
List<LinkButton> linksList = new List<LinkButton>();
listLink{
}
}
I want to use that list in other events
my linkbuttons are in visible = false;
From what i understand you want to create a list of LinkButtons using Object Initialization way.
Below code snippet should help you.
Aspx code:
<form id="form1" runat="server">
<asp:LinkButton ID="lnkBtn1" runat="server"></asp:LinkButton>
<asp:LinkButton ID="lnkBtn2" runat="server"></asp:LinkButton>
</form>
Aspx.cs code:
List<LinkButton> lnkBtnCollection = null;
protected void Page_Init(object sender, EventArgs e)
{
//Object Initialization way
lnkBtnCollection = new List<LinkButton>
{
lnkBtn1, lnkBtn2
};
//Second way where items are added to the list after the list is created
//lnkBtnCollection = new List<LinkButton>();
//lnkBtnCollection.Add(lnkBtn1);
//lnkBtnCollection.Add(lnkBtn2);
}
protected void Page_Load(object sender, EventArgs e)
{
//Use LinkBtn Collection here
foreach (var lnkBtn in lnkBtnCollection)
{
}
}

How can I Implement N level nested Repeater control in asp.net?

I want to achieve n level data hierarchy in using repeater control in asp.net.
Is there any solution to achieve that hierarchy ?
For this answer I'm going to suggest creating your template programmatically - see here: https://msdn.microsoft.com/en-us/library/aa289501 .
There is probably some way to use templates that have been created in markup, but this seems easier, and definitely more flexible.
I start out with a page with just a repeater (not template)
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater runat="server" ID="TestRepeater">
</asp:Repeater>
</div>
</form>
</body>
and a data class
public class DataClass
{
public string Name { get; set; }
public List<DataClass> Children { get; set; }
}
For the template we use the following class:
public class DataTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
var name = new Literal();
var repeater = new Repeater();
name.DataBinding += BindingLiteral;
repeater.DataBinding += BindingRepeater;
// this here makes it recursive
repeater.ItemTemplate = new DataTemplate();
container.Controls.Add(name);
container.Controls.Add(repeater);
}
private void BindingLiteral(object sender, System.EventArgs e)
{
var name = (Literal)sender;
var container = (RepeaterItem)name.NamingContainer;
name.Text = String.Concat("<h2>", DataBinder.Eval(container.DataItem, "Name").ToString(), "</h2>");
}
private void BindingRepeater(object sender, System.EventArgs e)
{
var name = (Repeater)sender;
var container = (RepeaterItem)name.NamingContainer;
name.DataSource = DataBinder.Eval(container.DataItem, "Children");
}
}
Obviously you'll want to use a more sophisticated template. Notice that if you currently have a template in markup, you could simply take the code that has been generated by the markup parser, and adapt it to your needs.
Now in the code behind of the page we simple assign the ItemTemplate and DataSource:
public partial class Test : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
TestRepeater.DataSource = GetTestData();
TestRepeater.ItemTemplate = new DataTemplate();
TestRepeater.DataBind();
}
}
Nice thing about this is your template is just a class, so you could add a public Int32 Depth { get; set; } to it, and change the generated controls based on your depth.
Another solution, without creating the template programmatically :
Using a simple data class :
public class DataClass
{
public string Name { get; set; }
public List<DataClass> Children { get; set; }
}
In the ASPX markup create your parent repeater, put your item display code in the ItemTemplate, and add a second "empty" repeater :
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater runat="server" ID="ParentRepeater" OnItemDataBound="Repeater_ItemDataBound">
<ItemTemplate>
<asp:Literal runat="server" Text="<%# Eval("Name") %>"></asp:Literal>
<asp:Repeater runat="server" ID="ChildRepeater" OnItemDataBound="Repeater_ItemDataBound" Visible="false">
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
And in the code-behind :
protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
DataClass currentItem = (DataClass)e.Item.DataItem;
if (currentItem.Children.Count > 0) {
Repeater ChildRepeater = (Repeater)e.Item.FindControl("ChildRepeater");
ChildRepeater.DataSource = currentItem.Children;
ChildRepeater.ItemTemplate = ParentRepeater.ItemTemplate;
ChildRepeater.Visible = true;
ChildRepeater.DataBind();
}
}
}

Asp.net Formview with a gridview inside the Edit/InsertTemplate working example

I'm using a FormView to edit my business objects. I don't have any problem to edit/insert single properties.
Some of the business objects have collection properties that I'd like edit/insert in the same way I do for the single properties: Text='<%# Bind("SinglePropertyName") %>'.
So I'd like to include a gridview inside of the edit/insert templates and bind (two-way) it Datasource to the collection property: Datasource='<%# Bind("CollectionPropertyName") %>'. Then I'd like to be able to edit the collection propties items with the gridview itself and get the changed values among the other sigleproperties' changes.
This works fine to show the template, the collection is rendered to the gridview. The problem is to get the changes on it.
I've tried to do so with no luck, I get the following exception when trying to Databind the gridview: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
Beside that, the NewValues of the FormView for the CollectionProperty from the ItemUpdating event always return null.
So I'd like to see a working example of a similar scenario to see if I'm able to do it or if I need to use a different approach.
Thanks!
I already found a solution to this and it was to encapsulate the gridview in a user control (ObjectList) that exposes a Value property to bind to.
<uc:ObjectList ID="ucObjectList" runat="server" Value='<%#Bind("Items") %>' />
ObjectList.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ObjectList.ascx.cs" Inherits="TestBinding.ObjectList" %>
<asp:GridView runat="server" ID="grdItems" DataSource='<%#Datasource%>'
OnRowEditing="grdItems_RowEditing"
OnRowCancelingEdit="grdItems_RowCancelingEdit"
OnRowUpdating="grdItems_OnRowUpdating">
<Columns>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
</Columns>
</asp:GridView>
ObjectList.ascx.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI.WebControls;
namespace TestBinding
{
public partial class ObjectList : UserControl
{
protected List Datasource
{
get
{
if (ViewState["ObjectList"] == null) ViewState["ObjectList"] = new Test();
return (List)ViewState["ObjectList"];
}
set { ViewState["ObjectList"] = value; }
}
[Bindable(true, BindingDirection.TwoWay)]
public List Value
{
get { return Datasource; }
set { Datasource = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void grdItems_RowEditing(object sender, GridViewEditEventArgs e)
{
((GridView)sender).EditIndex = e.NewEditIndex;
((GridView)sender).DataSource = Datasource;
((GridView)sender).DataBind();
}
protected void grdItems_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
((GridView)sender).EditIndex = -1;
((GridView)sender).DataSource = Datasource;
((GridView)sender).DataBind();
}
protected void grdItems_OnRowUpdating(object sender, GridViewUpdateEventArgs e)
{
Datasource[e.RowIndex].ID = int.Parse(e.NewValues["ID"].ToString());
Datasource[e.RowIndex].Last = (string)e.NewValues["Last"];
((GridView)sender).EditIndex = -1;
((GridView)sender).DataSource = Datasource;
((GridView)sender).DataBind();
}
}
}
I hope this help you if you deal with something like that.

How can i Access a control into a class?

I Have a Gridview in page.aspx. this gridview i want to pass as a parameter to the constructor of a class1.cs.Can anybody tel me, How can this be done?
So you've got a page with a Gridview:
<asp:GridView runat="server" ID="gv1" AutoGenerateColumns="true">
</asp:GridView>
<div>
This is where the count of rows of your GridView will be displayed:
<p>
<strong><asp:Label runat="server" ID="lCount" /></strong>
</p>
</div>
And, in the codebehind you populate it like this:
this.gv1.DataSource = FullName.GetDemoCollection(); //Just returns a List<string>;
gv1.DataBind();
And you have another class GridViewRowCounter that does something with GridView, e.g. counts the rows:
public class GridViewRowCounter
{
private System.Web.UI.WebControls.GridView _gv;
public GridViewRowCounter(){}
public GridViewRowCounter(System.Web.UI.WebControls.GridView _GV){
this._gv = _GV;
}
public int GetRowCount(){
return _gv.Rows.Count;
}
}
So, to pass your GridView to the Gridviewcounter class you can do something like:
public partial class PassingControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Bind the GridView
this.gv1.DataSource = FullName.GetDemoCollection();//
gv1.DataBind();
//Pass Gridview reference to the GridVeiwRowCounter constructor.
GridViewRowCounter gvcounter = new GridViewRowCounter(this.gv1);
//Get the external class to return the rowcount from your GridView.
this.lCount.Text = gvcounter.GetRowCount().ToString();
}
}
HTH.
I hope this is what you were asking ;-)

Nested DataPagers problem

Sample code
<asp:Repeater>
<ItemTemplate>
<asp:ListView DataSource=<%# Container.DataItem.Items %> ... />
<asp:DataPager .... />
</ItemTemplate>
</asp:Repeater>
This does not work.
The repeater data source is not a datasource control
It is set like so
repeater.DataSource = datasource
repeater.DataBind()
It is possible, and I've done it many times before.
You may have to wire up the events yourself, and you do have to use FindControl() in the repeaters item databound event to grab the specific ListView in order to set the Data Source, and also to call DataBind on it.
You can use the data binding shortcut <%# ... %> within the nested Repeater / DataList, but not to set the DataSource as you have done.
Paste the following into a blank new project. Compiles and runs.
(Big disclaimer - the html is just for demonstration and is pretty poor.)
Web Form Code.
<asp:ListView ID="dlOuter" runat="server"
onitemdatabound="dlOuter_ItemDataBound">
<LayoutTemplate>
<div id="personGroupList">
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
</div>
</LayoutTemplate>
<ItemTemplate>
<div class="groupHeading"><%# Eval("Key") %></div>
<asp:ListView ID="dlInner" runat="server"
ItemPlaceholderID="innerItemPlaceHolder"
onitemdatabound="dlInner_ItemDataBound"
>
<LayoutTemplate>
<asp:PlaceHolder ID="innerItemPlaceHolder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<div class="person">
Name: <%# Eval("Name") %>
Age: <%# Eval("Age") %>
</div>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:ListView>
Now in the code behind
protected void Page_Load(object sender, EventArgs e)
{
// takes a list of Person and group's by Person.City
// really this is just an outer grouping that's in use.
var query = from p in Person.GetPersons() select p;
dlOuter.DataSource = query.ToLookup(o => o.City);
dlOuter.DataBind();
}
// The outer List View is the groups.
// we bind the inner view to the list if Person in the group.
protected void dlOuter_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem di = (ListViewDataItem)e.Item;
ListView inner = (ListView)e.Item.FindControl("dlInner");
IGrouping<string, Person> lookup = (IGrouping<string, Person>)di.DataItem;
inner.DataSource = lookup.AsEnumerable();
inner.DataBind();
}
}
protected void dlInner_ItemDataBound(object sender, ListViewItemEventArgs e)
{
// included so you can see how it's wired up. Unused in this sample.
}
Person class is just for demonstration.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
public static List<Person> GetPersons()
{
List<Person> persons = new List<Person>
{
new Person { Name="Bob", Age=30, City="Chicago" },
new Person { Name="Mary", Age=20, City="NYC" },
new Person { Name="Marty", Age=12, City="LA" },
new Person { Name="Fred", Age=33, City="NYC" },
new Person { Name="Susan", Age=22, City="Chicago" }
};
return persons;
}
}
Note that in this example I'm grouping using ToLookup to create a grouping from a list. In the real code this is derived from, it's showing a page of data ordered by what happens on a particular day. E.g. the records are sorted by thing.SomeDate and the grouping is query.ToLookup( o => o.SomeDate.ToLongDateString() );
It's important to note that the ToLookup and use of IGrouping<T,X> is irrelevant except I need to get grouped data in there somehow for the purposes of example. You could just as easily have the canonical example of Order and OrderDetail where the outer ListView is a List<Order> and the inner ListView is the Order.OrderDetails

Resources