Reference a repeater within a gridview on item databound - asp.net

I've got an asp:DataGrid which has an asp:Gridview within it and this has many nested asp:Repeater's within that and i'm trying to reference the nested repeater from within my OnItemDataBound function
My code is similar to this
<asp:Datagrid runat="server" id="DataGrid1" OnItemDataBound="ItemDB" AutoGenerateColumns="false" Gridlines="None">
<Columns>
<asp:TemplateColumn HeaderText="">
<ItemTemplate>
<asp:GridView id="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Repeater id="Repeater1" runat="server">
<ItemTemplate>
<p>Test</p>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:Datagrid>
bit complicated but that's kinda what i'm working with.
In my ItemDB command I have this
Sub ItemDB(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs)
Dim drv As DataRowView = CType(e.Item.DataItem, DataRowView)
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
If CType(e.Item.FindControl("GridView1"), GridView).Visible = True Then
CType(e.Item.FindControl("Repeater"), GridView).Visible = True
End If
End If
End Sub
but i get the error
Object reference not set to an instance of an object
and i'm guessing it's because i am referencing a Repeater within a GridView
Any ideas how to reference this properly?
This code may not be the simplest way of doing this but i've taken over someone else's work and need a quick fix before re-coding it all
Thanks in advance

You'll have to find the Gridview in the template and then register the event for it's RowDataBound, and the find the repeater in the event handler. You should use the OnItemCreated Event to register the OnItemDataBound events, but the easiest would be to indicate the methods in your .aspx:
<asp:GridView id="GridView1" runat="server" AutoGenerateColumns="false" onrowdatabound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Repeater id="Repeater1" runat=""server"
onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<p>Test</p>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and in your code behind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//you could find the repeater in the gridview's itemtemplate here
// to the BulletedList
if (e.Row.RowType == DataControlRowType.DataRow)
{
Repeater rpt = (Repeater)e.Row.FindControl("Repeater1");
rpt.Visible = false;
}
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//you could find controls in the repeater's itemtemplate here.
}

Related

What is the preferred way to bind a radcombobox in a radgrid?

