Problem finding a control within a FormView from code-behind - asp.net

Here the code behind... I'm trying to retrieve this control so I can add items to the drop down list (I'm retrieving the Role Groups to add to the drop down list in the code-behind)
Protected Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim DDRoleGroups As DropDownList
DDRoleGroups = FormView1.FindControl("DDRoleGroup")
End Sub
Here's the FormView: (I took out most of the fields so it's easier to read)
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ID"
DataSourceID="ObjectDataSource_Vendors"
DefaultMode="Insert" BorderColor="DarkGray"
BorderStyle="Solid" BorderWidth="1px" CellPadding="4" Visible="False">
<EditItemTemplate>
</EditItemTemplate>
<InsertItemTemplate>
<label class="form_label">Role Group:</label><br /><asp:DropDownList ID="DDRoleGroup"
runat="server" Width="175px"
EnableViewState="False">
</asp:DropDownList>
</InsertItemTemplate>
</asp:FormView>
Could it possibly have to do with the fact that it's in the Page_Load sub and the control hasn't acctually loaded yet?
Thanks,
Matt

Your dropdown only exists in Insert mode. Try to implement the formview's ModeChanged event and retrieve the control if CurrentMode == Insert:
protected void FormView1_ModeChanged(object sender, EventArgs e)
{
if (FormView1.CurrentMode == FormViewMode.Insert)
{
DropDownList DDRoleGroups = FormView1.FindControl("DDRoleGroup");
// fill dropdown
}
}
You cannot handle this in Page_Load, as the form has not yet switched into Insert mode.

FindControl on a formview will only work for the template that the FormView's "CurrentMode" property is set to.
In your case, you can only do FindControl for "DDRoleGroups" if your FormView is set to "Insert", since that's the template that your control exists in.
Hope that helps.

Related

textChanged event doesn´t fire and i have autopostback=true

I have a textbox event declarated but it doesn´t fire. I have seen in SO other answers but all of them say that autopostback property has been true and i have it
my aspx
<asp:ScriptManager ID="ScriptManager2" runat="server" />
<asp:TextBox runat="server" ID="txtDia" Width="120px" Height="20px"
AutoPostBack="True" CssClass="textbox" OnTextChanged="txtDia_TextChanged"/>
<Juice:Datepicker ID="Datepicker2" runat="server" TargetControlID="txtDia"
DateFormat="dd/mm/yy"
MonthNames="Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto,Septiembre,Octubre,Noviembre,Diciembre"
MonthNamesShort="Ene,Feb,Mar,Abr,May,Jun,Jul,Ago,Sep,Oct,Nov,Dic,"
AutoPostBack="True" /></td>
and my aspx.vb
Protected Sub txtDia_TextChanged(sender As Object, e As System.EventArgs) Handles txtDia.TextChanged
CargarDatos()
End Sub
You should define your textbox like this (see OnTextChanged="txtDia_TextChanged" being added):
<asp:TextBox OnTextChanged="txtDia_TextChanged"
runat="server" ID="txtDia" Width="120px" Height="20px"
AutoPostBack="True" CssClass="textbox"/>
And remember that this event will rise onblur (focus removed from that textbox) only.
In your aspx you should write
<asp:TextBox runat="server" ID="txtDia" Width="120px" Height="20px"
AutoPostBack="True" CssClass="textbox" OnTextChanged="txtDia_TextChanged"/>
The event is not triggered if you overwrite the text in codebehind. So for example if you databind the control where the TextBox sits in.
You should so that only If Not IsPostBack:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
DataBindAllControls(); // including your textbox
}
}
Edit: Sorry, here VB.NET:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
DataBindAllControls() ' including your textbox
Else
End Sub
What FAngel said is correct.
I've had the same issue when validating dates and using jquery datepicker. I used the below to fire the validation routines after the box had been populated. So technically they fired twice, once after the textbox had lost focus to the datepicker, then again when my code fired after the datepicker had populated the textbox. It would have been better to disable the onblur event and call directly from the below, but wasn't possible in my project.
$('.datePicker').each(function () {
$(this).datepicker({
onSelect: function () {
$(this).trigger('blur');
}
});
});
You can use a variation on this by disabling the auto-postback and manually triggering it via the onSelect event.
You need to specify the method to be called when the event is fired like so:
<asp:TextBox runat="server" ID="txtDia" Width="120px" Height="20px" OnTextChanged="txtDia_TextChanged" AutoPostBack="True" CssClass="textbox"/>
Note:
OnTextChanged="txtDia_TextChanged"

Using FindControl method of FormView within a Repeater

