Binding Itemtemplate of GridView with DataTable - asp.net

I have below GridView in .aspx file.
<asp:GridView ID="grdScopeList" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="ScopeChk" runat="server" Checked=false />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="sync_scope_name" Visible=true />
</Columns>
</asp:GridView>
I am using Dataset/DataTable for assiging the GridView.Below is the Code snippet used in PageLoad event.
string scopecomm="select sync_scope_name from Sync.scope_info";
DataSet ds_scope = new DataSet();
ds_scope = GetData(scopecomm, remoteconn); grdScopeList.DataSource = ds_scope;
grdScopeList.DataBind();
But I am getting the column sync_scope_name twice.I am able to bind the column sync_scope_name in Dataset to BoundField.I just need to show it once.
Regards,
Sachin K

Most likely your query is returning duplicates.
Run your query manually against your database to discard this.
If the query should return duplicates and you only want to show them once, you need to group your query
select sync_scope_name
from Sync.scope_info
group by sync_scope_name
Or use the distinct keyword
select distinct sync_scope_name from Sync.scope_info

I added AutoGenerateColumns="false" in GridView.

Related

Filter gridview with OnChecked Event

I have a gridview loaded from a database with a checkbox in the first column. What I want is that when clicking on any row the grid will be filtered to show only the rows in which the value of the second cell is the same as the one I clicked on (having the option to select more rows with that value). Removing the checks he would reload all the information again. I tried doing it using the OnChecked event, but due to AutoPostBack it filters but loses the value of the checkbox checked. What is the best way to do what I want? I hope I have been explicit. Thank you
asp:GridView ID="gridview" runat="server" AutoGenerateColumns="false" DataKeyNames="Id">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkRow" OnCheckedChanged="chkRow_CheckedChanged" AutoPostBack="true" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Document" ItemStyle-Width="10%" HeaderText="Documento" />
<asp:BoundField DataField="Entidad" ItemStyle-Width="55%" HeaderText="Entidad" />
</Columns>
For Each row As GridViewRow In gvEncomendasPendentes.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim chkRow As CheckBox = TryCast(row.Cells(0).FindControl("chkRow"), CheckBox)
If chkRow.Checked Then
'Bind with filter
End If
End If
Next
Does the table display the entire dataset at all times? If so, I'd check into client-side filtering (JavaScript). Not having the round trip to the server/database would make your page a lot more responsive.
But assuming that's not the case, and to actually answer the posted question, here's how I'd approach it in the VB.Net Code. Try changing the Change Event like this:
Protected Sub chkRow_CheckedChanged (sender as object, e As EventArgs)
Dim chk As CheckBox = DirectCast(sender, CheckBox)
dim grv As GridRowView = DirectCast(chk.NamingContainer, GridRowView)
dim hdn AS HiddenField = grv.FindControl("hdnFieldWithValue")
If chk.Checked then
AddValueToFilerList(hdn.Value)
Else
RemoveValueFromFilterList(hdn.Value)
End If
BindGridView()
End Sub
Your way does work, but that has a Log(N) time on processing, as it needs to look at every row in the grid. The above way will KNOW which checkbox was checked, and deal with it appropriately.
And this small change to the markup:
<asp:hiddenField runat='server' id='hdnFilterList' />
<asp:GridView ID="gridview" runat="server" AutoGenerateColumns="false" DataKeyNames="Id">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkRow" OnCheckedChanged="chkRow_CheckedChanged" AutoPostBack="true" runat="server" checked='<%# CheckValueInFilterList(Eval("Entidad")) %>' />
<asp:hiddenField id="hdnFieldWithValue" runat="server" value='<%# Eval("Entidad")' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Document" ItemStyle-Width="10%" HeaderText="Documento" />
<asp:BoundField DataField="Entidad" ItemStyle-Width="55%" HeaderText="Entidad" />
</Columns>
You'll also a function something like this:
Protected Function CheckValueInFilterList(input as string) as boolean
Return MyListOfFilterItems.Contains(input)
End Function
The purpose of that would be to see if the input is contained in your list of filters you're applying to your query and returning true/false depending on that.
Which is directly related to why you're not retaining a check in the checkboxes between postbacks. Since you're rebinding the grid, the existing form state is thrown away in favor of the values from the bind. Since your markup lacked a setter for the checkbox's checked state in the databind, it always resorted to false.
I also added a hidden field to the Markup which would contain the filter list as some type of serialized string (JSON, XML, etc). I'd read it from that field on the Page Load where IsPostBack is True, and always write the list to it in the PreRender event. The point is to just have that passed back and forth through the posted form state so that you can remember them between postbacks.
Maintaining that list of filters in a control outside of the gridview as described does add a bit of overhead in the data that is sent to/from the server on roundtrips. But I wouldn't expect that to a large amount, and would expect a preformance increase due to not having to iterate through the entire gridview item list on every postback.

