Dynamically added bound columns to data grid is inaccessible after post back - c#

Below is my DataGrid : -
<asp:DataGrid ID="dgPlayers" runat="server" Width="100%" AutoGenerateColumns="False" AlternatingItemStyle-BorderWidth="1px" BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px"
CellPadding="3" ForeColor="Black" GridLines="Vertical" OnItemCommand="dgPlayers_ItemCommand" EnableViewState="true">
<FooterStyle BackColor="#CCCCCC" />
<HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<SelectedItemStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:TemplateColumn ItemStyle-CssClass="Edit">
<ItemTemplate>
<asp:Button ID="bEdit" Text="Edit" runat="server" CommandName="UPDATE_RECORD"></asp:Button>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Now on search button click i am adding bound columns to it.
Code for adding bound column is below : -
private void AddColumnsToDataGrid(DataGrid dgPlayers, DataTable dataSource)
{
try
{
List<BoundColumn> colList = new List<BoundColumn>();
string[] colNamesArr = new string[] { "player_id", "full_name","team_name", "role_name", "position_name", "jersey_number" };
for (int i = 0; i < dataSource.Columns.Count; i++)
{
if (i < colNamesArr.Length)
{
BoundColumn column = new BoundColumn();
column.DataField = colNamesArr[i];
//colList.Add(column);
if (i == 0)
{
column.Visible = false;
}
dgPlayers.Columns.Add(column);
}
else
{
break;
}
}
}
catch (Exception)
{
throw;
}
}
Now i am facing issue while i clicked edit button on DataGrid of one of row in it to bind row data to other controls on my page but i am unable to get dynamically bind bound columns in DataGrid ItemCommand....
protected void dgPlayers_ItemCommand(object source, DataGridCommandEventArgs e)
{
switch (e.CommandName.Trim().ToUpper())
{
case "UPDATE_RECORD":
this.GetControl<TextBox>("tbFullName").Text = e.Item.Cells[(int)Column.FullName].Text.Replace(" ", "");
this.GetControl<TextBox>("tbFName").Text = e.Item.Cells[(int)Column.FirstName].Text.Replace(" ", "");
this.GetControl<TextBox>("tbJerseyNum").Text= e.Item.Cells[(int)Column.JerseyNo].Text.Replace(" ", "");
this.GetControl<TextBox>("tbShirtName").Text = e.Item.Cells[(int)Column.ShirtName].Text.Replace(" ", "");
this.GetControl<TextBox>("tbLastName").Text = e.Item.Cells[(int)Column.LastName].Text.Replace(" ", "");
this.GetControl<TextBox>("tbShortName").Text = e.Item.Cells[(int)Column.ShortName].Text.Replace(" ", "");
}
}
Any Help on this...

You need to recreate the columns during the post backs. Try invoking the AddColumnsToDatagrid during subsequent postbacks in the load event.

Related

Gridview paging error: Specified argument was out of the range of valid values

