Adding new Columns to GridView with a new DataSource - c#

I have a gridview that is loaded from a DataSet, in which most of the fields are generated through templates.
One of them is an Image that changes according to the value that is returned from the dataset.
Here is an example:
<asp:TemplateField HeaderText="Attention">
<ItemTemplate>
<asp:Image ID="alertFlag" runat="server" ImageUrl='<%# Eval("alertFlag").ToString().Equals("True") ? "~/Images/Warning-32.png" : "" %>' />
</ItemTemplate>
</asp:TemplateField>
Now I have a dropdown list, in which, depending on what is chosen, a new request to the database is made, and new columns are added, but the previous ones must stay.
Should I create a new GridView or how should I add new the new columns, keep them hidden, and then show them when the proper event is fired. this includes loading new data from the database and binding to the gridview. And how would I add the condition above programatically?
Thanks.

I would say that you will use the same gridview and have column with visible set to true or false. I will suggest that you have a property in the code behind such as ShowColumnX which will return true or false based on the dropdown value. In the aspx, you will then bind the visible property to that value such as Visible="<%= ShowColumnX %>"
If your existing column is setup to bind value correctly to a field of your data source, then you dont have to do anything different then what you have already done such as rebinding the data source on postback.

Related

Update gridview according to checkbox

I have a gridview. It contains checkboxes against all the values. Once I click the checkbox, and press submit, the selected items are inserted into another databse. I want that those selected items shouldn't appear on the current gridview if loaded next time.
For this, what I have planned is that there must be a column in current database to indicate whether the checkbox has been checked or not. The column will be filled with yes/no accordingly. And then display the rows which have only "No" in them.
However, this seems to be lengthy. Is there any other means to achieve this.
Since I believe this is a continuation of your problem from here,
I'll just copy my answer from there.
Sorry if it's not written in c#, I just noticed that tag just now.
You need to include the Primary Key or the column that makes your record Unique in its table. I'll just assume a "ImageID" column.
Place it on a hidden field on your first column.
You'll need it to issue a SQL DELETE or UPDATE statement on those rows after insertion to the destination DB. Although by using the latter, you'll need to have a new column on the table let's say - "TRANSFER_STATUS" tinyint, a switch which you can update 1 or 0.
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true"
OnCheckedChanged="CheckUncheckAll"/>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID ="CheckBox2" runat="server" />
<asp:HiddenField ID="hfImgID" runat="server"
Value=<%# Eval("ImageID") %> />
</ItemTemplate>
</asp:TemplateField>
Code behind:
Dim cbSelect As CheckBox, imgToInsert As Image
Dim ddlStatus As DropDownList, hfImgID As HiddenField
For Each r As GridViewRow In gvDetails.Rows
cbSelect = r.Cells(0).FindControl("CheckBox2")
If cbSelect.Checked Then
hfImgID = r.Cells(0).FindControl("hfImgID")
imgToInsert = r.Cells(1).FindControl("imgPreview")
ddlStatus = r.Cells(2).FindControl("dpdListEstatus")
/*Insert statement goes here...
DELETE or UPDATE statement goes here,
passing the ID of the image from hfImgID.Value*/
End If
Next r
**EDIT**
/*Call your SELECT statement again here to refresh your GridView.
If you used UPDATE, you need to include
your toggle switch in the WHERE clause. TRANSFER_STATUS = 0*/
I don't know what DB you are using, so this is limited, but it will get the value of a cell based on the checkbox--this assumes the chkbox is in the 3rd cell(index 2) and that there is other text in cells 0 and 1 (I don't know what your DGV looks like). it then puts the cell values of the checked rows into a dataset--from there you could dump the dataset into a db of your choice (not sure what you have). In terms of not showing the row on next load, you could change the text of cell 4 (a y/n cell, for example), then update the current database. Next time you load the DGV, include in your call to show only rows with 'y' in column X (are you using SQL?)
'get checked items and add to dataset
Dim i As Integer = 0
For i = 0 To Outdgv.RowCount - 1
If Outdgv.Rows(i).Cells(2).Value = True Then
Dim dsNewRow As DataRow
dsNewRow = dataset.Tables("report").NewRow()
Dim val1 As String = Outdgv.Rows(i).Cells(0).Value
Dim val2 As String = Outdgv.Rows(i).Cells(1).Value
dsNewRow.Item(1) = val1
dsNewRow.Item(2) = val2
dataset.Tables("report").Rows.Add(dsNewRow)
Outdgv.Rows(i).Cells(3).Value = 'n'
End If
Next
From your reply to my comment, it seems a restriction during the current session is suffient. Therefore you could keep track in a session variable.
For example, if your rows have an integer id, you could store a List<int> in session, and add ids to the list each time a checked row is submitted. Then refer to the session variable when refreshing the grid.
I'm not entirely sure what your goal appears to be, but if your trying to hide items that are checked directly from the grid that is possible.
Query: SELECT * FROM [db] WHERE ([Checked] = 0);
So the premise is that if the value is zero, it appears on the grid. If it becomes any other value, it won't appear on the grid.
Grid
<asp:TemplateField HeaderText="Active">
<ItemTemplate>
<asp:CheckBox Id="CustomerCheck" runat="server"
Checked='<%# Eval("Active") %>'
Enabled="false" />
<asp:LinkButton Id="lbCustomerActive" runat="server"
Text="Activate" CommandName="OnActivate"
ToolTip='<%# "Activate or Deactivate Course: " + Eval("CourseId") %>'
OnClick="CustomerCheck_Click" CssClass="Activator" />
</ItemTemplate>
</asp:TemplateField>
You'll now be able to actually write a method for server, called CustomerCheck_Click. That server postback will call your method which can write to the database, once that value in that column is changed the grid will no longer display it.
protected void CustomerCheck_Click(object sender, EventArgs e)
{
// Logic to modify column in database.
}

