I got a GridView in ASP.Net in which a user control is placed:
<asp:GridView ID="GVWunitcollection"
CssClass="gridview"
runat="server"
ShowHeader="false"
ShowFooter="false"
AutoGenerateColumns="False">
<HeaderStyle CssClass="headerstyle" />
<RowStyle CssClass="rowstyle row" />
<FooterStyle CssClass="rowstyle row" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<uc:Unit ID="UNTcol" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I bind the GridView to a List<T> filled with custom 'Unit' Classes. Each Unit consists of several properties to fill the usercontrol. (The user control holds a table, and some labels and textboxes).
How can I achieve this? Is there a simple way to bind each usercontrol to the appropriate Unit?
By the way, this is my way to mimic a "dynamic" behavior of multiple usercontrols on a page. If there's a more simple way, I would like to know how!
thank you!
You should handle the OnRowDataBound event then use FindControl and the DataItem property on the event argument to extract the data you are binding to. You should expose properties on the user control to assign values to. Here is an example:
<asp:GridView ID="gvTest" runat="server" EnableViewState="false"
OnRowDataBound="gvTest_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblTest" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
protected void Page_Load(object sender, EventArgs e)
{
gvTest.DataSource = new[] { 1, 2, 3, 4 };
gvTest.DataBind();
}
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int item = (int)e.Row.DataItem;
Label lblTest = (Label)e.Row.FindControl("lblTest");
lblTest.Text = item.ToString();
}
}
Instead of int you should cast to your specific datatype and instead of Label you should cast to your user control type. Instead of the Label's Text property you should assing to the property you've exposed from your user control.
You could create public properties on your usercontrol and assign them values in the gridview's OnRowDataBound event.
I have a post that outlines how I handle dynamic usercontrols here
Hope that helps!
Related
I'm trying to conditionally hide a template column within the Gridview, I've tried the following, but this doesn't work. Is there a way to do this within the .aspx?
<asp:TemplateField HeaderText="Grade" SortExpression="grade" Visible='<%# Convert.ToDouble(Eval("grade")) == 0 ? true : false %>'>
<ItemTemplate>
<%# string.Format("{0:0.#}", Convert.ToDouble(Eval("grade"))) %>
</ItemTemplate>
</asp:TemplateField>
you can do all of your conditional formatting (colors, hide etc.) by using the itemDataBound event. However, your sample markup does not seem to have a control - and you want to have a control for that information. And that control should have some kind of "id" or name that you can refernce in code.
However, since you did not provide much of the markup? Then I give a example for both the cells collection, and the controls that you might have.
So, say we have this simple grid view. Note how the last two fields are both City, one is a bound field (often common), and the other is a label (but could be a text box or just about any asp.net control).
<asp:GridView ID="GridView1" runat="server" CssClass="table-hover" AutoGenerateColumns="False" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:TemplateField HeaderText ="City2">
<ItemTemplate>
<asp:Label ID="lblCity" runat="server" Text = '<%# Eval("City") %>' >'<"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Ok, on page load, we load up the above grid with this code:
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
LoadGrid();
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT ID, FirstName, LastName, HotelName, City from tblHotels", new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
GridView1.DataSource = cmdSQL.ExecuteReader;
GridView1.DataBind();
}
}
Ok, we get this output:
Now, lets hide a column, based on say city. We say City = "Edmonton", we hide the control.
So, you use the itemData bound event.
I have in this sample both the bound fields (cells) collection hide example, and also for how do you do this with templated controls (find control).
So, the code is this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow gvRow = e.Row;
// hide a Bound field
TableCell f = gvRow.Cells(4);
if (f.Text == "Edmonton")
f.Style("Display") = "none";
// hide a templated control
Label lbl = gvRow.FindControl("lblCity");
if (lbl.Text == "Edmonton")
lbl.Style("Display") = "none";
}
}
And now the output is this:
I need control id from grid view to use Trigger.
My code is here :
<asp:GridView ID="gvDetails" CssClass="table table-striped table-bordered datatables dataTable" DataKeyNames="folder_path" CellPadding="5" runat="server" AutoGenerateColumns="false" Width="100%">
<Columns>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="attachment_name" HeaderText="Attachment" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDownload" Text="Download" runat="server" OnClick="DownloadFile"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-CssClass="hideGridColumn" ItemStyle-CssClass="hideGridColumn">
<ItemTemplate>
<asp:HiddenField ID="hdnAttach_Id" Value='<%#(Eval("attachment_id").ToString())%>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#2FBDF1" Font-Bold="true" />
</asp:GridView>
I need code like...
<Triggers>
<asp:PostBackTrigger ControlID="lnkDownload" />
</Triggers>
how to get "lnkDownload" id from gridview?
Exception :
You need to register each and every LinkButton as an PostBackTrigger. After each row is bound in your GridView, you'll need to search for the LinkButton and register it through code as follows:
protected void gvDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
LinkButton lb = e.Row.FindControl("lnkDownload") as LinkButton;
ScriptManager.GetCurrent(this).RegisterPostBackControl(lb);
}
And need to call this on RowDataBoundevent.
You can access the controls from the grid view using the findcontrol method
foreach(GridViewRow row in gvDetails.Rows)
{
if(row.RowType == DataControlRowType.DataRow)
{
LinkButton linkButton = (LinkButton )row.FindControl("lnkDownload");
//Your other code
}
}
I've recently encountered this problem as well.
You can find a control by doing e.row.findcontrol("NameOfControl").
Since I don't fully know what you intend to do, you can retrieve the ClientID by finding the control. Then you can specify the ID of the button by saying Button.ClientID. This will display the ContentHolder1_gridview_0_button_0.
To add attributes, you can do button.Attributes.Add("attribute", "#" + button.ClientID);
The following code is something I've fixed to have the following attribute added to the button. This is so that I can click a button and copy the textbox.
Example:
protected void gvListInventoryPassword_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HtmlButton buttonPass= (HtmlButton)e.Row.FindControl("buttonPass");
TextBox txtBox= (TextBox)e.Row.FindControl("txtBox");
buttonPass.Attributes.Add("data-clipboard-target", "#" + txtBox.ClientID);
}
}//End of gvListInventoryPassword_RowDataBound function
I have a gridview on a .NET forms application, and on postback, I am not seeing the values entered in the textbox within a gridview.
ASPX:
<asp:GridView ID="gvItems" runat="server" AutoGenerateColumns="false" ShowHeader="false" DataKeyNames="ItemId" EnableViewState="true">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="txtItem" runat="server" Text="0" EnableViewState="true" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ItemId" />
</Columns>
</asp:GridView>
<asp:Button runat="server" ID="btn" Text="Submit" OnClick="btn_OnClick" OnClientClick="javascript:return someClientStuff();" />
Code Behind:
protected void btn_OnClick(object sender, System.EventArgs e)
{
foreach(GridViewRow row in gvItems.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
var itemId = Convert.ToInt32(gvItems.DataKeys[row.RowIndex].Values[0]);
var itemValue = ((row.Cells[0].FindControl("txtItem") as TextBox).Text;
}
}
I am seeing itemId populated for each row, but itemValue is always empty string.
Been a while since I worked on a forms application, any help is appreciated!
I will assume that the DataBind of the GridView is not in if(!IsPostBack). Add this to the Page_Load
if(!IsPostBack)
{
gvItems.DataSource = soruceOftheGrid
gvItems.DataBind();
}
On the button click, try to store the values in the view state and within page load event, try to assign the viewstate back to the grid view as for each postback, page load event is called. Its good to assign the values back to grid view within page load, this will help you to retain the values you have entered.
I have parent gridview and child gridview, In child gridview I have one dropdown list, I need to fire the onselectedindexchanged event for that drop down but it is not firring because it is existed in the child gridview. If I place that dropdown in parent gridview then that selectedindexchanged is firing but I want to place that dropdown in child gridview and need to fire onselectedindexchanged event when user change the dropdown list value . In the below gridview image you can see the Status column in child gridview. It contains dropdown now I want to fire that dropdown seleted index changed event in code behind.
<asp:GridView ID="gvCountry" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img alt="" id="imgsymbol" style="cursor: pointer" src="images/plus.png" />
<asp:Panel ID="pnlOrders" runat="server" Style="display: none">
<asp:GridView ID="gvBrokerdetails" runat="server" AutoGenerateColumns="false" CssClass="mGrid" OnRowCommand="gvBrokerdetails_RowCommand"
AlternatingRowStyle-CssClass="alt" PagerStyle-CssClass="pgr" GridLines="None" AllowPaging="true">
<Columns>
<asp:BoundField DataField="BrokerName" HeaderText="Name" />
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" OnSelectedIndexChanged="ddlStatus_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Text="Include" Value="0"></asp:ListItem>
<asp:ListItem Text="Exclude" Value="1"></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton ID="imgBtnDeleteRow" runat="server" Width="25px" Height="25px" CommandName="CrossImageButton" CommandArgument='<%#Eval("BrokerId")%>' ImageUrl="~/images/cross-button.png" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CountryName" HeaderText="Country Name" />
</Columns>
</asp:GridView>
CodeBehind:
public void ddlStatus_SelectedIndexChanged(object sender, EventArgs e)
{
}
But the above is event is not calling. Is there any other process to achieve or I need to specify any new property in the code.
Find your gridview inside the RowDataBound Event of parent gridview
protected void gvCountry_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
GridView mygrid = e.Row.FindControl("gvBrokerdetails") as GridView;
}
}
than handle the event of mygrid it is your child grid you can handle any event you want or assign any property to it. an example of Selected_IndexChanged is below
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView mygrid = e.Row.FindControl("gvBrokerdetails") as GridView;
mygrid.SelectedIndexChanged += new EventHandler(mygrid_SelectedIndexChanged);
}
}
void mygrid_SelectedIndexChanged(object sender, EventArgs e)
{
// Write your code here
}
I have a Gridview control and I have placed a RadioButton in the itemtemplate. When I click a button I'm trying to get the checked property of the radio button. But When I click the checked property is always returning false. Please look into the below code and let me know where I'm making mistake.
aspx Code
<asp:GridView ID="gvDepartments" runat="server" AutoGenerateColumns="False" GridLines="None"AllowPaging="true" CssClass="mGrid" PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="rdbtn" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Label ID="lbl" runat="server"></asp:Label>
<asp:Button ID="btn" runat="server" Text="Save" OnClick="btn_Click" CssClass="button small"/>
Code Behind on button click
foreach (GridViewRow row in gvDepartments.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
RadioButton rd = (RadioButton)row.FindControl("rdbtn");
lbl.Text += rd.Checked.ToString();// +rd1.Checked.ToString();
}
}
Result will be False always in the label always. I'm using Ajaxcontroltoolkit in the application, Above controls are present in the update panel and I even tried to placing button and event in the triggers but the result is same. Please help.
Regards,
Nuthan A R
When do you assign and load the DataSource of the GridView? Note that you should do that only if(!IsPostBack) and not on every postback. So use the Page.IsPostBack property.
So assuming that you're using Page_Load for this:
protected void Page_Load(Object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
DataBindGridView(); // method that assigns DataSource and calls DataBind
}
}