I having a problem maintaining a list of strings. The list is instantiated in OnInit and set as the data source for a GridView. (The basic idea is that the user enters something in the text box, and it appears in the GridView, as many times as they want.)
It works just fine for the first entry, whatever the user enters shows up in the GridView, pretty as can be. However, on following entries, any previously entered values disappear - OnInit is executed again, the List<string> is re-instantiated, and the previous values are over-written. I tried moving the OnInit logic into OnPreInit but just got a Null Reference Exception on the list.
Here's a contrived example of what I'm trying to do:
I have a TextBox, a Button and a Gridview:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add"
onclick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="true"></asp:GridView>
In the code behind:
protected override void OnInit(EventArgs e)
{
List<string> gvValues = new List<string>();
GridView1.DataSource = gvValues;
GridView1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
gvValues.Add(TextBox1.Text);
GridView1.DataBind();
}
I've created objects in OnInit in the past, and haven't had a problem with their state persisting. Obviously I'm missing something here. Someone please point out the flaw in my logic and suggest a method for achieving this functionality.
The below code is tested an it works.
// ASPX Code
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add"
onclick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="true"></asp:GridView>
// Code Behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<string> gvValues = new List<string>();
GridView1.DataSource = gvValues;
GridView1.DataBind();
Session["Data"] = gvValues;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
List<string> lt = new List<string>();
lt = (List<String>)Session["Data"];
lt.Add(TextBox1.Text);
GridView1.DataSource = lt;
GridView1.DataBind();
Session["Data"] = lt; // Save it in Session, so next time available
}
// Add the values one by one, and it will show you all the values
// OUTPUT
Test
Test1
Test2
Have you tried to reassign the list to the gridview and put the gvValues into the session:
protected override void OnInit(EventArgs e)
{
GridView1.DataSource = GvValues;
GridView1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
GvValues.Add(TextBox1.Text);
GridView1.DataSource = GvValues;
GridView1.DataBind();
}
private List<string> GvValues
{
get
{
if(Session["list"] != null)
{
return (List<string>)Session["list"];
}
return new List<string>();
}
set
{
Session["list"] value;
}
}
I did a small example which worked fine for me
default.aspx
<form id="form1" runat="server">
<asp:GridView ID="gvEntries" runat="server" AutoGenerateColumns="true">
</asp:GridView>
<asp:TextBox ID="txtNewEntry" runat="server"></asp:TextBox>
<asp:Button ID="btnSave" runat="server" Text="Save entry" OnClick="btnSave_Click" />
</form>
default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<string> source = new List<string>();
source.Add("entry1");
source.Add("entry2");
source.Add("entry3");
Session["source"] = source;
gvEntries.DataSource = source;
gvEntries.DataBind();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
List<string> source = (List<string>)Session["source"];
source.Add(txtNewEntry.Text);
gvEntries.DataSource = source;
gvEntries.DataBind();
}
This example binds your initial data on pageLoad (GET). So your datasource is stored within the gridviews viewstate. If you want to add another entry you have to access your original source - which has been stored within a Session-var. So get a reference to it, add a value, and rebind your dataSource.
Related
I am trying to store the text of the currently selected item of an Asp:Listbox in a variable. The value is always stored a null, or I receive the error
"System.NullReferenceException: 'Object reference not set to an instance of an object.'"
Listbox declaration below
<asp:ListBox ID="lbModules" runat="server" AutoPostBack="true" OnSelectedIndexChanged="lbModules_SelectedIndexChanged" ></asp:ListBox>
Code for SelectedIndexChanged below
`
protected void lbModules_SelectedIndexChanged(object sender, EventArgs e)
{
string code = lbModules.SelectedItem.Text;
int week = 1;
UpdateTextBox(week, code);
}
`
The listbox is being populated elsewhere with a method looping and adding values with listbox.items.add
I have tried
listbox.SelectedItem.Text, listbox.SelectedValue.Text, listbox.SelectedItem.Value, listbox.SelectedValue.Value,
Nothing I try returns the text of the selected value, always throws an exception or returns null.
Ok, first up, it does not make much sense to use the selected index change event UNLESS you have a autopostback=true.
So, if the user is to enter some info into text box etc., then the user say hits your submit button, then I not really sure of any value of using the selected index change event. But, with autopost-back it does.
hence, this markup:
<h2>Select Hotels</h2>
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true"
DataValueField="ID"
DataTextField="HotelName"
OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"
Width="190px" Height="160px" >
</asp:ListBox>
<h3>Selected value</h3>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
And code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL =
"SELECT ID,HotelName FROM tblHotelsA ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
ListBox1.DataSource = rstData;
ListBox1.DataBind();
}
}
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListBox1.SelectedIndex >= 0)
{
TextBox1.Text = ListBox1.SelectedItem.Value;
TextBox2.Text = ListBox1.SelectedItem.Text;
}
}
Note VERY but BEYOND careful that we ONLY load the listbox ONE time. Since for any event trigger on a page, the on-load event fires first, and THEN you code stub for the given button or event. Thus, if you load up the lb, or grid or in fact "any" data, but fail to include the all important if !IsPostBack code stub?
Then you cannot actually build a working web page!!! (so, my last 200+ web pages I have built ALL have and ALWAYS have that real first page load, since as noted, the on-load event triggers always on post-backs. So, if you load up the lb or anything again, it will blow out and overwrite your selections you have made).
So, above results in this:
However, if user is to enter data, select things, and THEN hit a submit button, then of course you probably would remove the autopostback = true. And place the above code behind the button click, and NOT use the selected index change event.
Even if you add items to the lb with code, the above rules still apply.
So, say this listbox:
<h2>Select Hotels</h2>
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"
Width="190px" Height="160px" >
</asp:ListBox>
<h3>Selected value</h3>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
We still need the autopostback, and thus this code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
for (int i = 1; i <= 6; i++)
{
string MyText = "Item # " + i;
ListBox1.Items.Add(new ListItem(MyText, i.ToString()));
}
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListBox1.SelectedIndex >= 0)
{
TextBox1.Text = ListBox1.SelectedItem.Value;
TextBox2.Text = ListBox1.SelectedItem.Text;
}
}
And now we get/see this:
So, either you are missing autopostback, or you are re-running your code to fill the lb each time on post-back, and that will as noted blow out any selecting the user makes.
Is this the right way to bind an object to TextBox in ASP.NET? I'm new to it. I want to get and set data to these text boxes from a database?
txtusername.Value = objBO_MstrUsers.UserName;
txtPassword.Value = objBO_MstrUsers.UserPassword;
TxtUserlevel.Value = objBO_MstrUsers.UserLevel.ToString();
txtUserPhno.Value = objBO_MstrUsers.UserPhone;
txtUserEmail.Value = objBO_MstrUsers.UserEmail;
I want to get and set data to these text boxes from a database.
Assuming you have a simple WebForms page such as:
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtUsername" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
</div>
</form>
this should work:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// populate control with database value
txtUsername.Text = objBO_MstrUsers.UserName;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
// get data from control
objBO_MstrUsers.UserName = txtUsername.Text;
// do anything with the data, e.g. store in database
// ...
}
I'm seeing this behavior on two of my pages, but I'm just going to ask about the one that's more important to me at the moment. I have a page that loads information from a database into a ASP gridview and then allows the user to add a detail to each populated line.
The issue I'm having is that when the 'Edit' button of the gridview and then subsequently the 'Update' or 'Cancel' button, it takes two click to actually fire the onclick event. A post back does take place on the first click, but nothing actually happens.
I'm including the code that seems relevant below. The page uses a master page and there are a number of divs involved with formatting, I'm excluding those.
Gridview and related controls:
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label Text="Plant Selector: " runat="server" />
<asp:DropDownList ID="ddlPlant" OnSelectedIndexChanged="ddlPlant_SelectedIndexChanged" runat="server" />
<asp:Button ID="btnUpdate" Text="Update" OnClick="btnUpdate_Click" runat="server" />
<p />
<asp:Label ID="lblTest" Text="" runat="server" />
<asp:Label ID="lblerror" Text="" ForeColor="Red" runat="server" />
<asp:GridView ID="gridview1" AutoGenerateColumns="false" runat="server" OnRowEditing="gridview1_RowEditing" OnRowCancelingEdit="gridview1_RowCancelingEdit" OnRowUpdating="gridview1_RowUpdating">
<Columns>
<asp:BoundField DataField="JobNum" HeaderText="Job Number" ReadOnly="true" />
<asp:BoundField DataField="ModelNum" HeaderText="Model" ReadOnly="true" />
<asp:BoundField DataField="Customer" HeaderText="Customer" ReadOnly="true" />
<asp:BoundField DataField="SchCompDate" HeaderText="Sch Comp Date" ReadOnly="true" />
<asp:TemplateField HeaderText="Details">
<EditItemTemplate>
<asp:TextBox ID="Txt" Width="98%" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label Text="Click Edit to add details of exception." runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="true" />
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="gridview1" />
</Triggers>
</asp:UpdatePanel>
Sample image below:
Here is the code behind:
private string Plant { get; set; }
// This sets the default plant based off IP.
protected void Page_PreInit(Object sender, EventArgs e)
{
getPlantFromIP();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
populateDDL();
BindData();
}
else
{
Plant = ddlPlant.SelectedValue.ToString();
}
}
// Populates the drop down.
private void populateDDL()
{
ddlPlant.Items.Add("NC");
ddlPlant.Items.Add("WA");
setPlantInDDL();
}
private void setPlantInDDL()
{
if(Plant == "WA")
{
ddlPlant.SelectedIndex = 1;
}
if (Plant == "NC")
{
ddlPlant.SelectedIndex = 0;
}
}
private void getPlantFromIP()
{
if (Request.ServerVariables["REMOTE_ADDR"] == "70.103.118.100")
{
Plant = "WA";
//ddlPlant.SelectedIndex = 1;
}
else
{
Plant = "NC";
//ddlPlant.SelectedIndex = 0;
}
}
// Database Query.
private DataTable getDataFromDatabase()
{
DataTable rTable = new DataTable();
string plant = ddlPlant.SelectedValue.ToString();
using (var conn = new MySqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["workorderConnectionString"].ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
try
{
cmd.CommandText = #"SELECT * FROM reportdatatables.compliance_exception_report
WHERE ExceptionNoted = '0' AND Plant = #plant";
cmd.Parameters.AddWithValue("#plant", plant);
MySqlDataReader reader = cmd.ExecuteReader();
rTable.Load(reader);
reader.Close();
cmd.Dispose();
}
catch
{
}
finally
{
conn.Close();
}
}
}
return rTable;
}
// Binds the data from the database to the gridview.
private void BindData()
{
DataTable data = getDataFromDatabase().Copy();
gridview1.DataSource = data;
gridview1.DataBind();
}
protected void ddlPlant_SelectedIndexChanged(object sender, EventArgs e)
{
//Plant = ddlPlant.SelectedValue.ToString();
BindData();
}
// On edit call.
protected void gridview1_RowEditing(object sender, GridViewEditEventArgs e)
{
}
// On cancel call.
protected void gridview1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridview1.EditIndex = -1;
}
protected void gridview1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
}
protected void btnUpdate_Click(object sender, EventArgs e)
{
BindData();
}
Here's what I've tried:
-A lot of posts a read saw this behavior relating to autopostback settings of controls. As you can see I'm made sure to not have any control with the autopostback set to true.
-I had some concern that the behavior might be related to the updatepanel, but removing it doesn't change the behavior at all.
-I read that having AutoEventWireup="true" in your page tag can cause this. I DO have that in my page tag, but setting it to false does not fix the issue and prevents my dropdown from being populated on page load.
-There was another post that suggested the ID of the control could be changing between page load and post back. I monitored the IDs of those controls and I do not see any change in their ID.
So all that being said, I'm hoping someone has a clue as to what I'm missing. If there is any more information I can provide that might help, please let me know.
Thank you in advance.
Try this, which will make the grid editable
protected void gridview1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
BindData();
}
for cancel also
protected void gridview1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridview1.EditIndex = -1;
BindData();
}
I'm trying to assign the selected value in the drop down to text box when ever I hit a button. I'm not able to see the selected value in the TextBox. Can someone please let me know what am I missing?
My code is as follows:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click1(object sender, EventArgs e)
{
string strConn = "Initial Catalog=NavigateV6;Data Source=SVUSRYE-SQL3D1;User ID=dopis_user;Password=dopis_password;Persist Security Info=True;MultipleActiveResultSets=True";
SqlConnection mycn = new SqlConnection(strConn);
DataSet ds = new DataSet();
SqlDataAdapter myda = new SqlDataAdapter("Select accountid FROM trn_account ", mycn);
myda.Fill(ds);
DDL.DataSource = ds;
DDL.DataTextField = "AccountID";
DDL.DataValueField = "AccountID";
DDL.DataBind();
}
protected void DDL_SelectedIndexChanged(Object sender, EventArgs e)
{
var selectedValue = ((DropDownList)sender).SelectedValue;
if (!string.IsNullOrEmpty(TextBox1.Text))
TextBox1.Text = selectedValue;
}
}
ASPX:
<asp:DropDownList ID="DDL" runat="server" AutoPostBack="True" OnSelectedIndexChanged = " DDL_SelectedIndexChanged" >
</asp:DropDownList>
<br />
<br />
<br />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click1"
Text="sumbit" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
</asp:Content>
jQuery can do that in a snap without a postback:
$('#<%= ButtonID.ClientID %>').click(function() {
$('#<%= TextBoxID.ClientID %>').val($('#<%= DDL_ID.ClientID %>').val());
return false;
});
In fact you don't even need to click a button, it can be done when the user selects a new value in the ddl:
$('#<%= DDL_ID.ClientID %>').change(function() {
$('#<%= TextBoxID.ClientID %>').val($(this).val());
});
Your problem is because when when you check (!string.IsNullOrEmpty(TextBox1.Text)), it always return false because at first stage, value of TextBox is empty and hence never execute inner code of if condition.....If you need to go through above condition, you can put some value in TextBox at the time of declaration.......
Or,
Simply do like this in SelectedIndexChanged of DropDownList
var selectedValue = ((DropDownList)sender).SelectedValue;
TextBox1.Text = selectedValue;
Here is working example as like your code:
ASPX:
<body>
<form runat="server" id="form1">
<asp:DropDownList ID="DDL" runat="server" AutoPostBack="True"
OnSelectedIndexChanged = "DDL_SelectedIndexChanged" >
<asp:ListItem Value="One">One</asp:ListItem>
<asp:ListItem Value="Two">Two</asp:ListItem>
</asp:DropDownList>
<br />
<br />
<br />
<asp:Button ID="Button1" runat="server"
Text="sumbit" onclick="Button1_Click" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
</form>
</body>
Code Behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
}
protected void DDL_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedValue = ((DropDownList)sender).SelectedValue;
TextBox1.Text = selectedValue;
}
}
I have a TextBox control inside a panel and this panel is inside DataList ItemTemplate.
After firing the ItemCommand event, everything works fine except that the TextBox.Text property is always an empty string "" although there is some text in it.
I tried several ways but without success. I would really appreciate if someone can assist me with this. Simplified code is shown below.
Thank you!
ASPX page:
<asp:DataList ID="dlDataList" runat="server" onitemcommand="dlDataList_ItemCommand">
<ItemTemplate>
<asp:Panel ID="pnlReply" runat="server" Visible="False">
<asp:TextBox ID="txtTextBox" runat="server"></asp:TextBox><br />
<asp:LinkButton ID="lnkbtnSend" CommandName="Send" runat="server">Send</asp:LinkButton>
</asp:Panel><br />
<asp:LinkButton ID="OpenPanel" CommandName="OpenPanel" runat="server">Open panel</asp:LinkButton>
</ItemTemplate>
</asp:DataList>
</asp:Content>
ASPX.CS Page code behind
protected void Page_Load(object sender, EventArgs e)
{
FillDataList();
}
private void FillDataList()
{
List<string> list = new List<string>();
list.Add("First");
list.Add("Second");
list.Add("Third");
dlDataList.DataSource = list;
dlDataList.DataBind();
}
protected void dlDataList_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "OpenPanel")
{
Panel pnlReply = (Panel)e.Item.FindControl("pnlReply");
pnlReply.Visible = true;
}
if (e.CommandName == "Send")
{
TextBox txtTextBox = (TextBox)e.Item.FindControl("txtTextBox");
//I tried this way also..
//TextBox txtTextBox = (TextBox)e.item.FindControl("pnlReady").FindControl("txtTextBox");
Label1.Text = txtTextBox.Text;
}
}
Please use IsPostBack in page load event. Without it your FillDataList(); is executing on every postback and resetting your DataList.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
FillDataList();
}
}