How to maintain controls through ViewState - asp.net

On my initial pageload I'm trying to add a bunch of textboxes. What I want to do is if a user types something into those text boxes I want to maintain that text. I'm using a placeholder and placing dynamic controls inside of my placeholder. Whenever the page_loads the ViewState is null. I'm sure i'm doing something wrong. Any help is appreciated.
Thanks!
default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
ViewStateMode="Enabled" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" enableviewstate="true">
<asp:PlaceHolder runat="server" ID="myPlacerHolder" EnableViewState="true"></asp:PlaceHolder>
<br />
<asp:Button runat="server" ID="_postbackButton" OnClick="_postbackButton_Click" Text="PostBack" />
</form>
</body>
</html>
Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
if (ViewState["myPlaceHolder"] == null)
for (int i = 0; i < 10; i++)
{
Label myLabel = new Label();
myLabel.Text = i.ToString();
myPlacerHolder.Controls.Add(myLabel);
TextBox rtb = new TextBox();
rtb.ID = i.ToString() + "_TextBox";
rtb.Width = 200;
myPlacerHolder.Controls.Add(rtb);
myPlacerHolder.Controls.Add(new Literal() { ID = i.ToString() + "row", Text = "<br/>" });
}
else
myPlacerHolder = (PlaceHolder)ViewState["myPlaceHolder"];
if (ViewState["myPlaceHolder"] == null)
ViewState["myPlaceHolder"] = myPlacerHolder;
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void _postbackButton_Click(object sender, EventArgs e)
{
// do nothing just cause postback
}
}

There are two problems with your approach:
Assigning a control to the variable myPlacerHolder doesn't put that control in the page. The control remains in the page, and the variable has a reference to a control that is not in the page.
You can't reuse controls created for one page in another page.
Just recreate the TextBox controls each time the page loads, and they will pick up the entered text from the form data that is posted back to the server.

Related

How to bind a generic list of enums to a GridView

I am unable to bind a generic list of enums to a GridView, below are all of the details:
Error Message
The data source for GridView with id 'GridView1' did not have any properties or attributes from which to generate columns. Ensure that your data source has content.
ASPX Page
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Amikids.Pages.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
</form>
</body>
</html>
Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Amikids.Pages
{
public partial class WebForm1 : System.Web.UI.Page
{
public enum Pet
{
Cat = 0,
Dog = 1,
Bird = 2
}
protected void Page_Load(object sender, EventArgs e)
{
List<Pet> pets = new List<Pet>();
pets.Add(Pet.Bird);
pets.Add(Pet.Dog);
GridView1.DataSource = pets;
GridView1.DataBind();
}
}
}
I was not able to figure out how to directly bind a list of enum values to a GridView. As work-around I converted the list of enum values to a list of string values.
Below - Code for Converting list of enum values to list of string values.
public static List<string> ConvertListOfPetsToListOfStrings(List<Pet> pets)
{
List<string> listOfStrings = new List<string>();
foreach (Pet pet in pets)
{
listOfStrings.Add(pet.ToString());
}
return listOfStrings;
}
Below - Code for binding to GridView
GridView1.DataSource = ConvertListOfPetsToListOfStrings(pets);
GridView1.DataBind();
Below - ASPX markup for binding to template field and setting a meaningfull HeaderText.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Type of Pet">
<ItemTemplate>
<%# Container.DataItem %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Best way to display Dynamic Content (From Database) in ASP.NET Web Page

I want to display my database table's one row content like as below frame. Table have Photo and description column. I also want two buttons like mentioned in image for some action. my database table have around 100 plus records. so in my web page I want to display 100 frame like below at runtime because it's possible that in future this record may goes up to 1000.
I am new in Web Application development. Anyone suggest me best GUI control to achive my goal with ASP.NET. Any tutorial or sample link will be great help.
Thanks.
First you create a user control with that design as I see here.
Then you use this user control inside a repeater and pass the database parameters to the user control to make the correct render. Additional you can use and DataView the same way.
working example
The custom control:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ShowData.ascx.cs" Inherits="Dokimes_StackOverFlow_ShowData" %>
<asp:Literal runat="server" ID="txtTheID" EnableViewState="false" />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<hr /><br />
and the code behind:
public partial class Dokimes_StackOverFlow_ShowData : System.Web.UI.UserControl
{
public int cValueID = -1;
protected void Page_Load(object sender, EventArgs e)
{
txtTheID.Text = cValueID.ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
}
}
and the main page that is use it:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<uc1:ShowData ID="ShowData1" runat="server" cValueID="<%# GetID(Container.DataItem) %>" />
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
and the code behind
public partial class Dokimes_StackOverFlow_ShowRepeatedData : System.Web.UI.Page
{
List<int> oMainIds = new List<int>();
override protected void OnInit(EventArgs e)
{
for (int i = 0; i < 10; i++)
{
oMainIds.Add(i);
}
Repeater1.DataSource = oMainIds;
Repeater1.DataBind();
base.OnInit(e);
}
protected void Page_Load(object sender, EventArgs e)
{
}
public int GetID(object oItem)
{
return (int)oItem;
}
}
You can use listview control because it supports custom formatting. repeater is the second option but listview has more features than repeater.

