Sending GridView into edit mode with the use of a separate button - c#

I've used GridView.EditIndex = -1 to do this, however I always have to click the button twice. If data is already present in the gridview, it is removed from the gridview. Why is this?
I have tried:
this.subBindGrid();
protected void subBindGrid()
{
GridView.Columns[7].Visible = true;
GridView.DataSource = <filepath>.Tables[0].DefaultView;
GridView.DataBind();
}
I have also tried:
GridView.DataBind();
on it's own.
Neither of these have made any difference.

Whenever you click on any control on a page. Than request is sent to the server for new page due to stateless nature of http. Every time you click on button you get a new page with DataSource of gridview is empty. to solve this. after GridView.EditIndex = -1.
Bind your Datasource and subBindGrid(); remember this will work only if <filepath>.Tables[0].DefaultView is not null

Related

Why is my LINQ query giving me old data?

I have the following code in an aspx.cs file:
protected void Page_Load(object sender, EventArgs e)
{
epdc = new edu_portalDataContext();
IQueryable<Assignment> _assignmentsList =
from assignment in epdc.Assignments
select assignment;
assignmentsList = _assignmentsList.GetEnumerator();
assignmentsList.MoveNext();
ListOfAssignments.DataSource = epdc.Assignments;
ListOfAssignments.DataBind();
}
Notes, to make it possible for you to understand the code:
Assignments is the name of the database table from which I'm pulling data.
ListOfAssignments is the ID of a Repeater control.
assignmentsList is used in the ListOfAssignments_ItemDataBound method.
Anyway, this is straightforward enough -- instantiate a data context, send it a basic query, get an enumerator, bind some data to a repeater. This part works. The next part is what confuses me.
Later on in the code, I have a click event tied to a Button control. What I want to happen is, the user enters some data in some fields, the user clicks on the button, the program makes a new record with that data, the program sends it off to the database, the database stores the new data, the Repeater (ListOfAssignments) updates with the new database data, and the user sees the new data on the page.
Here's the code in the click event:
Assignment newAssignment = new Assignment
{
//data is entered here
//...
};
epdc.Assignments.InsertOnSubmit(newAssignment);
epdc.SubmitChanges();
But here's what actually happens: when the user clicks the button, everything goes as expected, except the repeater doesn't update with the new data. I did a little debugging, and here's what I found:
assignmentsList doesn't update with the new database data. I looked around in Visual Studio's variable inspector, and the LINQ query doesn't pull in any of the new data. It's as if the user never entered anything at all. Until they refresh the page, that is: when they refresh, the Repeater updates and shows the new data.
Why doesn't the LINQ query give me fresh data on a postback?
Your click event is happening AFTER Page_Load. So the repeater is rebound before the new data is added. Do your databinding in PreRender.

Custom DropDownList Server Control Losing Items on Postback

I have a custom server control inheriting from DropDownList. On postback, the items are lost. It looks something like this:
public class MyClientSelectList : DropDownList
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// design mode hack to let visual studio display in design mode
if (!DesignMode)
{
if (!Page.IsPostBack)
{
this.Items.Add(new ListItem("Select an item..."));
// add more items from db
}
}
}
}
I checked EnablePostBack = true. I select a selected value in the page load of my page which is hosting this custom server control.
Why are the items lost on postback?
EnableViewState is already True by default, so mshsayem's solution will not work.
There're 2 way to do that, a standard way is to override SaveControlState and LoadControlState Method
Refer to http://msdn.microsoft.com/en-us/library/1whwt1k7(v=VS.100).aspx
Another way is, in the Init, reload list items from database no matter postback or not, then retrieve the selected value from post data and set it back to dropdownlist

Binding GridView in Code-Behind Not Working