I've seen a lot of questions close to this but haven't found my answer. Here's the key points of my example below:
RadGrid has a GridTemplateColumn
GridTemplateColumn has a RadComboBox in it's EditItemTemplate
RadComboBox is bound to an ObjectDataSource and had a RequiredFieldValidator
SelectedValue='<%#Bind("SomeValue")%>' seems to work but causes validation issues
Setting RadComboBox1.SelectedValue in ItemDataBound event seems to be working
Is binding with code in the ItemDataBound the best way to do this? What's interesting is that setting SelectedValue='<%#Bind("SomeValue")%>' on the aspx page has the SelectedValue already set by the time I get the ItemDataBound but for some reason, a RequiredFieldValidator fails in edit mode when doing this unless I set the value AGAIN in ItemDataBound. Below is a stripped down version of my code.
<telerik:RadGrid ID="rgTasks" runat="server" AllowAutomaticInserts="false" AllowAutomaticUpdates="false" AutoGenerateColumns="False">
<MasterTableView DataKeyNames="Id">
<CommandItemSettings ShowRefreshButton="False"></CommandItemSettings>
<Columns>
<telerik:GridEditCommandColumn ButtonType="ImageButton" UniqueName="EditCommandColumn"></telerik:GridEditCommandColumn>
<telerik:GridBoundColumn DataField="Id" ReadOnly="True" UniqueName="Id" DataType="System.Int32" Visible="false"></telerik:GridBoundColumn>
<telerik:GridTemplateColumn UniqueName="TaskTypeId" HeaderText="Task" DataField="TaskTypeId" DefaultInsertValue="">
<ItemTemplate>
<%# Eval("TaskType.Name")%>
</ItemTemplate>
<EditItemTemplate>
<telerik:RadComboBox ID="rcbTaskTypeId" runat="server" EmptyMessage="Select TaskType..."
DataSourceID="odsTaskTypes" DataValueField="Id" DataTextField="Name" SelectedValue='<%#Bind("TaskTypeId")%>'>
</telerik:RadComboBox>
<asp:RequiredFieldValidator ID="rfvTaskTypeId" runat="server" ControlToValidate="rcbTaskTypeId" ErrorMessage="Task Type is required" Display="Dynamic"></asp:RequiredFieldValidator>
</EditItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
<asp:ObjectDataSource ID="odsTaskTypes" runat="server" SelectMethod="GetTaskTypes" TypeName="CAPAModel.CAPARepo.DataRepo"></asp:ObjectDataSource>
Protected Sub rgTasks_ItemDataBound(sender As Object, e As GridItemEventArgs) Handles rgTasks.ItemDataBound
If ((TypeOf e.Item Is GridEditableItem) AndAlso e.Item.IsInEditMode) Then
If Not String.IsNullOrEmpty(DataBinder.Eval(e.Item.DataItem, "TaskTypeId").ToString) Then
Dim rcbTaskTypeId As RadComboBox = e.Item.FindControl("rcbTaskTypeId")
rcbTaskTypeId.SelectedValue = DataBinder.Eval(e.Item.DataItem, "TaskTypeId")
End If
End If
End Sub
I saw some relevant questions but am looking for an explanation of how I SHOULD be doing this and why. Thanks.
The error occured because you have set two different datafield as DataValueField and SelectedValue. I suppose you want to show another field as selected other than data in DataValueField and DataTextField. Please take a look into the following code snippet.
ASPX:
<telerik:GridTemplateColumn DataField="test" FilterControlAltText="Filter RegistryValue column" HeaderText="test" SortExpression="test" UniqueName="test">
<EditItemTemplate>
<telerik:RadComboBox ID="RadComboBox1" Runat="server" DataSourceID="odsTaskTypes" DataTextField="Name" DataValueField="Id" >
</telerik:RadComboBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="RegistryValueLabel" runat="server" Text='<%# Eval("RegistryValue") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
C#:
protected void gridiew1_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridEditableItem && e.Item.IsInEditMode)
{
GridEditableItem editItem = (GridEditableItem)e.Item;
RadComboBox combo = (RadComboBox)editItem.FindControl("RadComboBox1");
combo.SelectedItem.Text = (string)DataBinder.Eval(e.Item.DataItem, "TaskTypeId").ToString();
}
}
So I've gone back and forth with Telerik support on this and their suggestion was to just do it the way I'm doing it. Considering that I'm binding the control in the code, I can probably get rid of SelectedValue='<%#Bind("TaskTypeId")%>' like so:
<telerik:RadComboBox ID="rcbTaskTypeId" runat="server"
DataSourceID="odsTaskTypes" DataValueField="Id" DataTextField="Name" >
</telerik:RadComboBox>
...and then just keep the code as is:
Protected Sub rgTasks_ItemDataBound(sender As Object, e As GridItemEventArgs) Handles rgTasks.ItemDataBound
If ((TypeOf e.Item Is GridEditableItem) AndAlso e.Item.IsInEditMode) Then
If Not String.IsNullOrEmpty(DataBinder.Eval(e.Item.DataItem, "TaskTypeId").ToString) Then
Dim rcbTaskTypeId As RadComboBox = e.Item.FindControl("rcbTaskTypeId")
rcbTaskTypeId.SelectedValue = DataBinder.Eval(e.Item.DataItem, "TaskTypeId")
End If
End If
End Sub

(ASP.NET) Change TextBoxes attributes (onkeypress) in GridView