ASP Data-binded dropdown list without autopostback

I have a simple form with a dropdown list binded to a string array (as a simple example). The form is submitted when the user clicks a button.
I want to query the selected item in the list. I read the SelectedValue member of the dropdownlist which always contains the default item no matter what I select in the form.
I can't use autopostback on the list as in my production environment the form is displayed in dynamic div using jquery.
If I remove the binding and add the list items in the asp file using ListItems tags, than it magically works.
My sample asp code:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
<br />
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</div>
</form>
</body>
</html>
And the code-behind file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string[] items = { "bindItem1", "bindItem2", "bindItem3" };
DropDownList1.DataSource = items;
DropDownList1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
string text = TextBox1.Text;
string item = DropDownList1.SelectedValue;
}
}
In the page_load do the databinding only if Page.IsPostBack==False.
if (!IsPostBack)
{
//do the data binding
}
Your code now on every page load, will bind the data again and again, so the selected value is "not" changing.

Why do I get the result zero when I try to get the width of a DropDownList control in asp.net?

After I click button1, it display 0, why? How can get correct width of a DropDownList control? Thanks!
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
</asp:DropDownList>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Button1.Text = DropDownList1.Width.Value.ToString();
}
}
It's because the value Width is not set. In html, when the width value is not set, you let the browser choose the size.
Moreover, the asp.net engine only host properties to be able to render the correct Html. If you look at the code of the textbox, you will see that if you put a witdh, it will produces a style="width:yourvalue". ASP.net runs on the server side, so it do not have any idea of the actual size of the control.
If you actually require the client size of the dropdownlist, either specify it explicitly, or use some custom javascript to calculate the actual size of the control, then to pass the calculted size to an hidden field. In the code behind you be able to get the value from the Page.Request.Form collection.
Please clarify your need if you need further explanation.

Required field validator for multiple dropdown lists in an aspx page

I have an aspx page which has 18 (yes 18) dropdown lists and 18 text boxes. Each dropdown needs to be selected and each textbox needs to be filled. Dragging and dropping required field validators on these 36 controls and maintaining them is a painful task and does not seem to be the logical option as all I need is for the user to select a value from the dropdown.
Is there anyway I can loop through all these dropdown controls and textbox controls, check if they are empty and display warnings to users accordingly? Client-side validation solution or server side validation solution is fine with me.
Use a CustomValidator and have a client script function that makes sure every text box/drop down has a value.
One suggestion is to loop through all the controls on the page, use recursive function to dynamically bind RequiredFieldValidator to the found controls. You can tweak my code to suit your needs.
This code has some drawbacks though:
Use control.ID instead of associated label text
Adding RequiredFieldValidator to the page.controls will modify its ControlCollection. This will break the foreach method. Thus, I can only add RequiredFieldValidator to Panel instead.
.aspx
<asp:Panel ID="pnlValidation" runat="server">
</asp:Panel>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList1" runat="server" />
<asp:DropDownList ID="DropDownList2" runat="server" />
<asp:DropDownList ID="DropDownList3" runat="server" />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" />
.cs
protected void Page_Load(object sender, EventArgs e)
{
AddValidator(this);
}
private void AddValidator(Control ctrl)
{
if (ctrl is TextBox || ctrl is DropDownList)
{
RequiredFieldValidator rfv = new RequiredFieldValidator();
rfv.ControlToValidate = ctrl.ID;
rfv.Display = ValidatorDisplay.Dynamic;
rfv.ErrorMessage = ctrl.ID + " is required<br />";
pnlValidation.Controls.Add(rfv);
}
foreach (Control subctrl in ctrl.Controls)
AddValidator(subctrl);
}
If you are dynamically generating the textboxes and dropdownlists, you would probably want to dynamically generate the validation controls as well, but if all the drop down lists and textboxes are static you can use the following:
Use a CustomValidator Web Control, write client side javascript method that checks all the properties of the drop down lists and the textboxes and configure the web control's ClientValidationFunction with the function and set EnableClientScript=true. Also, b/c not all users have javascript enabled, plus to be sure as it is best practice, always also create a server side validation function as well and call Page.IsValid() on the submit action.
.aspx Sample Code
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs"
Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script language="javascript" type="text/javascript">
function ValidateMe(sender, args) {
var txt = document.getElementById("txt");
if (txt.value != "")
args.IsValid = true;
else
args.IsValid = false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox id="txt" runat="server" />
<asp:CustomValidator ClientValidationFunction="ValidateMe" ID="custval"
runat="server" ErrorMessage="Fail" onservervalidate="custval_ServerValidate" />
<asp:Button ID="btn" runat="server" Text="push" onclick="btn_Click1" />
</form>
</body>
</html>
c# codebehind sample code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Threading;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void btn_Click1(object sender, EventArgs e)
{
if (Page.IsValid)
{
btn.Text = "PASS";
}
else
{
btn.Text = "FAIL";
}
}
protected void custval_ServerValidate(object source, ServerValidateEventArgs args)
{
if (txt.Text != "")
custval.IsValid = true;
else
custval.IsValid = false;
}
}

Resources