I have a very annoying problem that I've been struggling with for a few hours now. I have multiple asp.net GridView controls on a page. One of these grids (grid B), is dependent on another grid (grid a) for its data to update correctly.
The problem I have is this:
When I do gridB.Databind() in a if(!IsPostback), then functionality of Grid B works, but the grid doesn't update with newly added records in Grid A.
When I do gridB.Databind() anywhere else that doesn't contain a Postback check, then the data in grid B updates correctly with the newly added records in Grid A, but then the functionality of Grid B no longer works.
Example:
// Functionality for dropdownlist etc works correctly, but new data from gvA doesn't show in gvB
if (grvSender.ID == "gvA")
{
if (!IsPostBack)
gvB.DataBind();
}
// Functionality for dropdownlist etc no longer works correctly, but new data from gvA shows correctly in gvB
if (grvSender.ID == "gvA")
{
if (IsPostBack)
gvB.DataBind();
}
I've called the databind method for gvB in every possible place known to man and the same problem persists...Fix problem A gives me problem B and fixing problem B gives me problem A.
Any ideas would be great. I can see this being something ridiculously silly but I've stared at the code almost all day now and I'm out of ideas.
You should use Page_PreRender event for your code and you can write your code as follow with else as well.
if (grvSender.ID == "gvA")
{
if (!IsPostBack)
gvB.DataBind();
}
else
{
if (IsPostBack)
gvB.DataBind();
}

Find Unchecked Checkboxes with jQuery and pass the Names to C# Code

This is my code:
public class MyCollection {
internal static Dictionary<string, CheckBox> MyCheckBox = new Dictionary<string, CheckBox>();
}
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
CheckBox chk1 = new CheckBox();
chk1.ID = "chk1";
chk1.Checked = true;
if (!MyCollection.MyCheckBox.ContainsKey(chk1.ID))
MyCollection.MyCheckBox.Add(chk1.ID, chk1);
CheckBox chk2 = new CheckBox();
chk2.ID = "chk2";
chk2.Checked = true;
if (!MyCollection.MyCheckBox.ContainsKey(chk2.ID))
MyCollection.MyCheckBox.Add(chk2.ID, chk2);
pl1.Controls.Add(chk1);
pl2.Controls.Add(chk2);
}
}
protected void btn1Click(object sender, EventArgs e) {
lit1.Text = "Chk1.Checked: " + MyCollection.MyCheckBox["chk1"].Checked.ToString();
lit1.Text += "<br />Chk2.Checked: " + MyCollection.MyCheckBox["chk2"].Checked.ToString();
}
i have 2 checkboxes, but always when press the button, Checkboxes.Checked are true, also when i unchecked them,
how can i hold checkboxes in some dictionary like above and check their Checked property in right way?
actualy i do't want any event for change Checkboxes, I Think about a jQuery script, that when i press the button retrive me the name of checkboxes that unchecked
i find a jQuery that can find the checkboxe names that unchecked but i don't know how can pass the names to the c# code?
my above code is just a sample and real project is a user control that dynamically define and render controls from a type, hmm the scenario is like this: the clients add the assembly of user control and declare a property of that named target type, user control read target and for each property decide which control must be add so by overrided RenderContents and other methods can add controls to page, so every control automatically have a Checkbox that enable/disable control and i need the checked property
i find this code in Stackoverflow...
var sList = "";
$('input[type=checkbox]').each(function () {
var sThisVal = (this.checked ? "1" : "0");
sList += (sList=="" ? sThisVal : "," + sThisVal);
});
console.log (sList);
but this code just write sList on console how can retrive the sList values in C# Code?
Firstly, you should never store an instance of a control such as a CheckBox in a static member since this is a recipe for a memory leak in your application. ASP.NET Control classes hold a reference to their containing Page and so by adding the Control to a static collection you're going to keep the entire Page instance and all its child Controls from being garbage-collected.
Secondly, there's no point in doing this in your case since it isn't going to achieve what you're trying to do. The instance of the CheckBox class that you add to the Dictionary isn't going to be the same instance that you want to interact with on subsequent requests; the instance you store in the Dictionary is for that request only which is why the CheckBox instances are always returning true from their Checked property.
I don't think that JQuery is relevant here since that will not help you reconstitute the CheckBox controls on the server. What you need to do is add the CheckBox controls to the Page on every request. In order for the CheckBox controls to have their state loaded from the Form collection you need to add the Controls early enough in the Page lifecycle: I would recommend trying to add them during the Page.Init event.
public void Page_Init(object sender, EventArgs e)
{
CheckBox chk1 = new CheckBox();
chk1.ID = "Chk1";
CheckBox chk2 = new CheckBox();
ck2.ID = "Chk2";
if(!IsPostBack)
{
ck1.Checked = true;
ck2.Checked = true;
}
p1.Controls.Add(chk1);
p2.Controls.Add(chk2);
}
Without the actual code it is difficult to understand what you're trying to do and how you're going about it. The fact remains, though, that if you don't add the CheckBox controls to the Page on every request then they cannot participate in the Page lifecycle and won't have their state loaded from the Form collection when the Page is submitted. It sounds to me like you want to manipulate the control tree of the Page on the server but that needs to be reconstituted on every request and only exists during the handling of the request. After the Page is rendered to the client the control tree no longer exists.
So, you could POST the values of the HTML input checkboxes to the server using JavaScript but where would you send them and what do you expect to happen? It seems like you're fighting against the ASP.NET Webforms way of doing things which revolves around post-backs and the Page object on the server that handles the request.
Use this one maybe useful this is all of your needed test it and let me know about the result:
Loop through checkboxes and count each one checked or unchecked
Remember please some simple thing: YOU MUST ADD DYNAMIC CONTROLS ON EACH AND EVERY POSTBACK. This will save a lot of your time.