I'm trying to enable paging for my gridview, however I'm always getting error:
"Specified argument was out of the range of valid values. Parameter name: index"
If i ignore the error the gridview creates the paging and works fine, but there is an error ignored...
This is my grid:
<asp:GridView ID="gvDeslocFinal" runat="server" Height="181px" Width="1042px" OnRowDataBound="gvDeslocFinal_RowDataBound" AutoGenerateColumns="false" AllowSorting="true" OnSorting="gvDeslocFinal_Sorting" OnPageIndexChanging="gvDeslocFinal_PageIndexChanging" OnSorted="gvDeslocFinal_Sorted" AllowPaging="True" OnRowCreated="gvDeslocFinal_RowCreated" PageIndex="1">
<Columns>
<asp:BoundField DataField="Utilizador" HeaderText="Utilizador" />
<asp:BoundField DataField="Carro" HeaderText="Carro" />...
<ItemStyle CssClass="hidden-field" />
</asp:BoundField>
<asp:TemplateField HeaderText="Detalhes">
<ItemTemplate>
<asp:LinkButton ID="lnkEdit" Text="ver detalhes" OnClick="lnkEdit_Click" runat="server"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EditRowStyle HorizontalAlign="Center" />
<HeaderStyle VerticalAlign="Middle" HorizontalAlign="Center" Font-Bold="False" Height="30px" />
<RowStyle HorizontalAlign="Center" VerticalAlign="Middle" Height="20px" />
</asp:GridView>
protected void gvDeslocFinal_Sorted(object sender, EventArgs e)
{
if (gvDeslocFinal.EditIndex >= 0)
return;
BindGrid();
}
BindGrid function:
private void BindGrid()
{
try
{
for (int i = 0; i < GlobalOffline.DesTerm.Length; i++)
{
string sDataIn = smtgh;
...
string sCodigo = GlobalOffline.DesTerm[i].Codigo;
string[] sRow = new string[] { sCarro, ..., sCodigo };
GlobalOffline.dtResult.Rows.Add(sRow);
}
gvDeslocFinal.DataSource = GlobalOffline.dtResult;
gvDeslocFinal.VirtualItemCount = GlobalOffline.dtResult.Rows.Count;
GlobalOffline.bDetails = false;
gvDeslocFinal.DataBind();
}

How to make an instance of dropdown list object in a button_click event

Some one please tell me why am getting this error when I click button1
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
The issue is with the dropdown lists. How can I create an instance of them in the button1_ click event?
protected void Button1_Click(object sender, EventArgs e)
{
string day = String.Empty;
string time = String.Empty;
string moduleId = string.Empty;
string moduleName = string.Empty;
DataTable dt = new DataTable();
dt.Columns.Add("ModuleID");
dt.Columns.Add("ModuleName");
dt.Columns.Add("Day");
dt.Columns.Add("Time");
foreach (GridViewRow row in GridView1.Rows)
{
DropDownList ddl_day = new DropDownList(); // wont work, I tried it!
day = ((DropDownList)row.FindControl("ddl_day")).SelectedItem.Value;
time = ((DropDownList)row.FindControl("ddl_time")).SelectedItem.Value;
DataRow dr = dt.NewRow();
// dr[0] = row.Cells[i].Text;
/* dr["ModuleID"] = moduleId;
dr["ModuleName"] = moduleName;*/
dr["Day"] = day;
dr["Time"] = time;
dt.Rows.Add(dr);
}
DataSet ds = new DataSet();
ds.DataSetName = "Student_module_data";
ds.Tables.Add(dt);
ds.WriteXml(#"E:\OBJECT ORIENTED DEV'T\xml_data\testing.xml");
}
Here is my html
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" CellPadding="3" OnRowDataBound="OnRowDataBound">
<Columns>
<asp:TemplateField HeaderText="Day">
<ItemTemplate>
<asp:DropDownList ID="ddl_days" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Time">
<ItemTemplate>
<asp:DropDownList ID="ddl_time" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Select" ShowSelectButton="True" />
</Columns>
<FooterStyle BackColor="White" ForeColor="#000066" />
<RowStyle ForeColor="#000066" />
<SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
<HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
</asp:GridView>
It look like following line return with null
((DropDownList)row.FindControl("ddl_day"));
And as you are try to use its property it is giving null reference error. So check if it is null or not.
var ddl_day = ((DropDownList)row.FindControl("ddl_day"));
if(ddl_day!=null)
{
day = ddl_day.SelectedItem.Value;
}
Check Same for other dropdown also.
Change the DropdownList ID from ddl_days to ddl_day in your HTML code, as Zaki told in the comment. This is the primary issue.

get the ID of any Item in NavigateUrl in GridView

Hello i have this gridview:
<asp:GridView ID="grd1" width="100%" AutoGenerateColumns="False" runat="server" EnableModelValidation="True" CellPadding="4" ForeColor="#333333" GridLines="None" >
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" />
<asp:HyperLinkField DataTextField="Plan Reference" HeaderText="Plan Reference" SortExpression="Plan Reference" NavigateUrl="https://www.yahoo.com?itemid="/>
</Columns>
<EditRowStyle BackColor="#999999" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" HorizontalAlign="Center"/>
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
</asp:GridView>
When I indicate on the plan reference column , then the url appears in the bottom left corner of the window like this: https://www.yahoo.com?itemid=
I want the id of the row that I indicate on it , appear in the url in the bottom left corner of the window, how can I code it?
This is my CS code :
DataTable GetData()
{
SPSite oSiteCollection = SPContext.Current.Site;
SPWeb oWeb = oSiteCollection.OpenWeb();
SPList oSpList = oWeb.Lists["Drill Plans"];
SPListItemCollection oSpListItemCollection = oSpList.Items;
DataTable dt = new DataTable();
try
{
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Plan Reference", typeof(String));
DataRow dataRow;
foreach (SPListItem oSplistItem in oSpListItemCollection)
{
//DateTime date = DateTime.Now;
//string currentDate = String.Format("{0:dddd, MMMM dd, yyyy}", date);
dataRow = dt.Rows.Add();
dataRow["ID"] = oSplistItem["ID"].ToString();
dataRow["Plan Reference"] = oSplistItem["Plan Reference"].ToString();
}
return dt;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Managers Approval" + ex.Message.ToString());
return dt;
}
}
Please help me.
I need a help for important work please
To append the ID of the bound item to the url you can use Container.DataItem like this:
<asp:HyperLinkField
DataTextField="Plan Reference"
HeaderText="Plan Reference"
SortExpression="Plan Reference"
NavigateUrl='https://www.yahoo.com?itemid=<%# Container.DataItem("ID") %>'/>
More info here.
EDIT
In order for the above to work, you need to bind your GridView to the data table returned from method GetData(). In your Page_Load method you should have something like this:
if(!IsPostback)
{
grd1.DataSource = GetData();
grd1.DataBind();
}
Another approach would be to handle the RowDataBound event of your GridView and set the NavigateUrl in there. To do so, you'll need to assign an id to the HyperLinkField (let's call it "link"). Here is the code:
protected void OnGridViewRowDataBound(object sender, GridViewRowEventArgs e)
{
var hyperLink = e.Row.FindControl("link") as HyperLinkField;
if(hyperLink != null)
{
var row = e.Row.DataItem as DataRow;
hyperlink.NavigateUrl = String.Format("https://www.yahoo.com?itemid={0}", row["ID"]);
}
}
Of course, don't forget to add the event handler in your markup:
<asp:GridView ID="grd1" RowDataBound="OnGridViewRowDataBound" ..
</asp:GridView>

GridView row editing

I have a gridview with five BoundFields.when inserting values to the grid i have got textbox fields to the cells and it's working fine.my issue is when editing a row i only need 3 cells to be editable and other two cells should left read only.how can i achieve this?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
CellPadding="4" ForeColor="#333333" GridLines="None" BackColor="WhiteSmoke" CssClass="grid-view"
AlternatingRowStyle-CssClass="alt" PageSize="8"
onrowcancelingedit="GridView1_RowCancelingEdit"
onrowdeleting="GridView1_RowDeleting" onrowediting="GridView1_RowEditing"
onrowupdating="GridView1_RowUpdating"
onrowdatabound="GridView1_RowDataBound"
onrowcommand="GridView1_RowCommand" onrowcreated="GridView1_RowCreated">
<RowStyle BackColor="#EFF3FB" />
<PagerSettings PageButtonCount="5" />
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:LinkButton ID="btnInsert" runat="server"
Text="Insert" CommandName="Insert" ForeColor="White" />
</HeaderTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Edit-Update" ShowEditButton="True" />
<asp:BoundField DataField="DeptID" HeaderText="Department ID"
ReadOnly="True" />
<asp:BoundField DataField="DeptCode" HeaderText="Department Code"/>
<asp:BoundField DataField="DeptDescription" HeaderText="Description" />
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" />
</Columns>
<PagerStyle CssClass="pgr"></PagerStyle>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
Code for inserting values to grid:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert")
{
DataTable DT = new DataTable();
DT = PinCDAO.GetDepartments();
DataRow DR = DT.NewRow();
DT.Rows.InsertAt(DR, 0);
GridView1.EditIndex = 0;
GridView1.DataSource = DT;
GridView1.DataBind();
((LinkButton)GridView1.Rows[0].Cells[1].Controls[0]).Text = "Insert";
}
}
Row уditing code:
GridView1.EditIndex = e.NewEditIndex;
Inserting and updating:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (GetDeptCode())
{
lblMessage.Text = "Already Contains a Department Code with the Same Name";
}
else if (CheckCodeLength())
{
lblMessage.Text = "Department Code Character Length is 3";
}
else
{
if (((LinkButton)GridView1.Rows[0].Cells[1].Controls[0]).Text == "Insert")
{
DepertmentProperties DP = new DepertmentProperties();
DP.DeptCode = ((TextBox)GridView1.Rows[0].Cells[3].Controls[0]).Text.ToString();
DP.DeptDescription = ((TextBox)GridView1.Rows[0].Cells[4].Controls[0]).Text.ToString();
PinCDAO.InsertDepartment(DP);
}
else
{
DepertmentProperties DP = new DepertmentProperties();
DP.DeptID = Convert.ToInt32(GridView1.Rows[e.RowIndex].Cells[2].Text.ToString());
DP.DeptCode = ((TextBox)GridView1.Rows[e.RowIndex].Cells[3].Controls[0]).Text.ToString();
DP.DeptDescription = ((TextBox)GridView1.Rows[e.RowIndex].Cells[4].Controls[0]).Text.ToString();
PinCDAO.UpdateDepartment(DP);
}
GridView1.EditIndex = -1;
BindData();
lblMessage.Text = "";
}
}
Set BoundField's ReadOnly property to "true"

