The problem is like this, I have a announcement table in my database. I want to display the announcement's record that I've found from the database by using labels and text boxes. The question is how do I create new labels and text boxes each time a record is found and i want the layout to be something like this picture.
Use a Repeater or a DataList...
Try asp repeater. e.g
<asp:Repeater ID="myRepeater" runat="server" OnItemDataBound="myRepeater_ItemDataBound">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblHeading" runat="server" Text='<%# Eval("TableColoumnName") %>' />
<asp:TextBox ID="txtHeading" runat="server" Text='<%# Eval("TableColoumnName") %>' />
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
in code behind provide the data source to your repeater and bind that datasource...
protected void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
myRepeater.DataSource = // provide datasource here....
myRepeater.DataBind(); // bind the data with repeater
}
you can use gridview, repeater etc..
http://www.codeproject.com/Articles/18132/ASP-NET-using-GridView-Control-as-Lookup
Related
I'm trying to add an delete image at the end of each row in a GridView. I want the user to be able to click the image to delete the row.
So I've used a HyperLinkField to create a link to another page which will delete the record:
<asp:HyperLinkField DataNavigateUrlFields="ID"
DataNavigateUrlFormatString="RemoveLine.aspx?ID={0}"
Target="_blank" />
The HyperLinkField doesn't contain an Image tag so I created a TemplateField with an Image inside.
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="imageRemove" runat="server" ImageUrl="~/Images/smallcross.gif" />
</ItemTemplate>
</asp:TemplateField>
However the HyperLinkField and Image appear in different columns and the image has no click event.
Any way of combining the two?
I'm using ASP.Net 4.0.
Thanks in advance
Normally you need to identify which record you want to delete, you can use the CommadArgument property to identify the record's Id:
<asp:TemplateField HeaderStyle-Width="40">
<ItemTemplate>
<asp:ImageButton ID="ButtonDelete" runat="server"
ImageUrl="~/Imags/delete.png" OnClick="ButtonDelete_Click" ToolTip="Delete"
CommandArgument='<%#Bind("UserId")%>'/>
</ItemTemplate>
</asp:TemplateField>
protected void ButtonDelete_Click(object sender, EventArgs e)
{
ImageButton button = sender as ImageButton;
DeleteUserById(Convert.ToInt32(button.CommandArgument));
}
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="btnDelete" runat="server"
ImageUrl="~/Imags/delete.png" OnClick="btnDelete_Click"
ToolTip="Delete row" CommandName="Eliminar" CommandArgument='<%#Eval("UserId")%>'/>
</ItemTemplate>
You can use the CommandArgument to pass the ID value of the selected row and perform
the desires results
// fires when the ImageButton gets clicked
protected void GridView1_ItemCommand(object sender, DataGridCommandEventArgs e)
{
if(e.Commandname ="Eliminar"){
this.Eliminar(Convert.ToInt32(e.CommandArgument));
}
}
// function to delete the record
private void Eliminar(int code)
{
//custom code to delete the records
}
How about an image button?
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Images/smallcross.gif" onclick="ImageButton1_Click" />
</ItemTemplate>
you can wrap your image with a raw anchor tag , you get the same result.
<asp:TemplateField>
<ItemTemplate>
<a href="RemoveLine.aspx?ID={0}">
<asp:Image ID="imageRemove" runat="server" ImageUrl="~/Images/smallcross.gif" />
</a>
</ItemTemplate>
</asp:TemplateField>
I am using a GridView to get data from a datasource.
I want to add a textbox at the end of each column in the GridView i.e at the footer
How do I do that?
Use FooterTemplate. Example:
<asp:TemplateField>
<ItemTemplate>
...
</ItemTemplate>
<FooterTemplate>
your textboxes go here
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
...
</ItemTemplate>
<FooterTemplate>
your textboxes go here
</FooterTemplate>
</asp:TemplateField>
You should understand the differences between the BoundField and the TemplateField class. The first is used to display fields as a text, while in the TemplateField you can customize the way you're going to display the information. So, you should use BoundField or TemplateField in a column (not one nested inside another as I think you're trying), in your case it has to be the TemplateField, because you want to customize the way your footer shows up. So, it should be something like this:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblNumber" runat="server" Text='<%# Bind("Number")%>' />
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txb" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
Add TextBox in <FooterTemplate>
<asp:TemplateField HeaderText="UnitsInStock">
<ItemTemplate>
//your displaying control
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="tb1" Text="Text" runat="server" />
</FooterTemplate>
</asp:TemplateField>
Find footer control in OnRowDataBound event:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Footer)
{
TextBox tb1 = (TextBox)e.Row.FindControl("tb1");
//do your stuff
}
}
The gridview control makes databinding of complex objects rather easy. In my scenario a gridview control gets bound to a Customer object which has a few 'flat' properties and one complex property that takes an object of the type Address. The grid displays the data as expected. The problem is that I have found no way to access the values of the Address properties in code behind. For example, setting the DataKeyNames collection to DataKeyNames="Id, Address.Id" results in an error:
DataBinding: System.Data.Entity.DynamicProxies.Customer_95531162E60920A5C3C02043F6564873913B91785C856624301E8B6E89906BF6 does not contain a property with the name Address.Id.
What is the proper way to access the value of the Address.Id field in code behind? Ideally I'd like to do something like:
protected void CustomerDetailsObjectDataSource_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
if (CustomersGridView.SelectedIndex < 0) return;
// Retrieving the Customer's id works:
e.InputParameters["id"] = Convert.ToString(CustomersGridView.DataKeys[CustomersGridView.SelectedIndex].Value);
// Retrieving the Address id doesn work:
e.InputParameters["id"] = Convert.ToString(CustomersGridView.DataKeys[CustomersGridView.SelectedIndex].Values["Address.Id"].ToString());
}
Here's the asp code:
<ContentTemplate>
<asp:GridView ID="CustomersGridView" runat="server" AutoGenerateColumns="False" DataSourceID="CustomersObjectDataSource"
onselectedindexchanged="CustomersGridView_SelectedIndexChanged" DataKeyNames="Id,Address.Id" ondatabound="CustomersGridView_DataBound">
<Columns>
<asp:TemplateField HeaderText="Aktion">
<ItemTemplate>
<asp:LinkButton runat="server" ID="SelectCustomerButton" Text="Auswählen" CommandName="Select" /> <br/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Kunde" SortExpression="LastName" ItemStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label ID="NumberLabel" runat="server" Text='<%#"GpNr: " + Eval("Number")%>'></asp:Label><br/>
<asp:Label ID="SalutationLabel" runat="server" Text='<%#Eval("Salutation")%>'></asp:Label>
<asp:Label ID="TitleLabel" runat="server" Text='<%#Eval("Title")%>'></asp:Label>
<asp:Label ID="FirstNameLabel" runat="server" Text='<%#Eval("FirstName")%>'></asp:Label>
<asp:Label ID="LastNameLabel" runat="server" Text='<%#Eval("LastName")%>'></asp:Label><br/>
<asp:Label ID="NameContactPersonLabel" runat="server" Text='<%#"Kontakt: " + Eval("NameContactPerson")%>'></asp:Label>
</ItemTemplate>
<ItemStyle VerticalAlign="Top" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Adresse" SortExpression="Address.PostalCode" ItemStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label ID="AddressIdLabel" runat="server" Text = '<%#Eval("Address.Id") %>'></asp:Label>
<asp:Label ID="AddressStreetLabel" runat="server" Text='<%#Eval("Address.Street")%>'></asp:Label>
<asp:Label ID="AddressHouseNumberLabel" runat="server" Text='<%#Eval("Address.HouseNumber")%>'></asp:Label>
<asp:Label ID="AddressHouseNumberExtensionLabel" runat="server" Text='<%#Eval("Address.HouseNumberExtension")%>'></asp:Label>
<asp:Label ID="AddressDoorNumberLabel" runat="server" Text='<%#Eval("Address.DoorNumber")%>'></asp:Label><br/>
<asp:Label ID="AddressPostalCodeLabel" runat="server" Text='<%#Eval("Address.PostalCode")%>'></asp:Label>
<asp:Label ID="AddressCityLabel" runat="server" Text='<%#Eval("Address.City")%>'></asp:Label><br/>
<asp:Label ID="AddressCountryLabel" runat="server" Text='<%#Eval("Address.Country")%>'></asp:Label>
</ItemTemplate>
Thanks!!
the reason is Gridview consider datakeynames as the property name, it is using DataBinder.GetPropertyValue() during CreateChildControls() to retrieve data key values, while DataBinder.Eval support multiple level property( as long as it is separated by dot character)
Example:
object item = ...
DataBinder.Eval(item, "Address.Id"); //no problem
DataBinder.GetPropertyValue(item, "Address.Id"); //will throw exception
there are several solution to solve your problem:
derive your custom gridview(override the CreateChildControls()) that it's datakeynames support multi layer expression. You may refer the default implementation by using Reflector. (lots of work)
store the complex property values into viewstate during RowDataBound event (prefered, and also used by me too :) )
Example:
private void CustomersGridView_RowDataBound(object sender, EventArgs args)
{
if(e.Row.RowType = DataControlRowType.DataRow)
{
object id = DataBinder.Eval(e.Row.DataItem, "Id");
//DictionaryInViewState is a variable that will be stored into viewstate later
DictionaryInViewState[id] = DataBinder.Eval(e.Row.DataItem, "Address.Id");
}
}
References:
http://www.telerik.com/forums/problem-with-a-complex-datakeynames-value
In my ASP.NET application, I have a GridView. For a particular field in this GridView, I've added an EditItemTemplate with a DropDownList. However, if the value of the field is "X", then I want to just display a label instead of the DropDownList. So how can I programatically check the field value, then decide which control to display?
Here is my EditItemTemplate:
<EditItemTemplate>
<asp:DropDownList ID="DropDownListLevel_ID" runat="server"
DataSourceID="ODSTechLvl" DataTextField="Level_Name"
DataValueField="Level_ID" SelectedValue='<%# Bind("Level_ID", "{0}") %>'>
</asp:DropDownList>
</EditItemTemplate>
If the value of Level_ID is "X", then I want to use:
<asp:Label ID="LabelLevel_ID" runat="server" Text='<%# Bind("Level_ID") %>'></asp:Label>
instead of the DropDownList.
I tried embedding an if statement before the DropDownList to check Eval("Level_ID"), but that doesn't seem to work. Any thoughts?
Try this:
<EditItemTemplate>
<asp:DropDownList ID="DropDownListLevel_ID" runat="server"
DataSourceID="ODSTechLvl" DataTextField="Level_Name"
DataValueField="Level_ID" SelectedValue='<%# Bind("Level_ID", "{0}") %>'
Visible='<%# Eval("Level_ID") != "X" %>'>
</asp:DropDownList>
<asp:Label ID="LabelLevel_ID" runat="server" Text='<%# Bind("Level_ID") %>'
Visible='<%# Eval("Level_ID") == "X" %>'></asp:Label>
</EditItemTemplate>
Here is something that will work for ASP.Net.
You could create an RowDataBound event and hide the label or the DropDownList
<asp:GridView id="thingsGrid" runat="server" OnRowDataBound="thingsGrid_RowDataBound"
... >
...
and in your code behind:
protected void thingsGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var boundData = e.Row.DataItem;
...
if (boundDataMeetsCondition)
{
e.Row.Cells[4].FindControl("editThingDropDownList").Visible = false;
e.Row.Cells[4].FindControl("editThingLabel").Visible = true;//*
}
else
{
...
}
}
}
*note this is less than ideal because it hard codes the cell index, and the ID of the controls is a string that wont be checked until runtime. There are much more elegant ways to solve this problem in asp.net mvc.
the OnRowDataBound is a sledge hammer that will give you full access to your grid, page methods, and your entire application. In a very simple scenario you could also do it inline without involving the codebehind.
<asp:Label ID="Label1" runat="server" Visible='<%# Convert.ToBoolean(Eval("BooleanPropertyInData"))%>' Text='<%# Eval("PropertyInData") %>'></asp:Label>
or
<asp:Label ID="Label1" runat="server" Visible='<%# Eval("PropertyInData").ToString()=="specialValue"%>' Text='<%# Eval("PropertyInData") %>'></asp:Label>
in the first inline approach, your data source has to expose such a property, and in the second you are hard coding your specialValue business logic into your presentation, which is also ugly and will lead to problems with maintainability.
Here's my code in a gridview that is bound at runtime:
...
<asp:templatefield>
<edititemtemplate>
<asp:dropdownlist runat="server" id="ddgvOpp" />
</edititemtemplate>
<itemtemplate>
<%# Eval("opponent.name") %>
</itemtemplate>
</asp:templatefield>
...
I want to bind the dropdownlist "ddgvOpp" but i don't know how. I should, but I don't. Here's what I have, but I keep getting an "Object reference" error, which makes sense:
protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) //skip header row
{
DropDownList ddOpp = (DropDownList)e.Row.Cells[5].FindControl("ddgvOpp");
BindOpponentDD(ddOpp);
}
}
Where BindOpponentDD() is just where the DropDownList gets populated. Am I not doing this in the right event? If not, which do I need to put it in?
Thanks so much in advance...
Ok, I guess I'm just dumb. I figured it out.
In the RowDataBound event, simply add the following conditional:
if (myGridView.EditIndex == e.Row.RowIndex)
{
//do work
}
Thanks to Saurabh Tripathi,
The solution you provided worked for me.
In gridView_RowDataBound() event use.
if(gridView.EditIndex == e.Row.RowIndex && e.Row.RowType == DataControlRowType.DataRow)
{
// FindControl
// And populate it
}
If anyone is stuck with the same issue, then try this out.
Cheers.
I had the same issue, but this fix (Jason's, which is adding the conditional to the handler) didn't work for me; the Edit row never was databound, so that condition never evaluated to true. RowDataBound was simply never called with the same RowIndex as the GridView.EditIndex. My setup is a little different, though, in that instead of binding the dropdown programmatically I have it bound to an ObjectDataSource on the page. The dropdown still has to be bound separately per row, though, because its possible values depend on other information in the row. So the ObjectDataSource has a SessionParameter, and I make sure to set the appropriate session variable when needed for binding.
<asp:ObjectDataSource ID="objInfo" runat="server" SelectMethod="GetData" TypeName="MyTypeName">
<SelectParameters>
<asp:SessionParameter Name="MyID" SessionField="MID" Type="Int32" />
</SelectParameters>
And the dropdown in the relevant row:
<asp:TemplateField HeaderText="My Info" SortExpression="MyInfo">
<EditItemTemplate>
<asp:DropDownList ID="ddlEditMyInfo" runat="server" DataSourceID="objInfo" DataTextField="MyInfo" DataValueField="MyInfoID" SelectedValue='<%#Bind("ID") %>' />
</EditItemTemplate>
<ItemTemplate>
<span><%#Eval("MyInfo") %></span>
</ItemTemplate>
</asp:TemplateField>
What I ended up doing was not using a CommandField in the GridView to generate my edit, delete, update and cancel buttons; I did it on my own with a TemplateField, and by setting the CommandNames appropriately, I was able to trigger the built-in edit/delete/update/cancel actions on the GridView. For the Edit button, I made the CommandArgument the information I needed to bind the dropdown, instead of the row's PK like it would usually be. This luckily did not prevent the GridView from editing the appropriate row.
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ibtnDelete" runat="server" ImageUrl="~/images/delete.gif" AlternateText="Delete" CommandArgument='<%#Eval("UniqueID") %>' CommandName="Delete" />
<asp:ImageButton ID="ibtnEdit" runat="server" ImageUrl="~/images/edit.gif" AlternateText="Edit" CommandArgument='<%#Eval("MyID") %>' CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="ibtnUpdate" runat="server" ImageUrl="~/images/update.gif" AlternateText="Update" CommandArgument='<%#Eval("UniqueID") %>' CommandName="Update" />
<asp:ImageButton ID="ibtnCancel" runat="server" ImageUrl="~/images/cancel.gif" AlternateText="Cancel" CommandName="Cancel" />
</EditItemTemplate>
</asp:TemplateField>
And in the RowCommand handler:
void grdOverrides_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Edit")
Session["MID"] = Int32.Parse(e.CommandArgument.ToString());
}
The RowCommand, of course, happens before the row goes into edit mode and thus before the dropdown databinds. So everything works. It's a little bit of a hack, but I'd spent enough time trying to figure out why the edit row wasn't being databound already.
protected void grdDevelopment_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (grdDevelopment.EditIndex == e.Row.RowIndex && e.Row.RowType==DataControlRowType.DataRow)
{
DropDownList drpBuildServers = (DropDownList)e.Row.Cells[0].FindControl("ddlBuildServers");
}
}
Try this one
This will help u
This code will be do what you want:
<asp:TemplateField HeaderText="garantia" SortExpression="garantia">
<EditItemTemplate>
<asp:DropDownList ID="ddgvOpp" runat="server" SelectedValue='<%# Bind("opponent.name") %>'>
<asp:ListItem Text="Si" Value="True"></asp:ListItem>
<asp:ListItem Text="No" Value="False"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("opponent.name") %>'></asp:Label>
</ItemTemplate>