I need an advice how to correct my code. I am using FindControl method to find TextBox inside Repeater. This is my markup:
<asp:Repeater ID="Repeater1">
HERE ARE SOME OTHER DATA
<ItemTemplate>
<asp:FormView ID="FormViewAddComment" runat="server"
DataSourceID="SqlDataSourceInsertComments" DefaultMode="Insert"
OnItemInserted="FormViewAddComment_ItemInserted"
OnItemInserting="FormViewAddComment_ItemInserting">
<InsertItemTemplate>
<asp:TextBox ID="txtAddComment" runat="server" CssClass="textbox"
Text='<%# Bind("CommentText") %>' Width="200px" />
<asp:Button ID="btnAddComment" runat="server" CssClass="button"
Text="Comment" CommandName="Insert" CausesValidation="false"/>
</InsertItemTemplate>
</asp:FormView>
</ItemTemplate>
</asp:Repeater>
And this is my code behind:
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
Dim FormView As FormView = DirectCast(Repeater1.FindControl("FormViewAddComment"), FormView)
Dim Comment As TextBox = DirectCast(FormView.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
The Comment TextBox is not found and the code throws an Object reference error when it tries to access the Text property.
You can find the textbox inside it using ItemDataBound event.
Thanks
You are accessing "txtAddComment" which is there in FormView,then why are you finding FormView in Repeater and then again in textbox in that...you can directly find out it...
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
If (FormView1.CurrentMode == FormViewMode.Insert)
Dim Comment As TextBox = DirectCast(FormViewAddComment.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
EDIT:-
My point is that you are writting the code in ItemInserting Event of FormView,so there you can directly find the FormView.I would suggest to use NamingContainer property in oredr to find the FormView which has trigged the event,by this way you can find the FormView then you can easily find the TextBox in it.
There is example of NamingContainer for Gridview Here

Formview.ChangeMode is not working

This is my webpage:
<asp:FormView
ID = "frmView1"
DefaultMode = "Insert"
runat = "server"
>
<ItemTemplate>
Item Template
</ItemTemplate>
<InsertItemTemplate>
Insert Item Template
</InsertItemTemplate>
</asp:FormView>
<asp:Button ID="btnSubmit" Text="Submit" runat="server" />
and this is the code-behind:
Private Sub btnSubmit_Click(sender As Object, e As System.EventArgs) Handles btnSubmit.Click
frmView1.ChangeMode(FormViewMode.ReadOnly)
End Sub
When I'm clicking the btnSubmit the formview is not showing anything! Is this the right way to change mode in code behind?
Moreover, in code behind instead of ChangeMode if write this:
frmView1.DefaultMode = FormViewMode.ReadOnly
forview shows the content of InsertItemTemplate. Could someone please explain what's going on here?
FormView won't show unless you bind, something like this:
using(SqlDataAdapter adapter = new SqlDataAdapter(sql,connection))
{
DataTable table = new DataTable();
adapter.Fill(table);
FormView1.DataSource = table;
FormView1.DataBind();
}
And just add EmptyDataTemplate tag to show empty message if your datasource don't return any value.
<EmptyDataTemplate>
There is nothing to see here.
</EmptyDataTemplate>
follow this tutorial and more about this on MSDN
In your code
<asp:Button ID="btnSubmit" Text="Submit" runat="server" />
must change to
<asp:Button ID="btnSubmit" Text="Submit" runat="server" command="ChangeModeToReadOnly" OnCommand="Button_Command" />
Instead of implementing OnClick event implement this
Protected Sub Button_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs)
Select Case e.CommandName
Case "ChangeModeToReadOnly"
frmView1.ChangeMode(FormViewMode.ReadOnly)
End Select
End Sub
You can try with adding the following DataBound function
protected void myFormView_DataBound(object sender, EventArgs e)
{
frmView1.ChangeMode(FormViewMode.ReadOnly);
}
The syntax is in C#

Can't find dropdown list in RowDataBound event

I'm following this example http://www.codeproject.com/KB/webforms/Editable_GridView.aspx to build an editable GridView control.
I have this code in my GridView:
<asp:TemplateField HeaderText="Negócio">
<ItemTemplate>
<asp:Label ID="lblNegocio" runat="server" Text='<%# Eval("Negocio") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlNegocio" runat="server" />
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlNewNegocio" runat="server" />
</FooterTemplate>
Now, I'm trying to fill the dropdown in the EditItemTemplate with some dynamic values just as the example says, in the RowDataBound Event of the grid. But when I do this, the FindControl method always returns Nothing:
Protected Sub gdvRegraRotationDefault_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gdvRegraRotationDefault.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ddlNegocio As DropDownList = e.Row.FindControl("ddlNegocio")
End If
End Sub
If I can't find the Dropdown I can't load the values in it and when I'm going to edit de entry it will be empty.
Can someone help me?
Thank you (:
Please use the RowEditing-Event, as your DropDownList should only be shown when clicking Edit.
But first, you have to bind the GridView newly as the GridView now needs to render different controls for the edit row:
protected void gdvRegraRotationDefault_RowEditing(object sender, GridViewEditEventArgs e)
{
gdvRegraRotationDefault.EditIndex = e.NewEditIndex;
gdvRegraRotationDefault.DataBind();
GridViewRow row = gdvRegraRotationDefault.Rows[e.NewEditIndex];
DropDownList ddl = row.FindControl("ddlNegocio") as DropDownList;
//now do databinding for DropDownList
}
The FindControl always return null because when your in the RowDataBound event you can get the label only.
If you want to fill the DropDownList when you click the edit button on the grid, then you have to use the GridViewRowEditing event.
In the RowDataBound event, simply add the following conditional:
if (myGridView.EditIndex == e.Row.RowIndex)
{
//do work
}

ASP.NET - GridView - How to programmatically add and read new controls to the cell?

Here is the setup:
I programmatically populate my gridview using LINQ to SQL query. Then I enter the edit mode and want to replace some standard TextBox controls with DropDownLists like this:
'excerpt from GridView1_RowEditing
Dim ddlist1 As New DropDownList
Dim res1 = From items1 In mydb.Items
Select items1.Col10
ddlist1.DataSource = res1
ddlist1.DataBind()
GridView1.Rows.Item(0).Cells(1).Controls.Add(ddlist1)
At this moment I have my gridview showing standard textbox control and new DDList control (in the Column 1).
The problem is -- I cant read the value from DDList in the RowUpdating method. It seems like DDList control is not in the GridView1.Rows.Item(0).Cells(1).Controls collection.
RowUpdating method sees only standard TextBox control and can read it's value.
Any suggestions are welcome. I just don't understand something here :(
Use TemplateField, and then you can locate your dropdown using FindControl
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
...
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating
Dim ddl = CType(GridView1.Rows(e.RowIndex).Cells(1).FindControl("DropDownList1"), DropDownList)
End Sub

Resources