I have a GridView with Textboxes inside, one for each row.
I need change the attribute "onkeypress" to validate keys.
<asp:Table runat="server">
<asp:TableRow runat="server">
<asp:TableCell runat="server">
<asp:GridView ID="gridview_1" DataSourceID="SqlDataSource3" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="textbox">
<ItemTemplate>
<asp:TextBox ID="textbox_1" CssClass="textbox_1" runat="server" Text='<%# Eval("sql_textbox")%>'>
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:TableCell>
</asp:TableRow>
And in the code behind:
foreach (GridViewRow row in gridview_1.Rows)
{
TextBox txtbox = ((TextBox)gridview_1.Rows[row.RowIndex].FindControl("textbox_1"));
txtbox.Attributes.Add("onkeypress","javascript:return validateFloatKeyPress(this, event);");
}
But when textboxes are generated, the JavaScript doesn't work. Why?
I can't do it in the ASP part, because I want the textboxes have different JavaScript methods with "if" clause in the code behind.
Thank you very much.
I put in asp:GridView the attribute onrowdatabound="GridView1_RowDataBound" and seems works properly. In code behind, I put...
<asp:GridView ID="gridview_1" DataSourceID="SqlDataSource3" AutoGenerateColumns="false" onrowdatabound="GridView1_RowDataBound" runat="server">
In code behind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.DataItem != null)
{
TextBox textBox1 = e.Row.FindControl("textbox_1") as TextBox;
textBox1.Attributes.Add("onkeypress","javascript:return validateFloatKeyPress(this, event);");
}
}
And it works properly, I think :)

Get index from selected Checkbox in DataGrid

