I have a GridView in a page with paging enabled (sorting not enabled, not used). OnRowDataBound and OnPageIndexChanged events are assigned.
<asp:GridView ShowHeader="False" ID="GV1" runat="server" AutoGenerateColumns="False" OnRowDataBound="gridView_RowDataBound" DataSourceID="SqlDataSource1" GridLines="None" CellPadding="0" PageSize="25" AllowPaging="True" OnPageIndexChanging="GV1_PageIndexChanging">
Datasource is assigned just below gridview as:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:my_connectionstring %>"></asp:SqlDataSource>
OnRowDataBound is used to display content in a formatted way. I don't think it causes any problem:
Protected Sub gridView_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs).....
PageIndexChanging is defined as follows:
Protected Sub GV1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs)
GV1.PageIndex = e.NewPageIndex
GV1.DataBind()
End Sub
In Page_Load Part here's how I populate datasource. It's from custom query constructed in string tempSqlStr:
SqlDataSource1.SelectCommand = tempSqlStr
If Not Page.IsPostBack Then
GV1.DataBind()
End If
Everything seems to be working, I get results paged by 25 records, I can move through pages. But what I recognized is the content of pages are changing as I move between them. The amount of records do not change but I can see a record I saw on first page again in second, when I move back to first page and then again to second page content of second page changes and I see a different set of records.
I have printed tempSqlStr value to all pages, it is same on all pages (it is not in "not page.ispostback" part).
Can it be because I construct tempSqlStr in Page_Load section and GV1_PageIndex_Changing cannot see the value? If this is the case why following pages showing record?
Any comment is appreciated. Thank you.
The problem is most likely that you are not ordering the results returned and that is why. Execute your select statement 5 times and see if the results are the same and you will know if it is this. If it is then add an order by in your query. Let me know if this solved your problem otherwise we can look further...
Related
I have a DataGridView control on a TabPage of a Windows Form application.
When the user moves the mouse over the DataGrid and uses the scroll wheel, the grid scrolls as expected. But when the user clicks in a cell on the screen, instead of the cell receiving focus, the DataGrid resets to the top and requires the user to scroll down again. This response is non-intuitive since it's not immediately obvious that the cell you thought you clicked on isn't there anymore.
I would be happy to prevent the DataGrid from responding to the scroll wheel until the user clicks in the grid, or preferably to maintain the current actions except not resetting to the top when first clicked.
From what I've researched here, it appears that the DataGrid is rebinding because I'm resetting the binding when the tabpage is entered (since the database might have been updated by one of the other tabs.
Private Sub TabPage1_Enter(sender As Object, e As EventArgs) Handles TabPage1.Enter
LoadTACTable()
End Sub
In LoadTACTable():
dbGetList("spSelectTACList", dtTACs, 0, 100000, Nothing) ' Record numbers are 0 based
bsTACs.DataSource = dtTACs
With gridTACs
' TOTAL Grid width = 1380
.DataSource() = bsTACs
.
.
.
(Showing only part of the code for brevity.
Is there a way to see if the TabPage is already displayed when entered? Or, is unnecessary to reset the gridTAC datasource every time I retrieve the data from the SQL database to the dtTACs datatable using my dbGetList() sub?
There are several possible solutions to your problem. One would be to not automatically rebind the datagrid but let the user do it by clicking some refresh button. That way the user would not see non-intuitive behavior.
You mentioned that the contents of one tab may need to be refreshed when the contents of other tabs are changed. Whenever the contents of a tab is changed and can affect other tabs, you could flag these other tabs (for example, by adding a star to their titles) to indicate that they no longer have the latest data. The user would then know that the tab needs to be refreshed.
There might be other solutions, but it is difficult to tell without knowing more about your use case.
With the guidance above, I believe I solved the issue:
I created a flag:
Dim TabDirty As Boolean
Then I set it in the TabPage.Leave handler:
Private Sub TabPage1_Leave(sender As Object, e As EventArgs) Handles TabPage1.Leave
dtTACs.Dispose()
TabDirty = True
End Sub
Then I just check it when I enter the TabPage:
Private Sub TabPage1_Enter(sender As Object, e As EventArgs) Handles TabPage1.Enter
If TabDirty = True Then
TabDirty = False
LoadTACTable()
End If
End Sub
So far, this appears to work - the grid is not getting reset when clicked, but I will do a bit more testing to confirm that the data is refreshed when necessary.
I have a WebForms application. Among other things, it has a Search box, a repeater, and a label totalItems that displays the count of the items in the repeater. The repeater is populated in a method called from Page_Init() method, based on a text entered into the Search control. For some reason, if I run the application with nothing in the Search control, and then second time with a text in the Search control, the content of the repeater changes accordingly, but the totalItems label is not updated. I debugged it and know that totalItems.Text is set to the correct value.
Here is the code:
In .aspx:
<div class="col-md-6">
<div class="makeblock">
<asp:Label ID="totalItems" CssClass="totalItems" Runat="server"></asp:Label>
</div>
</div>
In .aspx.cs:
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
InitializeComponent()
If Not IsNothing(Request.QueryString("group")) Then
buildTable(CInt(Request.QueryString("cat")), CInt(Request.QueryString("group")), CurrentPage)
End If
End Sub
Sub buildTable(ByVal itemCat As Integer, ByVal itemGroup As Integer, Optional ByVal pageNo As Integer = 1)
...
totalItems.Text = "Total Items: " & numItems.ToString()
...
itemRepeater.DataSource = pageds
itemRepeater.DataBind()
End Sub
To sum up some suggestions from the comments and discussion:
Generally speaking you should use the Page_Load() method as it ensures that all your page controls are properly loaded. Furthermore, you should guard your Page_Load() method with a check of the IsPostBack property to prevent re-populating your Repeater accidentally when handling another event, such as an OnItemCommand event from the repeater itself.
To help improve the architecture and to possibly expose some of the reasons why things are not updating as expected, I would suggest you separate the database operations, repeater population, and label updates into different methods. Then have a method that composes them together, calling them in proper sequence.
As for paging the repeater...the repeater is a very basic control that requires a lot of effort to do custom things with...the Web Forms event lifecycle can trip up even the most experienced of people. My suggestion would be to look into other SO questions about doing custom paging with repeater or other resources on the web to make sure you don't go down a path to insanity. You may find that something like a DataGrid could get the job done, although it is opinionated in its output and formatting.
I have a gridview with following sqldatasource code:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TSOstring %>" SelectCommand="TSOList" SelectCommandType="StoredProcedure">
I am using a textbox and button to search the value in the gridview. I am trying to control this from the code behind with the following code in the search_button click event.
SqlDataSource1.SelectCommandType = SqlDataSourceCommandType.StoredProcedure;
SqlDataSource1.SelectCommand = "[dbo].[TSOSearchByDie]";
SqlDataSource1.SelectParameters.Add("#DieNo", TypeCode.String, txt_die.Text.ToString());
What I want to do is change the sqldatasource1 to a different stored procedure with a parameter called "#DieNo" in it . Pass the textbox value to the parameter and return the result. The problem i have is that it always give me the error "Sys.WebForms.PageRequestManagerServerErrorException: Procedure or function 'TSOSearchByDie' expects parameter '#DieNo', which was not supplied".
Any Thoughts?
Thanks!!
Problem solved. I don't need the # sign in the code!!!
im using asp.net with vb.net in backcode. On my first page, i diplay names of all employees. I want to give that a hyperlink, that when clicked upon shall open the next page with say a querystring and opn only that employees records. Also I want the save the employeeid (which is not shown on page 1) on the second page, cause when i do updates on second page, I want to use that employeeId in "where" clause for update or insert statements.
any ideas?
If you're not concerned about people messing the with query string you can use that and then just get the data out in the next page during the Page_Init or Page_Load using:
HttpContext.Current.Request.Item("EmployeeID")
However, I'm a fan of not using the query string because people tamper with it. You can use the PostBackUrl property of your hyperlink (if you use the asp linkbutton), and in the next page you can use the Page.PreviousPage object to access any objects from the previous page.
<asp:LinkButton ID="lnkEmployeeLink23232" runat="server" CommandArgument="23232" PostBackUrl="NextPage.aspx" Text="Employee Name" />
You'll have to check for IsCrossPagePostBack on the first page to make sure you don't fire databinding unnecessarily, but at that point you should be able to get to the control that fired the postback and from there get the command argument which would be the employee id in question.4
http://msdn.microsoft.com/en-us/library/ms178139.aspx
http://www.developerfusion.com/code/4687/cross-page-postbacks-in-aspnet-20/
If you are using a datagrid or gridview, you can use the hyperlink field:
<asp:hyperlinkfield headertext="Employee Page"
datatextfield="Employee"
datanavigateurlfield="EmployeeID"
datanavigateurlformatstring="Employee.aspx?employeeid={0}" />
I have a DataGridView to which I've set a list of objects to the DataSource. (I'm in VS 2005 using VB.) I created the DataGridView by creating a Data Source of type AssetIdentifier and dragging that Data Source onto my form.
I want to update the DataGridView when the selection in either a combo box or another DataGridView changes. (Below I'm considering a click in another DataGridView.) The following works:
Public Class dlgShowAssets
' class member variable
Private assetIdList As List(Of AssetIdentifier)
' pertinent subs and functions
Private Sub RefreshAssetIdentifierDataGridView()
AssetIdentifierDataGridView.DataSource = assetIdList
End Sub
Private Sub AssetDataGridView_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles AssetDataGridView.CellClick
assetIdList = RepopulateTheList(id)
Me.RefreshAssetIdentifierDataGridView()
End Sub
End Class
In this case, I always knew that assetIdList would have at least one element. I'd update the list, and reset the data source of the DataGridView to that list, and all was well.
When I applied this to another situation, for which I couldn't guarantee that the list would have at least one element, things would work fine as long as I had at least one element in the list, but if the list became empty, the DataGridView threw System.IndexOutOfRangeException a number of times. The rows in the DataGridView would not go away if I went from a non-zero number of elements to zero.
I tried a workaround, which was to remove all of the elements, add one "dummy" element, and then re-bind the list to the control, and it still didn't work.
Also, following all of those exceptions, I'd get other similar exceptions when I hovered over the cells in the DataGridView.
I've been trying to track down this behavior for a few hours. Any insights? Thanks!
Will be happy to add more info if needed.
UPDATE: Some of the members of AssetIdentifier were "Nothing" but I fixed that in the constructor, and the exceptions still occur.
Refactored code and it works ...