GridView RowDataBoundEvent not running - c#

I'm working with a GridView and I am using a TableAdapter to communicate with my SQL Server 2017 Express. I have managed to display the table into a GridView but I would like to make the name of each entry in my database have a hyperlink that will direct the user to another page that contains a DetailsView that would allow the user to edit the corresponding entry. However, I am currently have troubles with the RowDataBoundEvent as it seemingly is not triggering.
When I set a breakpoint right at the if statement, the program does not stop at the breakpoint.
protected void ProductViewRowBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
string hyperLink = e.Row.Cells[1].Text;
e.Row.Cells[1].Text = "Test";
//HyperLink link = new HyperLink;
}
}
I checked my RowDataBound method name and it matches the one I specified in the aspx file:
<asp:GridView ID="ProductView" runat="server" Height="299px" Width="578px" AllowPaging="True" HorizontalAlign="Center"
OnRowDataBoundEvent="ProductViewRowBound" style="table-layout:auto">
<HeaderStyle Width="300px" />
</asp:GridView>
CS File:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class Maintenance : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataTable dt = new DataTable();
ProductSetTableAdapters.Product_Table_AlphaTableAdapter productAdapter = new ProductSetTableAdapters.Product_Table_AlphaTableAdapter();
ProductView.DataSource = productAdapter.GetData();
ProductView.DataBind();
}
ProductView.RowDataBound += new GridViewRowEventHandler(ProductViewRowBound);
}
protected void ProductViewRowBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
string hyperLink = e.Row.Cells[1].Text;
e.Row.Cells[1].Text = "Test";
//HyperLink link = new HyperLink;
}
}
}
ASPX File:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Maintenance.aspx.cs" Inherits="Maintenance" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="overflow-x:scroll;overflow-y:scroll; margin-left:auto; margin-right:auto;">
<asp:GridView ID="ProductView" runat="server" Height="299px" Width="578px" AllowPaging="True" HorizontalAlign="Center"
OnRowDataBoundEvent="ProductViewRowBound" style="table-layout:auto">
<HeaderStyle Width="300px" />
</asp:GridView>
</div>
</asp:Content>
Why is my RowDataBoundEvent not running and what can I do to fix it?

First, OnRowDataBoundEvent does not exist. It should be OnRowDataBound in the GridView.
<asp:GridView ID="ProductView" runat="server" OnRowDataBound="ProductViewRowBound">
Next you are binding the correct method to the GridView from code behind, but AFTER you bind data to the GridView. So it will not work when you bind productAdapter.GetData().
So either set the correct event name in the GridView aspx or move the method binding above ProductView.DataBind();

Related

C# Roles.GetAllRoles() error - does not contain a definition

I am trying to get all Roles in my C# application.
When I copy the C# code from: https://learn.microsoft.com/en-us/dotnet/api/system.web.security.roles.getallroles?view=netframework-4.8
into a single aspx page exactly as they have the example then the page works and I can see the Roles and add one properly.
When I have the following code-behind code:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
namespace ToolingPMv2.Admin.Access
{
public partial class Roles : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string[] rolesArray;
rolesArray = Roles.GetAllRoles();
RolesGrid.DataSource = rolesArray;
RolesGrid.DataBind();
}
}
}
}
My aspx page:
<%# Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" CodeBehind="UserRoles.aspx.cs" Inherits="ToolingPMv2.Admin.Access.Roles" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h2>Roles</h2>
<br />
<asp:GridView runat="server" CellPadding="2" id="RolesGrid" Gridlines="Both" CellSpacing="2" AutoGenerateColumns="false" >
<HeaderStyle BackColor="navy" ForeColor="white" />
<Columns>
<asp:TemplateField HeaderText="Roles" >
<ItemTemplate>
<%# Container.DataItem.ToString() %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Content>
I get the following error: 'ToolingPMv2.Admin.Access.Roles' does not contain a definition for 'GetAllRoles'
I thought that if I have 'Using System.Web.Security' I could access this method.
What am I doing wrong? This seems like a basic fundamental lesson that I should know by now.
The class for your page is named Roles so that is hiding the one in the other namespace. You need to be explicit, for example:
rolesArray = System.Web.Security.Roles.GetAllRoles();

GridView not displaying on webpage

I am trying to use gridview to display data from my database but I can't seem to get the gridview to display on the page. I inserted a breakpoint and the gridview shows the correct number of rows in the data source, and the correct number of rows in the gridview after databind. I am still not getting any display on the webpage, when inspecting where it should be with chrome I see the header tag but nothing related to the gridview. What am I doing wrong?
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string id = Request.QueryString["profileID"];
GridView achievementTable = new GridView();
AchievementDatabaseTableAdapters.UserGamesTableAdapter UserGamesAdapter = new AchievementDatabaseTableAdapters.UserGamesTableAdapter();
AchievementDatabase.UserGamesDataTable userGames = UserGamesAdapter.GetUserGames();
achievementTable.DataSource = userGames.Select("ProfileID =" + id).CopyToDataTable();
achievementTable.DataBind();
}
}
.aspx code
<%# Page Title="Profile" Language="C#" AutoEventWireup="true" CodeBehind="Profile.aspx.cs"
MasterPageFile="~/Site.Master" Inherits="AchievementProject.Profile" %>
<asp:Content ID="ProfileContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%: Title %></h2>
<asp:Gridview ID="achievementTable" runat="server" AutoGenerateColumns="True"
ShowHeaderWhenEmpty="true" EmptyDataText="Failed"></asp:Gridview>
</asp:Content>
achievementTable is local to the page load event. Move it to at least a protected variable at the class level and it will be available to your views.

