I can't figure out how to search for this and get exactly what I need. I'm trying to figure out how to change the way a piece of data displays. So, for example, if I retrieve a tinyint that is either a 1 or 0, and I want to display either "yes" or "no" respectively, how do I go about that? Here is what I have in the aspx:
<ASP:DataGrid id="AdminDataGrid" runat="server"
AutoGenerateColumns="False" AllowSorting="true"
Width="700px" CellPadding="3" EnableViewState="True"
BackColor="#EEEEEE" BorderColor="Black" HeaderStyle-BackColor="Gray"
Font-Name="Verdana" Font-Size="8pt" Font-Names="Verdana"
>
<Columns>
<asp:BoundColumn DataField="Active" HeaderText="Active State" ReadOnly="true" SortExpression="Active" />
</Columns>
</ASP:DataGrid>
To be clear, I just want it to automatically update the value every time it pulls data from the SQL table.
I've been trying a few things, but I'm not sure when and how to make the change. Member objects:
DataTable DataTableAdmin = new DataTable();
DataView DataViewAdmin;
Then in page load:
DataTableAdmin = myDataAccessObject.GetTable(strQuery);
DataViewAdmin = new DataView(DataTableAdmin);
I tried something like:
if (DataTableAdmin.Columns[0] = "0")
{
DataTableAdmin.Columns[0] = "No";
}
else
{
DataTableAdmin.Columns.[0] = "Yes";
}
But I know that's not right because it doesn't know what row to do that on. But I'd like it to be universally applied to all rows anyway. Then I thought I could do something with the DataView using a filter:
DataViewAdmin.RowFilter("Active = '0'");
But then I'm not sure how I would apply changes to what I get back. Something else I was considering would be to replace the column with a series of checkboxes that would be checked or unchecked depending on what the value is. Then that could be checked or unchecked, and the value could be updated in the database.
This is coming from the Question I posted in the comments. Pretty funny both columns are named Active in the 2 posts.
<asp:TemplateField HeaderText="Active" SortExpression="Active">
<ItemTemplate><%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %></ItemTemplate>
</asp:TemplateField>
C Shaper's answer got me on the right track, but it needed a decent amount of tweaking. First problem was: code blocks are not supported in this context. Changing the object to a TemplateColumn fixed that. Then it was failing to parse the value, saying the String was not recognized as a valid Boolean. After doing further research, I got it working with the following:
<asp:TemplateColumn HeaderText="Active" SortExpression="Active">
<ItemTemplate><%# Convert.ToBoolean(Convert.ToInt32(Eval("Active").ToString())) ? "Yes" : "No" %></ItemTemplate>
</asp:TemplateColumn>
Related
Here's my setup:
public class A
{
string FirstName{get;set;}
string LastName{get;set;}
List<Object> MyItems{get;set;}
}
my aspx page setup:
<asp:DataGrid AutoGenerateColumns="false" runat="server" ID="dgMyData" CellPadding="7">
<Columns>
<asp:BoundColumn DataField="Subject" HeaderText="Subject" />
<asp:BoundColumn DataField="EntryDate" HeaderText="Entry Date" />
</Columns>
</asp:DataGrid>
My question:
Assuming I'm using class A (or List myList) as a datasource,
I would like to add another column here to say "Yes" or "True" if there are items in the MyItems list. I don't need to display the items on this page, but I need to indicate whether they exist or not.
How would I go about doing this? I have looked at itemtemplate columns but am a bit uncertain how to do it for this data.
I am not sure if this helps you / if I understand the problem, but creating a new column and bind it to
(MyItems.Any()).toString()
helps you ?
you can also have
MyItems.Any() ? "items exist" : "no items"
the simplest solution would be to add a new property to hold the text string you want to display, like the following:
public class A
{
string FirstName{get;set;}
string LastName{get;set;}
List<Object> MyItems{get;set;}
string Info {get { return MyItems.Count > 0 ? "items exist" : "no items"; }}
}
and add a new column to the template adding
<asp:BoundColumn DataField="Info" HeaderText="Items Exist ?" />
If you do not want to change your object class, try using a template column, like:
<asp:TemplateColumn HeaderText="Items Exist ?">
<ItemTemplate>
<%#(Container.DataItem("MyItems") as IEnumerable<object>).Any()%>
</ItemTemplate>
</asp:TemplateColumn>
If you are using this on a new page, then it is better to use asp GridView instead of DataGrid. GridView is successor to Data Grid and offers more flexibility.
DataGrid was an ASP.NET 1.1 control. GridView is in 2.0. For more information on comparison please read here https://msdn.microsoft.com/en-us/library/05yye6k9%28v=vs.100%29.aspx
So the proposed answer (and one I was trying to avoid) was to add another variable to my object class.
Since this class is used in quite a few places and I didn't want to add an object, I was able to determine a way to solve this with ItemTemplate:
<asp:TemplateColumn>
<ItemTemplate>
<asp:Label Text='<%# Int32.Parse(DataBinder.Eval(Container.DataItem, "Files.Count").ToString()) > 0 ? "Yes" : "No" %>' runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
I have done gridviews before, where I bind all SQL data from data safe reader or specify column names and binds at the javascript level. This is a bit different and I am a bit stumped on how to proceed.
I have a business class that handles all SQL data queries.
This class is called to Fetch a LIST. This list contains collections and child collections.
var _InfoList = BusinessObjectClass.Get(_CriteriaKey);
I can access the list as such:-
Txtbox1.Text = _InfoList.ID#.ToString();
Now I am trying to bind one of the collections in the LIST to a gridview.:-
C#:-
gvwMembers.DataSource = _InfoList.Members;
gvwMembers.DataBind();
Where Members is a collection...
But this syntax doesn't add any thing to the gridview...The gridview is empty.
Second methodology:-
I also tried doing something like this:-
List<BusinessObjectClass> Members = new List<BusinessObjectClass>();
Members = _InfoList.Members;
gvwVendors.DataSource = Members;
gvwVendors.DataBind();
But to no avail.. this is because the problem lies in the 2nd statement:-
Members = _InfoList.Members.... this is not a valid assignment...can anyone help with this?
After fleshing out some details in the comments, it is perfectly fine to have a simple GridView with no columns defined, but make sure AutoGenerateColumns is not false. The default is true. This will create a column for you, based on each property of the object being bound.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true">
</asp:GridView>
And in order to pick and choose which properties to display, define them in the <Columns> section.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Property1" HeaderText="Property1" />
<asp:TemplateField HeaderText="Property2">
<ItemTemplate>
<asp:Label ID="lblProperty2" runat="server" Text='<%# Eval("Property2") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I having a little dilemma and Im not sure how to work around this issue. If I am editing a gridview, I am reading the rows as such
cmd.Parameters.Add("#X", SqlDbType.Char).Value = ((TextBox)GridView1.Rows[e.RowIndex].Cells[15].Controls[0]).Text;
cmd.Parameters.Add("#Y", SqlDbType.Char).Value = ((TextBox)GridView1.Rows[e.RowIndex].Cells[15].Controls[0]).Text;
When the gridview is in edit mode, both cells X and Y have textboxes because that is the default edit mode. I created the columns manually and I would like for cell X to be "read only". How can I change the code so that I can read the cell X without a textbox? Help would be greatly appreciated. Thanks!
This might be a bit too simple, but how about:
var lblHolder = (Label) GridView1.FindControl("lblMyLabel")
cmd.Parameters.Add("#X", SqlDbType.Char).Value = lblHolder.Text
Just search for your label (or whatever is holding your value) directly
Then your Grid View can look something like this
<asp:GridView ID="gvData" runat="server" AutoGenerateColumns="false" Width="95%" Font-Names="Verdana">
<RowStyle Height="40px" />
<Columns>
<asp:TemplateField HeaderText="Col1">
<ItemTemplate>
<asp:Label ID="lblMyLabel" runat="server"
Text='<%# eval("MyDataBaseField")%>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then you just need to connect a data source to the grid. There are of course loads of other ways to do it, but searching for controls by their Ids is a lot easier than trying to figure out their number in an array
I currently have a gridview that is set up and working properly but I ran into a little bit of an issue. My grid's datasource is being set from a DB table and one of the columns in the table is the numeric ID of another table. Rather than displaying this numeric ID in the grid, I need to display a description column off of the other table. Can I add an additional column to my current gridview just for display purposes?
Yes you can accomplish this by using a template on your ID field rather than creating a new field. This link has some examples. This way you can custom format your existing column.
You can use a data-set and bind this dataset to the gridview.
Using the data-set, you can add rows, columns. The below example is a good one to add rows/columns to the grid-view. You can also follow the same example with a little bit of tweaks.
http://www.codeproject.com/KB/aspnet/dynamic_Columns_in_Grid.aspx
Set AutoGenerateColumns to false, and define the columns that you want to display:
<asp:GridView ID="GridView1" runat="server" CellPadding="4" CellSpacing="0" AutoGenerateColumns="false" Width="100%">
<RowStyle BackColor="#ffffff" />
<AlternatingRowStyle BackColor="#f5f5dc" />
<HeaderStyle BackColor="Beige" ForeColor="#333333" Font-Bold="true" Height="25px" />
<Columns>
</asp:TemplateField>
<asp:TemplateField HeaderText="Address">
<ItemTemplate>
<%# Eval("Address") %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The change should be made in 3 locations:
The datasource should have the desc column brought back with it. Do the join in the database and bring it all back at once so the front end will not need to make an insane amount of calls.
On display, you can set the id column to invisible. This can be done on the code behind or on the aspx.
On edit, if it is a value that is based off of a look-up table, you will need to create a drop down list. You can query for more info if edit is needed, if not, the top two points should cover your needs.
I'm trying to delete a record from Gridview1 at the same time delete the corresponding image file off the server in a single click. (Each row in Gridview1 has an associated image file on the server.)
To delete the record, I'm using asp:CommandField showDeleteButton="true" along with a sqlDataSource's DELETE statement.
During that process, I'm also using GridView1's "onRowDeleting" event to delete the corresponding image file off the server.
Here's what it does, with the code I have below:
The record indeed gets deleted,
The file on the server does not,
There are NO errors thrown (since I guess that it's not finding the file, and this is the expected behavior).
Also consider:
I've already set up and tested a much simpler "see if files can actually be deleted off the
server" test before I started development on the Gridview. Since our files are on a hosting
company server, I wanted to test for any permissions issues.
Whereby:
Enter the fileName and extension into a text box ("myImage.jpg")
Click the button that uses the File.Delete method
WhaaLa - the file is gone from the server.
However, I can't get the file to go away with my new setup.
Here's the code:
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="libraryID"
DataSourceID="SqlDataSource1" Width="800px" onrowdeleting="deleteImageFromServer" CssClass="gridViewSmallText"
OnDataBound="rowCount">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<%--A link that goes to the uploadPage to upload a new version of the image--%>
<asp:HyperLinkField runat="server" HeaderText="SKU (Click to Update)" DataTextField="sku" DataNavigateUrlFields="sku" SortExpression="sku" DataNavigateUrlFormatString="graphicUpload.aspx?sku={0}" >
</asp:HyperLinkField>
<asp:TemplateField HeaderText="Image" SortExpression="imagePath">
<ItemTemplate>
<%--Pull the imagePath column from the database here-it also includes the image file --%>
<asp:Image ID="merchImage" runat="server" Height="100px" ImageUrl='<%# "http://www.ourcompanysite.net/" + DataBinder.Eval(Container.DataItem, "imagePath") %>' /><br />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="View Full Size">
<ItemTemplate>
<%--A link to view the image in it's full size in a new browser window--%>
<asp:HyperLink ID="fullSizeHyperlink" runat="server" NavigateUrl='<%# "http://www.leadingjewelersguild.net/" + DataBinder.Eval(Container.DataItem, "imagePath") %>' Text="View" Target="_blank" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DateUpdated" </asp:BoundField>
<%---some date stuff here--%>
<asp:BoundField DataField="DateCreated" HeaderText="First Uploaded" SortExpression="DateCreated" >
</asp:BoundField>
</Columns>
</asp:GridView>
Code behind:
protected void deleteImageFromServer(object sender, GridViewDeleteEventArgs e)
{
// I read from GridViewGuy.com that you're supposed to reference the row item via e.Values
string imageToDelete = e.Values["sku"] + ".jpg";
//I pulled the value of "imageToDelete" into a lable just to see what I was getting
//during the "onRowDeleting" and it reported back .jpg instead of the full file name
//myImage.jpg, so I guess this is the crux of my problem.
string image = Server.MapPath("/images/graphicsLib/" + imageToDelete);
string image = Server.MapPath("e:\\sites\\oursite\\files\\images\\graphicsLib\\" + imageToDelete);
if (File.Exists(image))
{
File.Delete(image);
}
//at this point the record from GridView1 is gone, but the file on server remains.
}
I think part of your problem may be that in order for e.Values["sku"] to contain a value, it has to be bound first. I don't think HyperlinkField binds its data (I could be wrong on that though so don't quote me)
First try adding a <asp:BoundField DataField="sku" Visible="false" /> in your column list. or change the HyperLinkField to TemplateField and explicitly bind the sku '<%#Bind("sku")%>'
If that doesn't work you can try changing DataKeyNames="libraryID" to DataKeyNames="libraryID,sku". You should be able to get the value out of e.Keys["sku"], or e.Values["sku"].
After you started development using the GridView control, have you verified that the deleteImageFromServer method is being called by setting a breakpoint in there?
And that imageToDelete is being set correctly?
After breaking into it, look at the 'watch' values for 'sender' and 'e'. Drill down into those to see what kind of objects they are and what values they hold.
Sometimes you have to traverse the object hierarchy in the GridVied control to get to the right object.