If I bind GridView to SqlDataSource, then the first time page will be created, GridView will display columns retrieved from data source. But if on postback I set GridView.DataSourceID to null or to an empty string
protected void Page_Load(object sender, EventArgs e)
{
...
if (IsPostBack)
GridView1.DataSourceID = "";
...
}
, then GridView won’t display any rows at all. But why is that?
Assuming GridView has EnableViewstate set to true, then it should be able to display rows it retrieved from data source when page was first created!
I realize one could argue that Framework notices that DataSourceId has changed and assumes GridView doesn't need data from previous data source, but I’d assume Framework would realize that empty string or null reference doesn’t point to any of data source and thus wouldn’t remove any data GridView retrieved from previous data source?!
thank you
EDIT:
Hello,
Basically what is going on is once you have set the DataSourceID to null or an empty string the control takes this as an indication from the consumer of the control that they do not wish to bind any data at all (even ViewState data). The control checks the DataSourceID prior to binding and if it is an empty string then it does not DataBind in its EnsureDataBound method.
So if you set DataSourceID to null inside Page_Load(), but GridView only checks DataSourceId moments before binding ( which happens much after Page_Load ), then until DataSourceId is checked, ViewState containing data from previous data source should still be available inside Page_Load() ( and still available,for example,inside an event handler subscribed to an event that caused a postback)?!
Your control will not rebind to the ViewState data if you set the DataSourceID to null or an empty string. The article I linked below has an excellent explanation as to why.
Basically what is going on is once you have set the DataSourceID to null or an empty string the control takes this as an indication from the consumer of the control that they do not wish to bind any data at all (even ViewState data). The control checks the DataSourceID prior to binding and if it is an empty string then it does not DataBind in its EnsureDataBound method.
System.What?: DataSource VS. DataSourceID (Internals)
I’d assume Framework would realize
that empty string or null reference
doesn’t point to any of data source
and thus wouldn’t remove any data
GridView retrieved from previous data
source?
Why do you think that way, you reset the value, of course, the girdview has to be bind the new value you reset.
Related
I am not setting my Gridview DataSource to a control like SqlDataSource or ObjectDataSource.
Instead I am Binding manually in the code behind using a method I wrote:
protected void Bind()
{
CustomDepartmentGV.DataSource = GetSortedDepartments();
CustomDepartmentGV.DataBind();
}
I am also manually handing update through the Gridview properties:
OnRowUpdating="UpdateRow"
And a simplified version of the UpdateRow method in the code behind:
protected void UpdateRow(object sender, GridViewUpdateEventArgs e)
{
var oldValues = e.OldValues;
}
When I run the code above the oldValues variable is set to a System.Collections.Specialized.OrderedDictionary class but the keys and values collections within that have 0 keys / values.
After researching this quite a bit I found a couple posts that say that e.OldValues is not set unless you set the Gridview DataSource to a control like SqlDataSource or ObjectDataSource. I do not want to use these as I like the flexibility it gives me to write my own methods in code behind before hitting the data access layer objects.
Does anyone know how I can get e.OldValues working or provide an alternative so I can look at the original values of the row being updated in the UpdateRow method?
Note
I am able to get the original values of the Gridview DataKey fields but I obviously don't want to set every column to be a data key.
Suppose the GetSortedDepartments() method returns a Datatable. You can put this datatable in the session (for example) and in the UpdateRow method use the Datakey of the the current row to get the old values from this datatable.
Don't forget to update the datatable and to put it again in the session after a row is updated.
I have a ObjectDataSource which is placed in de source code of my .aspx page, not the code behind, and is used inside an EditTemplate column of a datagrid.
<asp:DropDownList ID="ddlist1" runat="server" DataSourceID="osCreditType" ...
After selecting a value in the dropdown and setting the datagrid state back to ItemTemplate, I have the ValueMember of that DropDownItem in the NewValues collection inside the RowUpdating Event.
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
int primary = int.Parse(Convert.ToString(e.NewValues[0]));
}
Now, I want to retrieve some other information from the ObjectDataSource using that primary.
Is the data, used for the dropdown still available in the ObjectDataSource, or will a call to that source from code-behind make the datasource go back to the database
Can I use the ObjectDataSource to retrieve additional information using this primary key, and if so, how do I accomplish it ?
Thanks a lot in advance
You have to remember that the ObjectDataSource is really
just a Binder between your Data Layer and Your Controls.
What would be better is for you in the GridView1_RowUpdating routine
is to use a SqlDataAdapter and go and get the information from the database yourself
and then use that information to change the values of the Updated Row.
You will have a problem trying to run another Query with the Same ObjectDataSource,
cause as soon as you do that the control will try to rebind to the new data.
Hope this helps.
I get the above error in my C#/SQL/ASP.NET app because I have a datasource defined both in the ASPX file and the ASPX.CS file. But I want the Gridview to have selectable rows. So if I comment out the ASPX.CS datasource I get the above error but if I comment out the ASPX datasource I get the Gridview output but it is not selectable. How do I code this successfully?
You should only be specifying one or the other. If you want to give the data object directly to the grid, set the DataSource to be that object.
Otherwise, set the DataSourceID to the ID of the datasource that you want to be binding to, and let it do it's thing.
Selectable rows shouldn't have anything to do with where the data is coming from. You can select a row by setting the SelectedRow property. Making them selectable in the UI is a whole different topic.
Sounds like you need to just set the DataSourceID from the markup, and set AutoGenerateSelectButton to true in your markup as well. Your question makes it sound like this is the behavior you are looking for. If you'd rather generate your own select buttons, you should look into either CommandFields, or just adding your own buttons with a CommandName of "Select".
I have AspxGridView on my page. I want users to be able to set up some data on the web form, and after they press one button, the data from screen is being read, validated and bussines object is being created. This object has a GetData() function, and returns an array of objects representing rows in a grid.
I want ASPXGrid not to populate, until user clicks the button. I know I can set DataSourceId in design time to null – but then I lost availability of synchronizing grid columns with object properties (I cannot add or edit some column properties for new columns). I know I can intercept ObjectCreating event and provide grid with an fake object returning empty data sets. But are there any more elegant solutions?
When are you doing the DataBind() call? Couldn't you just place that inside an if block to make sure it only happens on postback?
if(Page.IsPostBack) {
DoDataBindingStuff();
}
ASP.NET 1.1 - I have a DataGrid on an ASPX page that is databound and displays a value within a textbox. The user is able to change this value, then click on a button where the code behind basically iterates through each DataGridItem in the grid, does a FindControl for the ID of the textbox then assigns the .Text value to a variable which is then used to update the database. The DataGrid is rebound with the new values.
The issue I'm having is that when assigning the .Text value to the variable, the value being retrieved is the original databound value and not the newly entered user value. Any ideas as to what may be causing this behaviour?
Code sample:
foreach(DataGridItem dgi in exGrid.Items)
{
TextBox Text1 = (TextBox)dgi.FindControl("TextID");
string exValue = Text1.Text; //This is retrieving the original bound value not the newly entered value
// do stuff with the new value
}
So the code sample is from your button click event?
Are you sure you are not rebinding your datasource on postback?
When are you attempting to retrieve the value from the TextBox? i.e. when is the code sample you provided being executed?
If you aren't already, you'll want to set up a handler method for the ItemCommand event of the DataGrid. You should be looking for the new TextBox value within that method. You should also make sure your DataGrid is not being re-databound on postback.
I would also highly recommend reading through Scott Mitchell's excellent article series on using the DataGrid control and all of it's functions:
https://web.archive.org/web/20210608183626/https://aspnet.4guysfromrolla.com/articles/040502-1.aspx