disable a checkbox in gridview

I have a gridview in which the first column in a checkbox. The grid displays one or more records that are returned from the database upon user search (the grid is populated in a proc called "protected void DisplayGridData()"). If the "inactive" column of that record is "1", I would like to have the checkbox disabled. How can I accomplish that?
The html code is:
<asp:GridView ID="gvCanadaOrders" runat="server" AutoGenerateColumns="False" CellPadding="2" CellSpacing="2" GridLines="None" Width="100%" AllowPaging="True" PageSize="30"
onpageindexchanging="gvCanadaOrders_PageIndexChanging" ForeColor="#333333" DataKeyNames="RecID">
<Columns>
<asp:TemplateField HeaderText="Disable" >
<ItemTemplate>
<asp:CheckBox ID="cbPONumber" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
<%--<asp:BoundField DataField="Rec_ID" HeaderText="Rec_ID" HtmlEncode="False"></asp:BoundField>--%>
<asp:BoundField DataField="Inactive" HeaderText="Inactive" HtmlEncode="False" ></asp:BoundField>
<asp:BoundField DataField="PO_Number" HeaderText="PO Number" HtmlEncode="False" ></asp:BoundField>
<asp:BoundField DataField="VENDOR_NAME" HeaderText="Vendor Name"></asp:BoundField>
<asp:BoundField DataField="ITEM_DESC" HeaderText="Item Description"></asp:BoundField>
<asp:BoundField DataField="MFG_PART_NO" HeaderText="MFG Part Number"></asp:BoundField>
<asp:BoundField DataField="System_DATE" HeaderText="System Date"></asp:BoundField>
<asp:BoundField DataField="PRINT_DATE" HeaderText="Print Date"></asp:BoundField>
</Columns>
<FooterStyle CssClass="GridFooter" BackColor="#990000" Font-Bold="True" ForeColor="White" />
<PagerStyle CssClass="GridPager" ForeColor="#333333" BackColor="#FFCC66" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle CssClass="GridHeader" BackColor="#990000" Font-Bold="True" ForeColor="White" />
<RowStyle CssClass="GridItem" BackColor="#FFFBD6" ForeColor="#333333" />
<AlternatingRowStyle CssClass="GridAltItem" BackColor="White" />
</asp:GridView>
The code that loads the gridview is:
protected void btnDisable_Click(object sender, EventArgs e)
{
try
{
string strPONumber = "";
foreach (GridViewRow gvr in gvCanadaOrders.Rows)
{
if (((CheckBox)gvr.FindControl("cbPONumber")).Checked == true)
{
string strRec_ID = gvCanadaOrders.DataKeys[gvr.RowIndex].Value.ToString();
//Update table here, diable inactive field;
SqlConnection con = new SqlConnection(strConn);
string sqlCanadaOrdersUpdate = "usp_CanadaOrders_Close";
SqlCommand cmdCanadaOrdersUpdate = new SqlCommand(sqlCanadaOrdersUpdate, con);
cmdCanadaOrdersUpdate.CommandType = CommandType.StoredProcedure;
cmdCanadaOrdersUpdate.Parameters.Add(new SqlParameter("#rec_ID", SqlDbType.VarChar, 50));
cmdCanadaOrdersUpdate.Parameters["#rec_ID"].Value = strRec_ID;
cmdCanadaOrdersUpdate.Parameters.Add(new SqlParameter("#usr_id", SqlDbType.VarChar, 50));
cmdCanadaOrdersUpdate.Parameters["#usr_id"].Value = User.Identity.Name.Substring(User.Identity.Name.Length - 7);
con.Open();
SqlDataAdapter sqladaCanadaOrdersUpdate = new SqlDataAdapter(cmdCanadaOrdersUpdate);
cmdCanadaOrdersUpdate.ExecuteNonQuery();
}
ClientScript.RegisterStartupScript(GetType(), "alert", "alert('Purchase Order " + strPONumber + " has been disabled.');", true);
}
}
The code for gridview databoundrow is:
void gvCanadaOrders_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Display the company name in italics.
e.Row.Cells[1].Text = "<i>" + e.Row.Cells[1].Text + "</i>";
}
}
Hook in to the RowDataBound event of the GridView. From there, you can cast the DataItem to your record type. A test for the flag then lets you modify the row controls.
I have this code in VB.net and did a quick conversion per your C# tag, so please forgive any errors.
void myGridView_RowDataBound(Object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
MyObject myObj = (myObj)e.Row.DataItem;
if (myObj.flag) {
CheckBox cb = (CheckBox)e.Row.FindControl("myCheckBox");
cb.Enabled=false;
}
}
}
EDIT: Per your edit to the question, you do not have OnRowDataBound in your markup. You would need to add OnRowDataBound="gvCanadaOrders_RowDataBound". It works the same way you've gon OnPageIndexChanging.
Handle the RowDataBound event and use e.Row parameter to find your checkbox.
It won't work on all cases, if you are using the HTML checkbox you should proceed by other by disabling property from CSS:
e.Row.Cells[0].Attributes["disabled"] = "disabled";
Reference link

Categories

Resources