ASP.NET web forms user control with DropDownList's SelectedIndex cannot be set

I have created a web forms user control with a DropDownList. I want to change SelectedIndex property of DropDownList1 to change the selected index.
WebUserControl1.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.ControlUI.WebUserControl1" %>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
WebUserControl1.ascx.cs:
using System;
namespace WebApplication1.ControlUI
{
public partial class WebUserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e) {
if (IsPostBack) return;
for (int i = 1; i <= 5; i++) {
DropDownList1.Items.Add("Test: " + i.ToString());
}
}
public void SetSelectedIndex(int index) {
DropDownList1.SelectedIndex = index;
}
}
}
Now I am using the user control in a page.
Default.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<%# Register Src="~/ControlUI/WebUserControl1.ascx" TagPrefix="uc1" TagName="WebUserControl1" %>
<asp:Content ID="HeadContent" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<uc1:WebUserControl1 runat="server" id="WebUserControl1" />
</asp:Content>
Default.aspx.cs:
using System;
using System.Web.UI;
namespace WebApplication1
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e) {
WebUserControl1.SetSelectedIndex(3);
}
}
}
This does not work. It assigns -1 into SelectedIndex property of DropDownList1. But the user control works if I add items into the DropDownList in the markup (WebUserControl1.ascx), rather than in the codebehind file (WebUserControl1.ascx.cs):
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.ControlUI.WebUserControl1" %>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>Test: 1</asp:ListItem>
<asp:ListItem>Test: 2</asp:ListItem>
<asp:ListItem>Test: 3</asp:ListItem>
<asp:ListItem>Test: 4</asp:ListItem>
<asp:ListItem>Test: 5</asp:ListItem>
</asp:DropDownList>
But I need to add items using the codebehind file, not in the markup file. Why it is not working? How to solve the problem?
The issue is that Page_Load for the page containing the user control (Default) executes before Page_Load for the user control (WebUserControl1). Therefore, when SetSelectedIndex is invoked from the page, the drop down does not have any list item in it when the page is first built.
You can solve the issue very simply by creating the list item for the drop down in the Init stage of the user control life cycle rather than in the Load stage:
protected void Page_Init(object sender, EventArgs e) {
if (IsPostBack) return;
for (int i = 1; i <= 5; i++) {
DropDownList1.Items.Add("Test: " + i.ToString());
}
}

Simple ASP.NET File Upload