how to retrieve checkbox values in gridview?

I have a grid-view on which each row consists check box, and there is a button outside the grid-view. when i check some rows on grid-view and clicking those button, i need to insert the checked rows details into another table of database. I have created the grid-view like this
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="student_name" HeaderText="student_name" SortExpression="student_name" />
<asp:BoundField DataField="student_id" HeaderText="student_id" SortExpression="student_id" ReadOnly="True" />
<asp:BoundField DataField="student_nric" HeaderText="student_nric" SortExpression="student_nric" />
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox AutoPostBack="false" Id="CheckBoxUpdate" runat="server" />
</ItemTemplate></asp:TemplateField>
</Columns>
</asp:GridView>
but dont know how to store the checked rows value to datatable. please help
On button click on which you want to save the values in the database.
Loop through earch row of the gridview.
Find the checkbox in that row
Check if it is checked or not
foreach (GridViewRow row in GridView1.Rows)
{
if (((CheckBox)row.FindControl("CheckBoxUpdate")).Checked)
{
//insert here
}
}
Here is a good link for the same
http://www.c-sharpcorner.com/Forums/Thread/201835/loop-through-gridview.aspx
You can use a stringbuilder object to iterate through the rows of the checkbox and store the value. see this tutorial
http://www.codeproject.com/Articles/11207/Selecting-multiple-checkboxes-inside-a-GridView-co

How to bind one column to gridview which is not present in database

How to bind one column to the gridview which is not present in the database?
I want to display the total unit in the last column named Total Unit but it is not present in database.
I got an argument exception:
Column 'tunit' does not belong to
table.
foreach(DataRow row in dt.Rows )
{
object[] obj=new object[2];
obj[0] = row["Transaction_Id"];
obj[1] = row["tunit"];
dtgrid.Rows.Add(obj);
}
The best solution to this problem is to implement unbound column as it is explained in the Unbound Columns topic.
if you are binding a list, you can add a property to that list and bind to the grid using eval("PropertyName")
When you prepare the select query make sure you have one more extra column with the total value you want for that particular row, then you can specify a column in the gridview as follows, make sure you specify
'AutoGenerateColumns = false;
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="sds_datasourceName">
<Columns>
<asp:TemplateField HeaderText="Total" >
<itemtemplate>
<asp:Label ID="Total" runat="server" Text='<%# Bind("Total") %>'></asp:Label>
</itemtemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

ASP .Net Gridview bind to data only when clicking update