ASP.NET Gridview with Link button column on Dynamic Grid

ASP.NET Gridview with Link button column on Dynamic Grid
The ASP.NET Gridview should have a linked column - 1st column, when clicked should take to another page with the clicked cell value. the Grid is a dynamic one, that is the columns are not fixed, no of columns/ column itself is dynamic. I added a asp control just for the first columns and remaining columns are dynamic, in the code behind and I add the first column "linkbutton" always.
<Columns>
<asp:TemplateField HeaderText="linkbutton">
<ItemTemplate>
<asp:LinkButton ID="linkbutton" runat="server" Text='<%#EVal("linkbutton") %>'
CommandName="ShowDetails" CommandArgument='<%#Eval("linkbutton") %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
linkbutton is part of the datatable, so when I bind the datatable to gridview it appears twice, once for the templatefield and once from the datatable bind. gridview.column().visible=false didnot work as it considers linkbutton as the only column not the datatable columns.
i tried to add the Linkbutton control from code behind that one also didnt work.
I would set the autogeneratecolumns to false, and then use asp:BoundFields in order to show the columns from the datatable, other than the linkbutton, which you are handling with the asp:TemplateField.
You can then use GridView.Columns().Visible to hide/show different columns.
You were not able to use GridView.Columns().Visible with the auto generated columns because they are not added to Columns():
Explicitly declared column fields can be used in combination with
automatically generated column fields. When both are used, explicitly
declared column fields are rendered first, followed by the
automatically generated column fields. Automatically generated column
fields are not added to the Columns collection.

How do I use the RowCreated event for GridViews

Problem:
I want to add headers in the middle of a gridview databind. I updated the DataTable to include headers and their correct positions(I've checked during debug, they're there). On the new rows that contain headers, one of the unneeded fields (unneeded as in the header doesn't need that information) has a flag called "Subheader" in it.
Background information:
So my datatable rows hold a server name, and the group the server belongs to. I updated the DataTable so it inserts a new row where the server name is the header text. The server group that this new row belongs to is "Subheader". My datatable holds more information than what my gridview shows. My gridview only needs one column, but has a column with visibility=false; which holds the server group.
What I want to achieve:
So when I bind this datatable to the gridview I want all the non-header rows to be links that point to another location. All the data rows that are headers I want to just leave them as is.
Code:
private void CurrentServers_RowCreated(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if(e.Row.Cells[1].Text != "Subheader")
{
e.Row.Cells[0].Text = "<a href='/EventViewer.aspx?m=" + e.Row.Cells[0].Text + "&s=&e=Application&r=25'>" + e.Row.Cells[0].Text + "</a>";
}
}
}
Questions:
This isn't working. e.Row.Cells[1].Text != "Subheader" always returns true. In debugging I check the value of e.Row.Cells[1].Text and somewhere in there it has the information I need.
Is this the correct event I should be handling?
How do I access that data? e.Row.Cells[1].Text and e.Row.Cells[1].ToString() do not return the result that I want, even though when in debugging I can find the value I want in e.Row
I've tried finding exactly how this works but am unable to find answers. If my GridView only has columns for 2 datatable columns, will e.Row.Cells only have the 2 cells that my gridview requires, or does this take place before it breaks apart the datatable (i.e. does it have all the columns that my datatable has)
Depending on how you bind your data and how you get server group, you could do the following:
In the item template where you're showing content of nonheader row, instead of plain text use two placeholders, one will hold label for nonhyperlink text and another will hold hyperlink. You bind both controls to whatever text property you use. And set those placeholders' visibility to Eval("ServerGroup").ToString().ToLowerInvariant().Equals("subheader") and !Eval("ServerGroup").ToString().ToLowerInvariant().Equals("subheader"). That way you won't have to write code to perform control manipulation and get away from using RowDataBound event all together.
Let me know if this doesn't make sense :)
EDIT:
<asp:GridView ID=".." runat="server" ...>
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:PlaceHolder id="phTextContent" runat="server" visible='<%# Eval("ServerGroup").ToString().ToLowerInvariant().Equals("subheader") %>'>
<asp:Label id="lblServerGroup" runat="server" text='<%#Eval("ServerGroup")%>'/>
</asp:PlaceHolder>
<asp:PlaceHolder id="phTextContent" runat="server" visible='<%# !Eval("ServerGroup").ToString().ToLowerInvariant().Equals("subheader") %>'>
<asp:HyperLink id="hlServerGroup" runat="server" Text='<%#Eval("ServerGroup")%>' NavigateUrl='<%#string.Fromat("/MyAction.aspx?param=", Eval("Param"))%>'/>
</asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

