Is it possible to pass an object to usercontrol in front-end? - asp.net

Is there anyway to pass an object to an usercontrol through the frontend tags? I have tried the following but it doesn't work.
Backend
public Range Range { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
// Popular channel range
Range Range = new Range()
{
Min = 0,
Max = 8
};
}
Frontend
<uc:PopularItems Range="<%=Range %>" runat="server" />

You can't use <%= with a server control. You should use <%# and databind:
Backend
[Bindable(true)]
public Range Range { get; set; }
Frontend
<uc:PopularItems ID="myControl" Range="<%# Range %>" runat="server" />
Backend of the page
if(! IsPostBack) {
myControl.DataBind();
// or, to bind each control in the page:
// this.DataBind();
}

Related

How to keep the variable value after post back

I am trying to keep the variable value after the post back. I tried it both by session variable and also Viewstate but failed to keep the value of random number same. Every time after button press (after page refresh) I am getting a new random value but I want to keep the same value.
//in code behind
public static int RandNumber{ get; set; }
protected void Page_Load(object sender, EventArgs e)
{
//by using session
Session["rand"] = rnd.Next(0, 10);
RandNumber = Int32.Parse(Session["rand"].ToString());
//by view state
int rand = rnd.Next(0, 10);
ViewState["KEY"] = rand;
RandNumber = Int32.Parse(ViewState["KEY"].ToString());
}
for post back in the form:
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
And tried to access in the page as below:
<p>Random No: <%= RandNumber %></p>
Only set a new random number if it's not a post back by checking IsPostBack
public int RandNumber{ get; set; }
protected void Page_Load(object sender, EventArgs e)
{
//by using session
if(!IsPostBack){
Session["rand"] = rnd.Next(0, 10);
}
RandNumber = Int32.Parse(Session["rand"].ToString());
}

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();
}
}
}

How to update user control in UpdatePanel?

I want to refresh a user control in UpdatePanel, but I would also like to refresh it with different property values.
<asp:UpdatePanel runat=server ID=up1>
<Triggers>
<asp:AsyncPostBackTrigger controlid="but01" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Button runat="server" Text="Test" ID="but01" />
<UC:Uc runat=server ID="Uc1" />
</ContentTemplate>
</asp:UpdatePanel>
Codebehind for but01 click is
void but01_Click(object sender, EventArgs e)
{
this.Uc1.ID = 1;
this.Uc1.Length = 50;
}
I tested this code, and the user control is being refreshed, but new values ID=1, Length=50 are not applied.
Control code behind is rather simple
namespace Admin.Web.Controls
{
public partial class Uc1 : System.Web.UI.UserControl
{
private string p_to;
private string p_from;
private string p_subject;
private string p_body;
private string p_priority;
}
protected void Page_Load(object sender, EventArgs e)
{
this.txtFrom.Text = p_from;
this.txtTo.Text = p_to;
this.txtSubject.Text = p_subject;
this.txtBody.Text = p_body;
}
public string Subject
{
get
{
return p_subject;
}
set
{
p_subject = value;
}
}
public string From
{
get
{
return p_from;
}
set
{
p_from = value;
}
}
public string To
{
get
{
return p_to;
}
set
{
p_to = value;
}
}
public string Body
{
get
{
return p_body;
}
set
{
p_body = value;
}
}
}
ascx header is
<%# Control Language="c#" Inherits="Admin.Web.Controls.Uc1" AutoEventWireup="true" Codebehind="Uc1.ascx.cs" %>
When I initiate user control from aspx page during page load, everything is ok. On postback from control panel, user control is refreshed (checked with Label + time), but no values are passed to user control.
Remove Triggers tag
http://msdn.microsoft.com/en-us/library/Bb399001(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
OR
Move asp:Button to outside of UpdatePanel.
http://msdn.microsoft.com/en-us/library/Bb399001(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-5
Update:
Please make the setter and getter of the control as -
public string Subject
{
get { return txtSubject.Text; }
set { txtSubject.Text = value; }
}

Multiple Pages (Like google results) in ASP.net