Here's how I want the control to work. Click edit on a row in gridview. There's a textbox in one of the columns, I would like it to be blank even though there's data in the database for that column, but when I click update I would like whatever new text the user entered to update the database for that column. It would be one-way databinding, but the other way?
Here's how I did it using an sql datasource with the select,update and delete methods generated.
First, you'll need to make any column that you want to edit like this a template field with an item template and and edit item template:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="SqlDataSource1"
onrowupdating="GridView1_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="City" SortExpression="City">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("City") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtCityEdit" Text=""></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Next handle the gridview's on update event:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//find the value control who's value you want
TextBox tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("txtCityEdit");
//since we are not using a bound column for city we need to explicitly insert the value
//into the update parameter.
SqlDataSource1.UpdateParameters["City"].DefaultValue = tb.Text;
}
Even if you are using something other than an SQL Datasource this should be the basic solution.
// Find notes textbox
TextBox tb = (TextBox)MyActiveReferrals.Rows[e.RowIndex].FindControl("NotesTextBox");
e.NewValues.Add("Notes", tb.Text);
I used a linq data source.

How do I data bind a drop down list in a gridview from a database table using VB?

So in this gridview, there is a column for status and I want to have a drop down list with Pass, Pending, Fail appear when the edit button is clicked. These values are already in a table, so I need to somehow bind from this table to each ddl for every row.
Here is the column from the gridview. As you can see, I would like to just have a label showing when not in edit mode, and a ddl when the edit button is pressed
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="Name"
datatextfield="Name" DataSource="*What goes here?*"> />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text='I don't understand how to get this from the ddl' />
</ItemTemplate>
</asp:TemplateField>
For clarity's sake, my table is named Status, and the database is named DirectImport
There's a few steps to go through here - none of them are particularly difficult, but they can be a bit fiddly (IMHO). The good news is once you've got this working once, it gets easier to do it again!
I'm assuming you've got a <asp:*DataSource> control on your page - my preference is for an ObjectDataSource but I don't think it matters, I think a SqlDataSource works equally well. I've never tried doing this with GridView.DataSource = MyDataSet in code-behind, so I don't know whether that would work or not, but my assumption is that it wouldn't as you wouldn't get the proper two-way binding that you want. This data source feeds your grid with your main data. The key point here is that your database query must return both the Status text field and the Status id.
So your gridview will now look something like:
<asp:objectdatasource runat="server" id="MainDataSource" ... />
<asp:gridview runat="server" id="MyGridView" DataSourceID="MainDataSource">
<Columns>
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text="<%# Bind('Status') %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
The Text="<%# Bind('Status') %>" is the bit you're missing to get the status text into the grid.
Now add a second data source into your markup that reads in the set of values from the Status table.
<asp:objectdatasource runat="server" id="StatusObjectDataSource" ... />
And add the EditItemTemplate into the GridView, which is bound to the Status DataSource.
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="StatusID"
datatextfield="Status" DataSourceID="StatusObjectDataSource"
SelectedValue="<%# Bind('StatusId') %>" />
</EditItemTemplate>
The SelectedValue="<%# Bind('StatusId') %>" is what connects up the two datasets so that when you flip a row into Edit mode, the dropdownlist has the correct item already selected, and when you then save it you've got the Status ID to put into your database.
And you're done.
I have used the RowDataBound event. Here is a small code snippet. HTH
you would have an ItemTemplate in your aspx/ascx
<asp:TemplateField HeaderText="Column Headings">
<ItemTemplate>
<asp:DropDownList ID="ddlName" runat="server" Width="150"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
and in your code behind, you will have
protected void grdDataMap_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlName");
ddl.DataSource = someList;//the source of your dropdown
ddl.DataBind();
}
}
so when you bind your grid with grdDataMap.Databind (assuming your grid id is grdDataMap), row databound event will be called for each row (including header/footer, and thats the reason you check RowType)
so you can probably decide what controls/columns to hide/show/bind inside this row databound event
In the winforms world I pull my objects from the DB into a List(Of Whatever) and use the list as the datasource.
This also lets me add extra "convenience" fields in the object so that I can populate it with stuff from other tables.
I don't know asp.net at all so if you can do something similar, it might help.
A really quick solution is to create a custom web control for the status dropdown. The control will always contain the same data. When it renders you populate the datasource. When it gets added to the gridview, the data will be in the drop down. Hope that helps!

Resources