I have a infragistics grid that gets data when a dropdown is changed
1- i want to hide the last column every time the grid is loaded with data
2- i also want to update header according to data
problem
I am trying
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
EntityName.Text = DropDownList1.SelectedItem.Text;
string entity = "t_" + DropDownList1.SelectedItem.Text;
String strConnString = ConfigurationManager.ConnectionStrings["LiveLeaseConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand("p_DataList_ByRegardingObject", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#RegardingObjectName", entity);
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sqlDataAdapter.Fill(dt);
this.EntityGrid.DataSource = dt;
this.EntityGrid.Columns[6].Hidden = true;
its throwing null reference error and it doesnt seem to update column names each time it loads data.data is getting refreshed but not the column names.
here is my aspx
<asp:DropDownList ID="DropDownList1" AutoPostBack="true" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem>Select Entity</asp:ListItem>
</asp:DropDownList>
<asp:Label runat="server" ID="EntityName"></asp:Label>
<ig:WebScriptManager ID="WebScriptManager1" runat="server"></ig:WebScriptManager>
<ig:WebDataGrid ID="EntityGrid" runat="server" Width="100%" Height="50%" StyleSetName="Claymation" >
<Behaviors>
<ig:Sorting>
</ig:Sorting>
</Behaviors>
<ClientEvents Click="NavigateOnClick" />
</ig:WebDataGrid>
If your AutogenerateColumns is True - grid column collection will be empty. The trick is to get to the column via Grid Rows.
After grid is bound try this:
this.EntityGrid.Rows[0].Items[6].Column.Hidden = true;
Just make sure that grid has at least one row.
Related
How to maintain sorting throughout paging in gridview in asp.net.
Below is my code behind for binding grid, paging, and sorting
private string SortDirection
{
get { return ViewState["SortDirection"] != null ? ViewState["SortDirection"].ToString() : "ASC"; }
set { ViewState["SortDirection"] = value; }
}
private void BindGV(string sortExpression = null)
{
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlCommand cmd = new SqlCommand("SPGetEmpDetailes", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
if (sortExpression != null)
{
DataView dv = dt.AsDataView();
this.SortDirection = this.SortDirection == "ASC" ? "DESC" : "ASC";
dv.Sort = sortExpression + " " + this.SortDirection;
EmployeeGV.DataSource = dv;
}
else
{
EmployeeGV.DataSource = dt;
}
EmployeeGV.DataBind();
}
}
I am new to .NET and I want to maintain sorting throughout paging but I don't know how to do it.
protected void EmployeeGV_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
EmployeeGV.PageIndex = e.NewPageIndex;
BindGV();
}
protected void EmployeeGV_Sorting(object sender, GridViewSortEventArgs e)
{
this.BindGV(e.SortExpression);
}
Ok, so since we have a data pager here, then that means the data page routine will re-bind the GV. So, that means:
Loading up - first page load - we fill the grid
When we page - we fill the grid
When we sort - we fill the grid.
So, from above, we see at least 3 places. That suggests we need (and want) ONE routine to load up the grid - since we have several places where we will do this.
And I see you have one routine for this. We tweak it up a bit.
Next up:
The sort value we get/have does not persit, so once again we can use ViewState for that. (and again I see you attempting to use that).
So, lets lay this out.
First up, and NEVER forget this rule:
You want to load combo boxes, grids, listbox and ANY data on your FIRST page load, and ONLY your first page load, and ONLY first time. If you break this rule then you in effect cannot build a working web forms page - you just can't!!!!
And the reason is simple:
Any button click, any post-back, and any code operations on that page will ALWAYS and I repeat ALWAYS will trigger the page load event first and then YOUR event - (button click, paging or whatever). So, that means we ALWAYS will have our page load code stub and have a if (!IsPostBack) code stub - (darn near always follow this design pattern).
Ok, so lets code this up.
next up: I see no reason to put say a datatable in some using block - they safe dispose on their own. However, adopting using blocks for sql connections, and things like a sql command object - yes, do apply a using block.
Ok, I think we quite much cleared up the base issues.
So, lets setup the code, say like this:
So, say our simple markup - we dropped in a row select button.
<div style="padding:35px;width:55%">
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table"
AllowPaging="True" OnPageIndexChanging="GridView1_PageIndexChanging" PageSize="8" AllowSorting="True" OnSorting="GridView1_Sorting">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last" SortExpression="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:CheckBoxField DataField="Active" HeaderText="Active" ItemStyle-HorizontalAlign="Center" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" Text="View" CssClass="btn" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
</div>
Ok, now our code, say this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["MySort"] = "HotelName";
BindGV();
}
}
void BindGV()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * FROM MyHotels", conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
// apply optional sort
if (ViewState["MySort"] != null)
rstData.DefaultView.Sort = ViewState["MySort"] as string;
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindGV();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
ViewState["MySort"] = e.SortExpression;
BindGV();
}
And now we get this:
So, the trick or approach?
We have ONE view sate that holds our sort - when we want to sort, we simply put into this ViewState["MySort"] = some column to sort. After that, our bind + load routines are free to run - and we sort if set.
Thus, the pager routine, sort routine, and load routine -- they all call that one routine, and thus we don't have to write a lot of code.
And the view button? Well, if we click on that button (say we add a click event) like this:
Then the row button click can be this:
protected void Unnamed_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
Debug.Print("Row index click = " + gRow.RowIndex.ToString());
// get database (hidden pk row id
int? PKID = GridView1.DataKeys[gRow.RowIndex]["ID"] as int?;
Debug.Print("Database PK = " + PKID.ToString());
Debug.Print("Hotel name this row = " + gRow.Cells[2].Text);
}
And clicking, we get:
I'm working on a ASP.Net Web Forms Application.Currently SqlDataReaders directly bind to the two grid views. I need to change the data set before binding it to the grid view .There are two datasets coming from Stored Procedure (Two select Queries). I need to edit both of them and replace some data before binding to grids .What is the best way to achieve this.?
private void BindTable()
{
LiteralMessage.Text = "";
RecentLiteralMessage.Text = "";
ErrorLiteralMessege.Text = "";
var isStandbySelected = SelectedDatabase.SelectedValue == "stats";
using (var db = new Database(isStandbySelected))
{
try
{
//db.BeginTransaction(IsolationLevel.Snapshot);
db.BeginTransaction(); //Need a transaction block to stop from closing connection
db.StoredProcedure = "dbo.NewExportList";
if (!string.IsNullOrEmpty(TextBoxNameFilter.Text))
db.AddParameter("#nameFilter", TextBoxNameFilter.Text);
db.AddParameter("#excludedExports", CheckBoxExcludedExports.Checked);
db.AddParameter("#RunOnReportingServer", SelectedDatabase.SelectedValue == "stats" );
if(CheckBoxRecentlyRun.Checked)
db.AddParameter("#recentExports", true);
System.Data.SqlClient.SqlDataReader reader = db.GetDataReader();
GridViewExports.DataSource = reader;
GridViewExports.DataBind();
if (GridViewExports.Rows.Count > 0)
{
GridViewExports.Visible = true;
}
else
{
GridViewExports.Visible = false;
LiteralMessage.Text = "No Results";
}
GridViewRecentExports.DataSource = null; //clear any exsisting data
if (reader.NextResult()) //Get the second data set if any
{
GridViewRecentExports.DataSource = reader;
}
GridViewRecentExports.DataBind();
if (GridViewRecentExports.Rows.Count > 0)
{
GridViewRecentExports.Visible = true;
}
else
{
GridViewRecentExports.Visible = false;
RecentLiteralMessage.Text = "No Results";
}
db.CloseConnection();
//db.CommitTransaction();
}
catch (Exception ex)
{
}
}
Ok, there are two approaches common used here.
First, lets take a sample GV, and work though the two common apporaches here.
Our simple markup:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:BoundField DataField="Nights" HeaderText="Nights" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Price" HeaderText="Price" DataFormatString="{0:c2}"
ItemStyle-HorizontalAlign="Right" />
</Columns>
</asp:GridView>
Ok, and our code to load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn)) {
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
GridView1.DataSource = rstData;
GridView1.DataBind();
}
Ok, and we now have this:
so, with above, we say want the the total price for each row booking to show.
So, lets use the "common" approach here. We first add our extra control to the grid view. Lets use a plane jane text box:
eg: this:
<asp:BoundField DataField="Price" HeaderText="Price" DataFormatString="{0:c2}"
ItemStyle-HorizontalAlign="Right" />
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label ID="lblTotal" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
so, we just added a label to the gv.
So, the event we use is the row data bound event This even is great, since it gives us the one data row, and the one grid view row to work with. This event also great for changing the color of a row, or text box, and of course also doing some calculation or setting up the value of a un-bound control - such as our label called
So, now in our row data bound event, we can do this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView gData = (DataRowView)e.Row.DataItem;
Label lblTotal = e.Row.FindControl("lblTotal") as Label;
decimal MyPrice = (int)gData["Nights"] * (decimal)gData["Price"];
lblTotal.Text = string.Format("{0:c2}", MyPrice);
}
}
And now our gird is this:
Ok, so above is the common approach.
However, a interesting approach?
Once you fill a data table, then you are free to process that table, and that EVEN includes adding new columns to the table!!!
So, lets dump (remove) our data bound row event.
lets CHANGE the label to use bound data from the table. So, our markup is now:
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label ID="lblTotal" runat="server"
Text = '<%# string.Format("{0:c2}", Eval("MyTotal")) %>'
></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now, we don't' have a column in data table called MyTotal, do we?
but, we can AFTER getting the table from the query or stored procedure ADD the table.
so, our grid load code now becomes this:
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn)) {
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
rstData.Columns.Add("MyTotal", typeof(decimal));
foreach (DataRow MyRow in rstData.Rows)
{
MyRow["MyTotal"] = (int)MyRow["Nights"] * (decimal)MyRow["Price"];
}
GridView1.DataSource = rstData;
GridView1.DataBind();
}
Note how we just added a new column, and then did a table process loop to setup that value. The results of the GV are thus the same.
Last but not least?
FEW PEOPLE realize that a data table supports expressions!!!
And when you modify values etc. the update automatic. So, in place of that row processing loop above? We could in fact do this:
DataColumn MyCol = new DataColumn("MyTotal", typeof(decimal));
MyCol.Expression = "[Nights] * [Price]";
rstData.Columns.Add(MyCol);
GridView1.DataSource = rstData;
GridView1.DataBind();
So, in most cases, I often just use the row data bound. And this event is nice since you don't write a loop, and for conditional format such as a row color change, or a column/cell format of color etc., or the new setting of the new text box? row data bound is nice.
But, you can also as noted, add columns, and loop + process the data table, and you can even add columns that are based on expressions of other columns. You then send that updated and pre-processed table to the gridview as normal.
Also note that while I used a query, a store procedure would work the same way:
eg:
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand("MyStoreProcedure", conn)) {
cmdSQL.CommandType = CommandType.StoredProcedure;
cmdSQL.Parameters.Add("#Active", SqlDbType.Bit).Value = 1;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
DataColumn MyCol = new DataColumn("MyTotal", typeof(decimal));
MyCol.Expression = "[Nights] * [Price]";
rstData.Columns.Add(MyCol);
GridView1.DataSource = rstData;
GridView1.DataBind();
I am trying to populate 2 text boxes using a dropdownlist on my web-page however I can't get the code required text boxes to populate
I can confirm that the code stated below works when I use a button instead of a dropdownlist
I have defined the dropdown list in the default.aspx as follows:
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource1" DataTextField="Player" DataValueField="ID" AppendDataBoundItems="true" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Value="">Please Select</asp:ListItem></asp:DropDownList>`
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Phocas_WorkBenchConnectionString %>" SelectCommand="SELECT ID, [PlayerFirstName] + ' ' + [PlayerLastName] as 'Player' FROM [Players]"></asp:SqlDataSource>
I have created the C# code in the default.aspx.cs as follows:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection sql = new SqlConnection(#"Data Source=DESKTOP-PMSK135\SQLEXPRESS;Initial Catalog=Phocas_WorkBench;Integrated Security=True");
{
SqlCommand getFirstName = new SqlCommand("Select PlayerFirstName from Players where ID = #PlayerID", sql);
SqlCommand getLastName = new SqlCommand("Select PlayerLastName from Players where ID = #PlayerID", sql);
getFirstName.Parameters.AddWithValue("#PlayerID", DropDownList1.SelectedValue);
getLastName.Parameters.AddWithValue("#PlayerID", DropDownList1.SelectedValue);
sql.Open(); //Opens Connection to the SQL Database using the definded Connection String. In this case the defined connection string is stored in "sql"
string getResults = (string)getFirstName.ExecuteScalar();
TextBox3.Text = getResults;
getResults = (string)getLastName.ExecuteScalar();
TextBox4.Text = getResults;
sql.Close();
}
}
I am hoping to populate the results from the 2 SqlCommand into textbox3 and textbox4 with #PlayerID being equal to the results stored in the dropdownlist with the DataValueField="ID" as ID is the Unique identifier
I have tried many different types when trying to replace the variables in the AddWithValue. See the ones I have tried below:
DropDownList1.text
DropDownList1.DataValueField
DropDownList1.SelectedValue
DropDownList1.SelectedIndex
However none of the above seem to work.
A nudge in the right direction would be very helpful
Thank you.
I have a table for projects that has a bit value for whether the project is still active or not. I created a stored procedure that pulls the project name and the value for the project (0 for inactive, 1 for active). When I display it on my webpage, the bit values show up in checkboxes (which is good because I would like to be able to update those values with a button).
The problem is that I'm unable to click or unclick them.
How could I pull my data correctly so that the checkboxes for the project name is clickable to be updated?
Any help would be much appreciated.
public void loadProj()
{
SqlConnection con;
DataTable dt = new DataTable();
string CS = ConfigurationManager.ConnectionStrings["ProjDB"].ConnectionString;
using (con = new SqlConnection(CS))
{
con.Open();
SqlCommand cmd = new SqlCommand("GetProjActive", con);
SqlDataAdapter sa = new SqlDataAdapter(cmd);
callStoredProcedure(cmd, sa);
sa.Fill(dt);
GridView.DataSource = dt;
GridView.DataBind();
}
}
You need to set up a asp:TemplateField in your GridView columns, with a asp:CheckBox control inside this template.
Setting the CheckBox value: The Boolean database value should be bound into the CheckBox using the OnRowDataBound event.
Changing the database value: Register a OnCheckedChanged event on the template field's CheckBox control.
HTML markup:
<asp:GridView ID="gv"
runat="server"
DataSourceID="..."
OnRowDataBound="gv_DataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chk_selection" runat="server" OnCheckedChanged="chk_selection__CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
....
</Columns>
</asp:GridView>
Code behind:
protected void gv_DataBound(object sender, GridViewRowEventArgs e)
{
// Get this row's CheckBox control
CheckBox chkSelector = (CheckBox)e.Row.FindControl("chk_selection");
// Cast the database boolean value and set the checkbox's Checked property
chkSelector.Checked = Convert.ToBoolean(DataBinder.Eval(e.Row.DataItem, "bool_field"));
}
protected void chk_selection__CheckedChanged(object sender, EventArgs e)
{
// Update your database
}
I have a CheckBox in GridView cell. I want to update the database on CheckBox change, like when I unchecked it, 'Status' column in table update as false or vice versa.
Your question is very incomplete. But i'll give it a try, maybe it's helpful anyway.
Assuming you want to update as soon as the Checked state has changed(the user clicked the CheckBox), you have to set AutoPostBack="true" first.
Then you can handle the CheckBox.CheckedChanged event:
protected void Check_Clicked(Object sender, EventArgs e)
{
// get the checkbox reference
CheckBox chk = (CheckBox)sender;
// get the GridViewRow reference
GridViewRow row = (GridViewRow) chk.NamingContainer;
// assuming the primary key value is stored in a hiddenfield with ID="HiddenID"
HiddenField hiddenID = (HiddenField) row.FindControl("HiddenID");
string sql = "UPDATE dbo.Table SET Status=#Status WHERE idColumn=#ID";
using (var con = new SqlConnection(connectionString))
using (var updateCommand = new SqlCommand(sql, con))
{
updateCommand.Parameters.AddWithValue("#ID", int.Parse(hiddenID.Value));
// assuming the type of the column is bit(boolean)
updateCommand.Parameters.AddWithValue("#Status", chk.Checked);
con.Open();
int updated = updateCommand.ExecuteNonQuery();
}
}
Grid source
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:CheckBox ID="chkview" runat="server" AutoPostBack="true" OnCheckedChanged="chkview_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
C# code
protected void chkview_CheckedChanged(object sender, EventArgs e)
{
// code here.
}