I am trying to do the following
I have a dynamic table in my asp page
and I want to show the table in multi pages like google results
any useful suggestion please
note:
I don't to use gridview
so any another way ??
If you want more flexibility in the output than GridView provides, take a look at Repeater.
Since the Repeater doesn't directly implement paging, you'll have to supply your own Next and Previous buttons. As noted by Sundararajan S if you have many records you'll want to use the current page number and page size to return only the current page's records to the browser rather than all of them.
Below is an example (I didn't know what your data source would be like, so I just used a list as an example. Substitute with something more appropriate.)
Hope that helps.
Default.aspx:
<asp:Button ID="PrevPageButton" runat="server" Text="Prev"
onclick="PrevPageButton_Click" />
<asp:Label ID="CurrentPageLabel" runat="server" />
<asp:Button ID="NextPageButton" runat="server" Text="Next"
onclick="NextPageButton_Click" />
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<h2> <%# Eval("Name") %> </h2>
<p>
<%# Eval("Description") %>
</p>
</ItemTemplate>
</asp:Repeater>
Default.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace RepeaterPaging
{
public partial class _Default : System.Web.UI.Page
{
private const int PageSize = 10;
private const int MaxPage = 4;
public int CurrPage
{
get
{
if (this.ViewState["CurrPage"] == null )
this.ViewState["CurrPage"] = 0;
return (int) this.ViewState["CurrPage"];
}
set { this.ViewState["CurrPage"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindItems();
}
}
protected void BindItems()
{
int currPage = CurrPage;
List<Book> books = new List<Book>();
int startItem = (currPage * PageSize) + 1;
for (int i = startItem; i < startItem+PageSize; i++)
{
books.Add(new Book("Title " + i, "Description " + i + " ..................."));
}
Repeater1.DataSource = books;
Repeater1.DataBind();
CurrentPageLabel.Text =
string.Format(" Page {0} of {1} ", CurrPage + 1, MaxPage + 1);
}
protected void NextPageButton_Click(object sender, EventArgs e)
{
if (CurrPage < MaxPage)
{
CurrPage++;
BindItems();
}
}
protected void PrevPageButton_Click(object sender, EventArgs e)
{
if (CurrPage > 0)
{
CurrPage--;
BindItems();
}
}
}
public class Book
{
public string Name { get; set; }
public string Description { get; set; }
public Book(string name, string desc)
{
Name = name;
Description = desc;
}
}
}
You can use the jquery tablesorter plugin and the jquery.tablesorter.pager plugin to accomplish this. It will work on a standard html table, and has a lot of options such as alternate row hilighting, sorting, etc.
It depends on how many records at max will be returned. The most efficient way would be
Implement Pagination numbers as links which differ in query parameter.
Based on the query parameter, in the server side, fetch the records corresponding to that page alone. eg. if your page size is 10 and the current page is 2 , fetch only 11,20 records from the server and bind it to html table.
If you are using LINQ to SQL , use Take and SKIP methods as in http://blog.ofiryaron.com/blog/post/Pagination-on-Linq-to-SQL-childs-play!.aspx
If you are using direct SQL queries or Stored procs , make use of RowID to fetch that pages records.

Getting data from a checkbox inside a template column of asp.net gridview

This seems like something simple, but I can't seem to figure it out! I'm trying to get 2-way data-binding to work on an ASP.net page with a check box as one of the columns. How do I get the updated values (from check boxes) back from the gridview ?????
Here is my data type:
[Serializable]
public class UserRequirements
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserId { get; set; }
public string Email { get; set; }
public bool ThingRequired { get; set; }
}
My markup looks something like this:
<form id="form1" method="post" runat="server" >
<asp:GridView ID="UserTable" runat="server" AutoGenerateColumns="false" >
<Columns>
...
<asp:TemplateField HeaderText="Required ?">
<ItemTemplate>
<asp:CheckBox id="chkBox1" runat="server" on
Text ="Required"
checked='<%# DataBinder.Eval(Container.DataItem,"ThingRequired") %>'>
</asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button id="thebutton" Text="Save Changes" OnClick="UpdateRequirements" runat="server" CausesValidation=false />
</form>
My code behind looks something like this:
List<UserRequirements > _userList = new List<UserRequirements >();
protected void Page_Load(object sender, EventArgs e)
{
_userList = data_layer.GetUserRequirments();
this.UserTable.DataSource = _userList;
this.UserTable.DataBind();
}
Eventually, I will call something like this, but I don't know where this should go or how to get the values back from the gridview:
void UpdateRequirements(object sender, EventArgs e)
{
_userList = ???????????? // How do I get the data?
data_layer.UpdateUserRequirements( _userList );
}
foreach (GridViewRow di in GridView1.Rows)
{
HtmlInputCheckBox chkBx = (HtmlInputCheckBox)di.FindControl("chkBox1");
if (chkBx != null && chkBx.Checked)
{
/// put your code here
}
}
try something like this to get the value on change:
protected void OnCheckedChanged(object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender as CheckBox;
string checkBoxId = c.ID;
bool checkBoxValue = c.Checked;
//update database
}
[EDIT]
If you want to get all the values from the rows in the grid in one go, you will need to bind the checkboxes using the Id for the row or item in your list of UserRequirements, so in your grid do something like this:
<asp:CheckBox ID="<%# Eval('Id') %>" />
then on postback, iterate through the items in the UserRequirements list matching the object/item Id with the Ids of the checkboxes in the grid .. something like this:
foreach (UserRequirement item in Requirements)
{
Control c = grid.FindControl(item.Id);
CheckBox cbx = c as CheckBox;
if (cbx != null)
{
bool value = cbx.Checked;
//update db
}
}
Note: you may need to use FindControl recursively to search child controls, or do a foreach on each GridViewRow object in the grid to pickup the checkbox you are looking for.

Resources