I have a very simple ASP.NET page that uploads an Excel workbook, then processes it. It uses AJAXFILEUPLOAD from the AJAX toolkit on ASP.NET... Here's the markup:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"
CodeBehind="ImportWorkbook.aspx.cs" Inherits="Timesheet.ImportWorkbook" %>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="HeaderContentPlaceHolder">
<h1 class="topContent">
Upload CPAS Timesheet Workbooks
</h1>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="RightContentPlaceHolder" runat="server">
<br />
<br />
<asp:HiddenField ID="tbTSID" runat="server" />
<asp:HiddenField ID="tbWorkbookPath" runat="server" />
<ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server" AllowedFileTypes="xls,xlsx,xlsm"
CssClass="dropdown" MaximumNumberOfFiles="1" OnUploadComplete="AjaxFileUpload1_UploadComplete" />
<br />
<br />
<asp:Panel ID="ProcessChoices" runat="server" >
<br />
<br />
<p>
Select how you want this workbook processed:</p>
<br />
<asp:RadioButtonList ID="rbChoices" runat="server" BorderStyle="Groove" BorderWidth="2px"
BorderColor="Black" BackColor="Teal" Font-Names="Tahoma" Font-Size="10pt" ForeColor="White"
Width="40%">
<asp:ListItem Value="True" Selected="True">&nbsp Replace ALL Items in the Timesheet</asp:ListItem>
<asp:ListItem Value="False">&nbsp Add Items from this Workbook to the Existing Timesheet Items</asp:ListItem>
</asp:RadioButtonList>
<br />
<br />
<asp:Button ID="btnValidate" runat="server" Text="Validate and Process"
BackColor="#B92217" ForeColor="White" BorderColor="#7C1810"
BorderStyle="Groove" Font-Names="Tahoma" onclick="btnValidate_Click" />
</asp:Panel>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="BottomSpanContentPlaceHolder" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</asp:Content>
The master page and css pages are trivial, formatting only.
Here's the codebehind:
using System;
using System.IO;
using TimesheetUtilites;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;
namespace Timesheet
{
public partial class ImportWorkbook : System.Web.UI.Page
{
private const string HDriveLocation= "H:\\mtv\\secure\\Construction\\Access\\CPAS WorkArea\\TimesheetUploads\\";
private string strWorkbookPath;
private int currTSID;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request.QueryString["ID"] != null)
{
tbTSID.Value = Request.QueryString["ID"]; // Storing the Timesheet ID in a hidden Textbox
}
}
else
{
if (!string.IsNullOrEmpty(tbWorkbookPath.Value))
{
ProcessChoices.Enabled = true;
}
}
int.TryParse(tbTSID.Value, out currTSID);
strWorkbookPath = tbWorkbookPath.Value;
}
protected void AjaxFileUpload1_UploadComplete(object sender, AjaxFileUploadEventArgs e)
{
strWorkbookPath = HDriveLocation + Path.GetFileName(e.FileName);
tbWorkbookPath.Value = strWorkbookPath;
AjaxFileUpload1.SaveAs(strWorkbookPath);
ProcessChoices.Enabled = true;
}
protected void btnValidate_Click(object sender, EventArgs e)
{
bool processOption;
bool.TryParse(rbChoices.SelectedValue, out processOption);
strWorkbookPath = tbWorkbookPath.Value;
TimesheetUtilites.ImportTimesheet imp = new ImportTimesheet(currTSID, strWorkbookPath, processOption);
}
}
}
My issue is simple. Although the event handler "AjaxFileUpload1_UploadComplete" works fine, and uploads the file in an instant, when I fire the "btnValidate_Click" event, the "tbWorkbookPath.Value" has become an empty string, and the "ProcessChoices.Enabled" propety doesn't change. Needless to say, the "Upload Complete" event handler is the only opportunity I have to capture this file path, so I'm at a loss what I'm doing wrong.
I posted on ASP.NET and go NO answers. Can anyone give me an idea where to start?
This is information you should be storing in your page's ViewState so that it persists between postbacks and resets on page initialization. Change your private string member to something like the following:
private string strWorkbookPath {
get {
return this.ViewState["strWorkbookPath"];
}
set {
this.ViewState["strWorkbookPath"] = value;
}
}
If you need a primer on what the ViewState is, check out this article on MSDN: Saving Web Forms Page Values Using View State. It's a bit dated but still communicates the basics of how ViewState operates currently.
Put a hidden field with runat="server" attribute on your page and use the below script:
<script type="text/javascript">
function uploadComplete(sender, args) {
var filename = args.get_fileName();
$("#hiddden_field_id").val(filename);
}
</script>
Now you should be getting the image name in your events.
I think you should try storing that value in session rather than a hidden field as the page is not reloaded and it was an ajax call. So when the button is clicked for validation, it is actually another request made but the value of the hidden field in this page object and the hidden field is still empty. Once your job is done for that value in session, remove it from there or set it to some different value.

Display Session variables in GridView (ASP.NET)?

Just starting with ASP.NET and find it difficult to use the GridView. I have a set of Session variables which I want to put into a GridView control, but I lack the knowledge. The file:
<%# Page Title="Warehouse" Language="C#" AutoEventWireup="true"
MasterPageFile="~/Site.master"
CodeFile="Warehouse.aspx.cs" Inherits="Warehouse" %>
<asp:Content ID="HeaderContent" runat="server"
ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Warehouse
</h2>
<asp:Panel ID="WarehousePanel" runat="server">
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</asp:Panel>
</asp:Content>
In the code behind I want to add the session variables to the GridView1, just for display purposes. Later on it will be connected to a database, but for practice, I want to know how I can add my session variables to the GridView1. The 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 Warehouse : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session["milk"] == null)
Session["milk"] = "0";
if (Session["apple"] == null)
Session["apple"] = "0";
if (Session["orange"] == null)
Session["orange"] = "0";
// on page load, add session variables ie Session["milk"].ToString();
// column 1: inventory name
// column 2: inventory value
GridView1.?
}
}
I might be thinking this all wrong. If I do, please correct me to the right path! Thanx for listening.
It's as simple as putting this in your Page_Load:
// Sample to add a value to session to ensure that something is shown
Session.Add("SessionValue1", "Value");
// Actual work of binding Session to the grid
GridView1.DataSource = Session;
GridView1.DataBind();
There's a Microsoft Knowledge Base article that goes some way to answering your question(s) as it provides some examples of Data Binding in action and links to further articles giving additional detail.
Assuming you had some code such as:
var warehouseItems =
from item in DataTableContainingWarehouseItems.AsEnumerable()
select
new
{
InventoryName = item.Field<string>("Name"),
InventoryValue = item.Field<int>("Value"),
InventoryPrice = item.Field<decimal>("Price"),
StockOnHandValue = Convert.ToDecimal(item.Field<int>("Value") * item.Field<decimal>("Price"))
};
You could then bind directly to that:
GridView1.DataSource = warehouseItems;
GridView1.DataBind();

Categories