I am using DataGrid in Asp.net
<asp:DataGrid>
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:CheckBox ID="chkDetail" runat="server" OnCheckedChanged="chkDetail_CheckedChanged" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Name" HeaderStyle-Font-Bold="true" HeaderStyle-HorizontalAlign="Center">
<EditItemTemplate>
<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Name") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
As you can see, there is a Checkbox inside DataGrid.
Everytime I check in checkbox, I would like to fire 2 events
1. Other checkboxes will be unselected (I can do it with JS - so it's ok)
2. Context will store DataGrid Name field like this
protected void chkDetail_CheckedChanged(object sender, EventArgs e)
{
Context["Name"] = ??;
}
Because DataGrid doesn't have "Rows" like GridView, I have no idea how to get the Name from the same row.
Thanks in advance.
DataGridViewRow dgvrows = TrGrid.SelectedRows;
string c = dgvrows.Cells("Late_Time").value.toString();
OR
DataGridViewRow dgvrow = this.dataGridView1.Rows[index];
DataRowView drvrow = (DataRowView)dgvrow.DataBoundItem;
You can try this code
protected void chkDetail_CheckedChanged(object sender, EventArgs e)
{
Context["Name"] = (((sender as CheckBox).NamingContainer as DataGridItem).FindControl("label_id") as Label).Text;
}
Your sender will be a CheckBox as the event is triggered by it.
Every control will have a property called NamingContainer which gives the nearest server control that inherits INamingContainer interface. In your case it is DataGridItem. And you can use FindControl method to find child control and cast it to appropriate control type to access its properties.

Binding value to textbox inside of gridview

I have problems with binding a value of a field inside a gridview to a textbox which is inside the gridview as well. I'm intending to do this for editing the table.
I tried to do this with eval and bind, but the textbox won't show the values and I have absolutely no clue why.
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:GridView ID="gvBS" runat="server" AutoGenerateColumns="false" DataKeyNames="ID" SkinID="gvWithoutWidth">
<Columns>
<asp:CommandField ShowEditButton="true" EditImageUrl="~/Images/GridView/gv_edit.png" ButtonType="Image"
CancelImageUrl="~/Images/GridView/gv_cancel.png" UpdateImageUrl="~/Images/GridView/gv_update.png"/>
<asp:TemplateField HeaderText="Sollmonat" HeaderStyle-HorizontalAlign="Left">
<EditItemTemplate>
<asp:TextBox ID="tbSollMonat" runat="server" Text='<%# Eval("SollMonat") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvSollMonat" ValidationGroup="Update" runat="server"
ControlToValidate="tbSollMonat" ErrorMessage="Bitte Sollmonat (dd.mm.yyyy) angeben"
SetFocusOnError="true">*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="revSollMonat" ValidationGroup="Update" runat="server"
ValidationExpression="^\d+$" ControlToValidate="tbSollMonat">*</asp:RegularExpressionValidator>
</EditItemTemplate>
<ItemTemplate>
<%# Eval("SollMonat")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
The thing is that it works fine inside the ItemTemplate, but doesn't inside the EditItemTemplate-element. Really no clue what the problem is.
Code behind:
Sub gvBS_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs) Handles gvBS.RowEditing
gvBS.EditIndex = e.NewEditIndex
End Sub
Sub gvBS_RowCancelingEdit() Handles gvBS.RowCancelingEdit
Me.gvBS.EditIndex = -1
gvBS_DataBind()
End Sub
I assume that the GridView enters never edit-mode since you aren't handling the RowEditing event or you didn't DataBind it after you've set gvBS.EditIndex = e.NewEditIndex;.
<asp:GridView
OnRowEditing="gvBS_RowEditing" OnRowCancelingEdit="gvBS_RowCancelingEdit"
ID="gvBS" runat="server" AutoGenerateColumns="false"
DataKeyNames="ID" SkinID="gvWithoutWidth">
codebehind (BindGrid is the method which databinds your grid):
protected void gvBS_RowEditing(object sender, GridViewEditEventArgs e)
{
gvBS.EditIndex = e.NewEditIndex;
BindGrid();
}
protected void gvBS_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gvBS.EditIndex = -1;
BindGrid();
}
You should also remember to databind it only on the first load, not on consecutive postbacks when ViewState is enabled(default). Therefore you can check the page's IsPostBack property:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}
}
Try the Bind instead of Eval in EditItemTemplate like this
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:GridView ID="gvBS" runat="server" AutoGenerateColumns="false" DataKeyNames="ID" SkinID="gvWithoutWidth">
<Columns>
<asp:CommandField ShowEditButton="true" EditImageUrl="~/Images/GridView/gv_edit.png" ButtonType="Image"
CancelImageUrl="~/Images/GridView/gv_cancel.png" UpdateImageUrl="~/Images/GridView/gv_update.png"/>
<asp:TemplateField HeaderText="Sollmonat" HeaderStyle-HorizontalAlign="Left">
<EditItemTemplate>
<asp:TextBox ID="tbSollMonat" runat="server" Text='<%# Bind("SollMonat") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvSollMonat" ValidationGroup="Update" runat="server"
ControlToValidate="tbSollMonat" ErrorMessage="Bitte Sollmonat (dd.mm.yyyy) angeben"
SetFocusOnError="true">*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="revSollMonat" ValidationGroup="Update" runat="server"
ValidationExpression="^\d+$" ControlToValidate="tbSollMonat">*</asp:RegularExpressionValidator>
</EditItemTemplate>
<ItemTemplate>
<%# Eval("SollMonat")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>

ASP.net GridView: get LinkItem's row

I want to show "Delete" link in GridView to registred users, therefore I am using templateField:
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" OnSorting="GridView_Sort">
<Columns>
<asp:TemplateField HeaderText="Control">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" onClick="deleteEntry()" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now in my deleteEntry() function how can I know anything about the row in which "Delete" link was clicked? How to ge for e.g. rowindex?
You could approach this slightly different. You see, when a control is placed inside a gridview, any event raised from that control raises also the RowCommand on the GridView.
To get what you want you could then add both CommandName and CommandArgument to your LinkButton and then catch it in the GridView's RowCommand.
<asp:LinkButton id="LinkButton1" runat="server" commandName="LinkButtonClicked" commandArgument='Eval("myObjectID")' />
where myObjectID is the name of the ID column of your object you bind the grid to.
Then
void GridView1_RowCommand( object sender, GridViewCommandEventArgs e )
{
if ( e.CommandName == "LinkButtonClicked" )
{
string id = e.CommandArgument; // this is the ID of the clicked item
}
}

Resources