Problem with dynamic controls in .NET

Problem with dynamic controls
Hello all,
I'm wanting to create some dynamic controls, and have them persist their viewstate across page loads. Easy enough, right? All I have to do is re-create the controls upon each page load, using the same IDs. HOWEVER, here's the catch - in my PreRender event, I'm wanting to clear the controls collection, and then recreate the dynamic controls with new values. The reasons for this are complicated, and it would probably take me about a page or so to explain why I want to do it. So, in the interests of brevity, let's just assume that I absolutely must do this, and that there's no other way.
The problem comes in after I re-create the controls in my PreRender event. The re-created controls never bind to the viewstate, and their values do not persist across page loads. I don't understand why this happens. I'm already re-creating the controls in my OnLoad event. When I do this, the newly created controls bind to the ViewState just fine, provided that I use the same IDs every time. However, when I try to do the same thing in the PreRender event, it fails.
In any case, here is my example code :
namespace TestFramework.WebControls
{
public class ValueLinkButton : LinkButton
{
public string Value
{
get
{
return (string)ViewState[ID + "vlbValue"];
}
set
{
ViewState[ID + "vlbValue"] = value;
}
}
}
public class TestControl : WebControl
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Controls.Clear();
ValueLinkButton tempLink = null;
tempLink = new ValueLinkButton();
tempLink.ID = "valueLinkButton";
tempLink.Click += new EventHandler(Value_Click);
if (!Page.IsPostBack)
{
tempLink.Value = "old value";
}
Controls.Add(tempLink);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ValueLinkButton tempLink = ((ValueLinkButton)FindControl("valueLinkButton")); //[CASE 1]
//ValueLinkButton tempLink = new ValueLinkButton(); [CASE 2]
tempLink.ID = "valueLinkButton";
tempLink.Value = "new value";
tempLink.Text = "Click";
Controls.Clear();
Controls.Add(tempLink);
}
void Value_Click(object sender, EventArgs e)
{
Page.Response.Write("[" + ((ValueLinkButton)sender).Value + "]");
}
}
}
So, let's examine case 1, where the line next to [CASE 1] is not commented out, but the line next to [CASE 2] is commented out. Here, everything works just fine. When I put this control on a page and load the page, I see a link that says "Click". When I click the link, the page outputs the text "[new value]", and on the next line, we see the familiar "Click" link. Every subesquent time I click on the "Click" link, we see the same thing. So far, so good.
But now let's examine case 2, where the line next to [CASE 1] is commented out, but the line next to [CASE 2] is not commented out. Here we run into problems. When we load the page, we see the "Click" link. However, when I click on the link, the page outputs the text "[]" instead of "[new value]". The click event is firing normally. However, the "new value" text that I assigned to the Value attribute of the control does not get persisted. Once again, this is a bit of a mystery to me. How come, when I recreate the control in OnLoad, everything's fine and dandy, but when I recreate the control in PreRender, the value doesn't get persisted?
I feel like there simply has to be a way to do this. When I re-create the control in PreRender, is there some way to bind the newly created control to the ViewState?
I've struggled with this for days. Any help that you can give me will be appreciated.
Thanks.
ViewState-backed properties are only persisted to ViewState if the control is currently tracking ViewState. This is by design to keep ViewState as small as possible: it should only contain data that is truly dynamic. The upshot of this is that:
ViewState propeties set during the Init event are not backed to ViewState (because the Page has not yet started tracking ViewState). Thus Init is a good place to add controls and set (a) properties that won't change between postbacks (ID, CssClass...) as well as initial values for dynamic properties (which can then be modified by code in the rest of the page lifecycle - Load, event handlers, PreRender).
When dynamically adding controls in Load or PreRender, ViewState is being tracked. The developer can then control which propeties are persisted for dynamically added controls as follows:
Properties set before the control is added to the page's control tree are not persisted to ViewState. You typically set properties that are not dynamic (ID etc) before adding a control to the control tree.
Properties set after the control is added to the page's control tree are persisted to ViewState (ViewState tracking is enabled from before the Load Event to after the PreRender event).
In your case, your PreRender handler is setting properties before adding the control to the page's control tree. To get the result you want, set dynamic properties after adding the control to the control tree:
.
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ValueLinkButton tempLink = new ValueLinkButton(); // [CASE 2]
tempLink.ID = "valueLinkButton"; // Not persisted to ViewState
Controls.Clear();
Controls.Add(tempLink);
tempLink.Value = "new value"; // Persisted to ViewState
tempLink.Text = "Click"; // Persisted to ViewState
}
As others have statement you'll need to ensure that you are creating via the Init method. To learn more about the ASP.NET page life cycle check out this article: http://msdn.microsoft.com/en-us/library/ms178472.aspx
I'm already re-creating the controls in my OnLoad event.
That's your problem. OnLoad is too late. Use Init instead.
Thank you for your help, but I tried that and it didn't make a difference. Besides, OnLoad works just as well for dynamic controls as OnInit, as long as you give your controls the same IDs every time.
I believe that once you have added the dynamic controls to the page in PageLoad, the ViewState is bound to the controls and the "ViewState still needs to be bound" flag (in concept, not an actual flag) is cleared. Then, when you recreate the controls, the existing ViewState is no longer bound.
I faced something similar last year, only in my case I did not want the ViewState to rebind. My issue is that I was not recreating the previous controls, which is why I think that the pseudo-flag notion above applies.
Try calling Page.RegisterRequiresControlState(). You can also use RequiresControlState() to check if it's already been registered.
ViewState works on the Page and its child objects. The new control in [Case 2] has not been added to the Page (or any of its children). In fact, in case of the code above, the object will be out of scope as soon as the OnPreRender method ends and will be garbage collected.
If you absolutely have to swap out the control, you will need to remove the old control from its parent using Remove() method and add the new control at the right place using AddAt().
If the control was the only child of the parent, the code would be something like the following.
ValueLinkButton tempLink = new ValueLinkButton();
Control parent = FindControl("valueLinkButton").Parent;
parent.Remove(FindControl("valueLinkButton"));
parent.AddAt(0, tempLink);
Control added before SaveViewState method called in control life cycle should persist their values. I would concur with Joe's answer. Check this image
http://emanish.googlepages.com/Asp.Net2.0Lifecycle.PNG
I figured out yesterday that you can actually make your app work like normal by loading the control tree right after the loadviewstateevent is fired. if you override the loadviewstate event, call mybase.loadviewstate and then put your own code to regenerate the controls right after it, the values for those controls will be available on page load. In one of my apps I use a viewstate field to hold the ID or the array info that can be used to recreate those controls.
Protected Overrides Sub LoadViewState(ByVal savedState As Object)
MyBase.LoadViewState(savedState)
If IsPostBack Then
CreateMyControls()
End If
End Sub

Categories

Resources