How to place a different value within a GridView, if the source is a DataTable?

First of all, I've got a DataTable which stores data in a number of fields. One of these fields stores a value, which can either be '1', '0' or '-1'.
What I'm trying to accomplish is to fill a GridView with all the data contained in this DataTable, except for the previously mentioned field. Instead of this field, I would like to display a column which shows a different icon depending on the value (either 0, 1 or -1).
In other words, if a row contains a value of '0' in this field within the DataTable, I would like a red circle icon to appear in the equivalent cell within the GridView.
Could anyone kindly explain how this may be accomplished? Below is some code which may help to explain the situation further.
The GridView is filled with the data contained in the DataTable.
source = new DataSource();
TableGridView.DataSource = source.FillTable();
TableGridView.DataBind();
What should be done after this?
EDIT: Solution added as a comment below
Well there are different approaches:
1) you could add a field to your DataTable for the image and fill it with the url of the image that corresponds to the value. Add an image to the GridView and set it's ImageUrl to that field.
2) Add a template field to your GridView and add the 3 images. In the Visible property of the each image you set something like <% (int)Eval("MyNumericValue") == x %> (x being 0, 1 or -1) . That way only 1 image is shown, the others hidden (not rendered even).
from the hip:
<TemplateField>
<ItemTemplate>
<asp:image runat="server" imageurl="~/images/0.png" Visible='<%# (int)Eval("MyNumericValue") == 0 %>' />
<asp:image runat="server" imageurl="~/images/1.png" Visible='<%# (int)Eval("MyNumericValue") == 1 %>' />
<asp:image runat="server" imageurl="~/images/-1.png" Visible='<%# (int)Eval("MyNumericValue") == -1 %>' />
</ItemTemplate>
</TemplateField>
Solved: I created the TemplateField in ASP.NET code, and the other fields programmatically in the .cs class. Next, I added a chunk of code which switches round the order of the columns. Hope someone finds this helpful.

Adding checkbox dynamically to dataGrid in C# Visual studio 2005

I have a dataGrid(not dataGridView) in which i need to add Checkbox dynamically at the first column. How can i do this.?
In the ItemDataBound event, which fires for each row of the DataGrid, you could dynamically add a control to the first cell. Easier to use a TemplateColumn, but if you want to do it dynamically as you asked, this is how I'd do it.
private void DataGrid1_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.AlternatingItem) ||
(e.Item.ItemType == ListItemType.Item))
{
CheckBox chk = new Checkbox();
e.Item.Cells[0].Controls.Add(chk);
}
The following woprks with a GridView, and I believe that it's also the same for a DataGrid.
Just add a Template Column. (You can do that in source or via the GUI). Then add a checkbod to the ItemTemplate:
<Columns>
<asp:TemplateField>
<HeaderTemplate>
Retry
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
ps. Might want to consider dropping in a GridView if you're on 2.0+
I don't believe you can add them to the first column dynamically if the datagrid already has columns, because it would just append the new column to a datagrid by using the Add method, making it the last column:
CheckBoxColumn checkCol = new CheckBoxColumn();
DataGrid1.Columns.Add(checkCol);
but to add them dynamically you could either follow thse steps at CodeProject Adding a CheckBox column to your DataGrid
or
If you still want the look of them being in the first column, then you can just create them in your client side code and set their visibile attribute to false and when you conditions are met in code behind then set the attribute to true, which gives the idea that it was crated dynamically

Categories

Resources