I have a GridView in a ASP.NET web application, in which I have added buttons in each row:
<asp:GridView ID="gridviewdatadosen" runat="server" AutoGenerateColumns="False" CssClass="table table-striped table-bordered table-hover" OnRowDataBound="gridviewdatadosen_RowDataBound" OnSelectedIndexChanged="gridviewdatadosen_SelectedIndexChanged" OnRowCommand="gridviewdatadosen_RowCommand">
<Columns>
<asp:BoundField DataField="NIK" HeaderText="NIK" SortExpression="NIK"></asp:BoundField>
<asp:BoundField DataField="NIDN" HeaderText="NIDN" SortExpression="NIDN"></asp:BoundField>
<asp:BoundField DataField="NAMA" HeaderText="NAMA" SortExpression="NAMA"></asp:BoundField>
<asp:BoundField DataField="Alamat" HeaderText="Alamat" SortExpression="Alamat"></asp:BoundField>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:Button ID="btnstatus" runat="server" Text="Aktif" CssClass="btn btn-primary" CommandName="aktifasi" CommandArgument='<%# Eval("NIK") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I fill the datagridview on the server side. I filled it with taking the data in the database.
DataTable dt = new DataTable();
DataTable dt1 = new DataTable();
SqlConnection conn = new SqlConnection(#"Data Source=localhost;Initial Catalog=SKRIPSI;User ID=sa;Password=sa");
conn.Open();
string ngisi = "SELECT [nik] as 'NIK' , [nidn] as 'NIDN', [nama] as 'NAMA', [alamat] as 'Alamat' FROM [dosen]";
SqlCommand comm = new SqlCommand(ngisi, conn);
dt.Load(comm.ExecuteReader());
conn.Close();
gridviewdatadosen.DataSource = dt;
gridviewdatadosen.DataBind();
int tmp = dt.Rows.Count;
after I fill the datagridview, I wanted to check the status of dosen whether he is active or not by select id and status of dosen.
conn.Open();
string check = "SELECT nik, status FROM [dosen]";
comm = new SqlCommand(check, conn);
dt1.Load(comm.ExecuteReader());
conn.Close();
I have tried to change the existing text on the button but did not succeed.
for (int i = 0; i < tmp; i++)
{
if (dt1.Rows[i][1].ToString() == "Aktif")//check the dosen aktif or not
{
for (int j = 0; j < tmp; j++)
{
if (dt.Rows[j][0].ToString() == dt1.Rows[i][0].ToString())// check nik where status = 'Aktif'
{
// I want to change the button in each row. if he 'Aktif' then the text in button will change to be 'aktif'
//do not know what to do
}
}
}
}
I want to change the button in each row. if he 'Aktif' then the text in button will change to be 'aktif'. help me to solve this problem. Sorry if my english or my explain is bad. Thank You
You can loop all the rows, find the Button and change the Text based on the values in dt1
foreach (GridViewRow row in GridView1.Rows)
{
//find the button in the row with findcontrol and cast back to a button
Button button = row.FindControl("btnstatus") as Button;
//check dt1 and set button text
button.Text = "Active";
}
Or you can do the same on the GridView databinding with the OnRowDataBound event.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//find the button in the row with findcontrol and cast back to a button
Button button = e.Row.FindControl("btnstatus") as Button;
//check dt1 and set button text
button.Text = "Active";
}
}
Related
I work on asp.net web forms with c# I need to add checkbox column as last column on gridview
but i don't know how to add it
static string con =
"Data Source=DESKTOP-L558MLK\\AHMEDSALAHSQL;" +
"Initial Catalog=UnionCoop;" +
"User id=sa;" +
"Password=321;";
SqlConnection conn = new SqlConnection(con);
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridViewSearch.DataSource = GetDataForSearch();
GridViewSearch.DataBind();
}
}
public DataTable GetDataForSearch()
{
string response = string.Empty;
SqlCommand cmd = new SqlCommand();
DataTable dt = new DataTable();
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select top 10 datelogged AS EntredDatetime, Doc_type AS OrderType, Printer_name, BranchID AS BranchCode, id from Print_Report";
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 50000;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
}
catch (Exception ex)
{
response = ex.Message;
}
finally
{
cmd.Dispose();
conn.Close();
}
return dt;
}
on aspx page
<asp:GridView ID="GridViewSearch" runat="server">
</asp:GridView>
GridViewSearch.DataSource = GetDataForSearch();
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "X";
checkColumn.HeaderText = "X";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values
GridViewSearch.Columns.Add(checkColumn);
GridViewSearch.DataBind();
I get error on line below
GridViewSearch.Columns.Add(checkColumn);
argument 1 can't convert from system.windows.forms.datagridviewcheckbox to system.web.ui.webcontrol.databoundfield
so how to solve this issue please ?
Seems to me, that if you want say a button, or check box, or dropdown?
why not just add it to the markup.
So, say like this:
<div id="MyGridPick" runat="server" style="display:normal;width:40%">
<asp:Label ID="lblSel" runat="server" Text="" Font-Size="X-Large"></asp:Label>
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" cssclass="table table-hover" OnRowDataBound="GridView1_RowDataBound" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" ItemStyle-Width="120px" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Select" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkSel" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
Then my code to load is this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA ORDER BY HotelName");
GridView1.DataSource = MyRstP(cmdSQL);
GridView1.DataBind();
}
Now, of course I get VERY tired of typing that connection string stuff over and over. So, I have a "genreal" routine like this:
public DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
cmdSQL.Connection = conn;
using (cmdSQL)
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And the result of running above:
So, kind of hard to make the case to "add" a check box control, when you can just drop one into the gridview.
Same goes for a button, maybe we want a button to "view" or edit the above row, or some such.
So, once again, just drop in a plain jane button, say like this:
<asp:TemplateField HeaderText="View" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:Button ID="bView" runat="server" Text="View" CssClass="btn"
OnClick="bView_Click" />
</ItemTemplate>
</asp:TemplateField>
And now we have this:
And EVEN better?
Well, since that button (or check box) is a plain jane standard control?
then you can add standard events, like a click event, or whatever you want.
Say this code for the button click (shows how to get current row).
protected void bView_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA WHERE ID = #ID");
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = PKID;
DataTable dtHotel = MyRstP(cmdSQL);
General.FLoader(MyEditArea, dtHotel.Rows[0]);
MyGridPick.Style.Add("display", "none"); // hide grid
MyEditArea.Style.Add("display", "normal"); // show edit div area
}
And we now get/see this:
Edit: Process each checked/selected row.
this:
protected void cmdSelProcess_Click(object sender, EventArgs e)
{
// process all rows in GV with check box
String sPK = "";
List<int> MySelected = new List<int>();
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox chkSel = (CheckBox)gRow.FindControl("chkSel");
if (chkSel.Checked)
{
int PK = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
// add pk value of row to our list
MySelected.Add(PK);
// Or we could process data based on current gRow
if (sPK != "")
sPK += ",";
sPK += PK.ToString();
Debug.Print(PK.ToString());
}
}
// at this point, we have a nice list of selected in MySelected
// or, maybe process as a data table
SqlCommand cmdSQL =
new SqlCommand($"SELECT * FROM tblHotelsA where ID IN({sPK})");
DataTable rstSelected = MyRstP(cmdSQL);
//
foreach (DataRow dr in rstSelected.Rows)
{
// do whatever
}
}
Datagridviewcheckboxcolumn is a Windows formx object. You are working in web forms. Please see the link below for information on the webforms check box field
CheckBoxField checkColumn = new CheckBoxField();
My problem is this:
I'm creating a gridview that contains buttons. In these buttons, certain default text is displayed.
At the very bottom of the grid, there is a unique button that will create an additional row onclick.
Now, after I create my initial rows on the first page load, and all of the default button attributes are present, I am then able to select a value from a dropdown list that changes the text of the button in the next cell over.
But when I click to add a new row, that button text is reverted back to the default.
The selected value of the dropdown list does not change however.
I'm referencing this tutorial:
http://snipplr.com/view/72801/adding-dynamic-rows-in-gridview-with-dropdownlists-in-aspnet/
But have adjusted the code to include a dynamic button
private void AddNewRowToGrid()
{
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = dtCurrentTable.Rows.Count + 1;
//add new row to DataTable
dtCurrentTable.Rows.Add(drCurrentRow);
//Store the current data to ViewState
ViewState["CurrentTable"] = dtCurrentTable;
for (int i = 0; i < dtCurrentTable.Rows.Count - 1; i++)
{
//extract the DropDownList Selected Items
DropDownList ddl1 = (DropDownList)Gridview1.Rows[i].Cells[1].FindControl("DropDownList1");
DropDownList ddl2 = (DropDownList)Gridview1.Rows[i].Cells[2].FindControl("DropDownList2");
// Update the DataRow with the DDL Selected Items
dtCurrentTable.Rows[i]["Column1"] = ddl1.SelectedItem.Text;
dtCurrentTable.Rows[i]["Column2"] = ddl2.SelectedItem.Text;
}
//Rebind the Grid with the current data
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//Set Previous Data on Postbacks
SetPreviousData();
}
protected void Change_Button(object sender, EventArgs e)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
GridViewRow row = (GridViewRow)((DropDownList)sender).NamingContainer;
int index = row.RowIndex;
Button btn = (Button)Gridview1.Rows[index].Cells[3].FindControl("btn");
btn.Text = "HELLO";
ViewState["CurrentTable"] = dtCurrentTable;
}
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" AppendDataBoundItems="true" AutoPostBack="true" OnSelectedIndexChanged="Change_Button">
<asp:ListItem Value="-1">Select</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 3">
<ItemTemplate>
<asp:Button ID="btn" runat="server" Text="Default">
</asp:Button>
</ItemTemplate>
Can anybody explain how I'm able to maintain the desired text, or any attribute for that matter, on the postback?
This is strictly for my own education. I'm trying to learn more about preserving the page's state when I move between webforms.
i have a gridview in a asp.net webform and i add it a check box column like this (the dataTable first column(0) is empty in sql data source and i add check boxes on the column cells):
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (rowNum != 0)//except first row
{
CheckBox cb = new CheckBox();
cb.Enabled = true;
e.Row.Cells[0].Controls.Add(cb);//row[0]=first clmn-and this event happend for all rows
}
rowNum++;
}
now i have a dynamic check box column! and user should check some of them and click the submit then i need the row number of the checked check boxes.
how can i do this?
i tried this before:
DataTable editTable = new DataTable();
editTable.Rows.Add(GridView1.Rows[0]);
var x = editTable.Rows[0][0];
but the x cannot get the check box true or false! it seems that getting me the original field under the check box content.
regards.
Instead of creating the controls dynamically which in most cases results in a lot of trouble, you could add the CheckBoxes in one or more template columns. The following sample shows how to add a checkbox in a template column and how to retrieve the value afterwards:
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chb" runat="server" />
<asp:HiddenField ID="hiddenId" runat="server"
Value='<%# DataBinder.Eval(Container.DataItem, "Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Text" />
</Columns>
</asp:GridView>
In my sample, I've bound some data to the GridView:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var dt = GetData();
gridView.DataSource = dt;
gridView.DataBind();
}
}
private DataTable GetData()
{
var dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Text", typeof(string));
for (int i = 0; i < 10; i++)
dt.Rows.Add(new object[] { i, "Test text " + i.ToString() });
return dt;
}
If you need to set the value, you can do so in the RowDatabound event. The following code shows how to retrieve the value of the Checkbox controls:
protected void btn_Click(object sender, EventArgs e)
{
List<int> checkedIds = new List<int>();
foreach(GridViewRow row in gridView.Rows.OfType<GridViewRow>()
.Where(x => x.RowType == DataControlRowType.DataRow))
{
var hiddenId = (HiddenField)row.Cells[0].FindControl("hiddenId");
var checkBox = (CheckBox) row.Cells[0].FindControl("chb");
if (checkBox.Checked)
checkedIds.Add(int.Parse(hiddenId.Value));
}
}
My gridview has 2 columns - DropDownList & TextBox. The DDL is databound by a datatable. The SelectedIndex Change of DDL will populate its Textbox and also add a new row. All of this works fine, but the selected values of DDLs of previous rows, reset to 0 index, when a new row is added.The textbox values remain intact though. How can I retain the DDL selected values when adding new rows.
For eg. if I select 'abc' from dropdown of row 1, it populates its text field and also adds a new row. But with the postback happening, abc does not remain selected in row 1 ddl:
LOGIN PHONE
1 123456789
2
ASPX:
<asp:GridView ID="gvCommissions" runat="server"
OnRowDataBound="gvCommissions_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="LOGIN" ItemStyle-Width="29%">
<ItemTemplate>
<asp:DropDownList ID="ddlLogin" runat="server" Width="98%"
DataTextField="login" DataValueField="id"
OnSelectedIndexChanged="ddlLogin_SelectedIndexChanged" AutoPostBack="true" >
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="PHONE" ItemStyle-Width="12%">
<ItemTemplate>
<asp:TextBox ID="txtPhone" runat="server" Width="98%"
Text='<%# Eval("phone")%>' Enabled="false"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CODE BEHIND:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Get values from DB, store to a datatable and then to a viewstate
GetAgentDetails();
//Adds an empty row to grid
SetInitialRow();
}
}
private void AddNewRow()
{
//Create a datatable
dtCurrentData = new DataTable();
dtCurrentData.Columns.Add("phone");
//Store values of each row to a new datarow. Add all rows to datatable
foreach (GridViewRow gvRow in gvCommissions.Rows)
{
DataRow drcurrentrow = dtCurrentData.NewRow();
drcurrentrow["phone"] = ((TextBox)gvRow.FindControl("txtphone")).Text;
dtCurrentData.Rows.Add(drcurrentrow);
}
//create an empty datarow and also add it to the new datatable.
DataRow dr = dtCurrentData.NewRow();
dr["phone"] = "";
dtCurrentData.Rows.Add(dr);
//Bind the new datatable to the grid
gvCommissions.DataSource = dtCurrentData;
gvCommissions.DataBind();
}
protected void gvCommissions_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlLogin");
dtAgents = (DataTable)ViewState["AgentsTable"];
ddl.DataSource = dtAgents;
ddl.DataBind();
ddl.Items.Insert(0, "");
}
}
When you databind in AddNewRow, the original rows are lost. You must store the dropdown selected index, together with your textbox phone value in dtCurrentData. You can then set the index of the dropdowns in your RowDataBound event, using the values your saved in dtCurrentData.
private void AddNewRow()
{
//Create a datatable
dtCurrentData = new DataTable();
dtCurrentData.Columns.Add("phone");
//new column for dropdown index
dtCurrentData.Columns.Add("ddlIndex");
//Store values of each row to a new datarow. Add all rows to datatable
foreach (GridViewRow gvRow in gvCommissions.Rows)
{
DataRow drcurrentrow = dtCurrentData.NewRow();
drcurrentrow["phone"] = ((TextBox)gvRow.FindControl("txtphone")).Text;
//get dropdown index
drcurrentrow["ddlIndex"] = ((DropDownList)gvRow.FindControl("ddlLogin")).SelectedIndex;
dtCurrentData.Rows.Add(drcurrentrow);
}
//create an empty datarow and also add it to the new datatable.
DataRow dr = dtCurrentData.NewRow();
dr["phone"] = "";
//initial drop down index
dr["ddlIndex"] = 0;
dtCurrentData.Rows.Add(dr);
//save to the viewstate like your AgentsTable
ViewState["CurrentData"] = dtCurrentData;
//Bind the new datatable to the grid
gvCommissions.DataSource = dtCurrentData;
gvCommissions.DataBind();
}
protected void gvCommissions_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlLogin");
dtAgents = (DataTable)ViewState["AgentsTable"];
ddl.DataSource = dtAgents;
ddl.DataBind();
ddl.Items.Insert(0, "");
//get the dropdown index from CurrentData
//use the current gridview's row index, since it matches the datatable
if (ViewState["CurrentData"] != null)
{
DataTable dtCurrentData = (DataTable)ViewState["CurrentData"];
ddl.SelectedIndex = Convert.ToInt32(dtCurrentData.Rows[e.Row.RowIndex]["ddlIndex"]);
}
}
}
RowDataBound gets fired every time (irrespective of whether the page is PostBack page or NOT).
You need to add that if(!IsPostBack) condition around the code where you are performing the databinding for the dropdowns in your RowDataBound event.
when i checked [checked box] data on my page (1) and then go on to next page (2) through paging(bottom button of pages like [1234]) and then checked data on page (2).
when i came back to page (1) then it remain unchecked as i don't checked anything!!!
all the things remains at its original positions. all are unchecked on both pages .
when coming from 1 page to page 2 (check-boxes of page 1 forget his value and get unchecked) and after when coming from page 2 to page 1 same thing happens.
sorry for my bad and rough English.
any suggestion??
If its a gridview or any repeater control try this
Gridview HTML
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" AllowPaging="True"
PageSize="5" Width="324px" DataKeyNames="CategoryID"
OnPageIndexChanging="GridView1_PageIndexChanging">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CS Codes
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
RememberOldValues();
GridView1.PageIndex = e.NewPageIndex;
BindData();
RePopulateValues();
}
And
private void RememberOldValues()
{
ArrayList categoryIDList = new ArrayList();
int index = -1;
foreach (GridViewRow row in GridView1.Rows)
{
index = (int) GridView1.DataKeys[row.RowIndex].Value;
bool result = ((CheckBox)row.FindControl("CheckBox1")).Checked;
// Check in the Session
if (Session[CHECKED_ITEMS] != null)
categoryIDList = (ArrayList)Session[CHECKED_ITEMS];
if (result)
{
if (!categoryIDList.Contains(index))
categoryIDList.Add(index);
}
else
categoryIDList.Remove(index);
}
if (categoryIDList != null && categoryIDList.Count > 0)
Session[CHECKED_ITEMS] = categoryIDList;
}
And
private void RePopulateValues()
{
ArrayList categoryIDList = (ArrayList)Session[CHECKED_ITEMS];
if (categoryIDList != null && categoryIDList.Count > 0)
{
foreach (GridViewRow row in GridView1.Rows)
{
int index = (int)GridView1.DataKeys[row.RowIndex].Value;
if (categoryIDList.Contains(index))
{
CheckBox myCheckBox = (CheckBox) row.FindControl("CheckBox1");
myCheckBox.Checked = true;
}
}
}
}
Bind Data Code
EDIT
/* QUERY */
private const string QUERY_SELECT_ALL_CATEGORIES = "SELECT * FROM Categories";
private void BindData()
{
SqlConnection myConnection = new SqlConnection(ConnectionString);
SqlDataAdapter ad = new SqlDataAdapter(QUERY_SELECT_ALL_CATEGORIES,
myConnection);
DataSet ds = new DataSet();
ad.Fill(ds, "Categories");
GridView1.DataSource = ds;
GridView1.DataBind();
}
For more details chk this Maintaining_State_of_CheckBoxes
When you are navigating from one page to another ,your page refreshes so it cant retain value for checkbox,If you want to do this you have to do it from code behind ,write code
Checkbox.Checked=True in !IsPostback according to your valid conditions.