Loading a value on the insert command of a detailsview - asp.net

In a detailsview, how can I prepopulate one of the textboxes on the insertcommand (When the user clicks insert and the view is insert).
I think this would work for codebehind:
Dim txtBox As TextBox = FormView1.FindControl("txtbox")
txtbox.Text = "Whatever I want"
Is this right? What do I need in the aspx (not as sure)? Also, I'm assuming the server-side code will go in the itemcommand or insertcreating event.
I have typed this in VB.NET but I am using C# (I can do both so on a language agnostic forum I might type the problem in another language). I am also using a SqlDataSource, with my parameters and insert/delete/edit commands all created.
I am trying to generate a random GUID (using the GUID object), which will be prepopulated in the textbox.
Also, is the postbackurl property of a button not another way of preserving form state?
Thanks

I would update the field in the DetailsView to a TemplateField:
<asp:TemplateField>
<InsertItemTemplate>
<asp:TextBox ID="txtField" runat="server" Text='<%# Bind("GUID") %>'/>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="lblField" runat="server" Text='<%# Bind("GUID") %>'/>
</ItemTemplate>
</asp:TemplateField>
Then you have two options:
generate your GUID and insert into
your datasource. This may have to be done with SQL since you mentioned using SqlDataSource
remove the binding and access the controls from code in the
DataBound event of your DetailsView
Private Sub dv_DataBound(ByVal sender As Object, ByVal e As EventArgs) Handles dv.DataBound
dim txt as Textbox = dv.FindControl("txtField")
txt.Text = GenerateGUID()
End Sub

I'm guessing you need to use one of detailsview events.
Hook up to ItemCommand, ModeChanging or ModeChanged events and fill your value there.

I am doing something like this as well. I am hiding the DetailsView and showing it when the user clicks a button.
dvDetails.ChangeMode(DetailsViewMode.Insert)
pnlDetailMenu.Visible = True
Dim ColumnTextBox As TextBox
ColumnTextBox = dvDetails.Rows(0).Cells(1).Controls(0)
If Not ColumnTextBox Is Nothing Then
ColumnTextBox.Text = "Initial Value"
End If

Related

How to bind SelectedValue of DropdownList to DataSoruce when drop down is populated programmatically?

I have a GridView. When I go into edit mode on a row, I want one of the columns to be a dropdown. My first draft included this:
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<%# Eval("type_name") %>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ctlItemType" runat="server" datasourceid="dsItemTypes"
DataTextField="name" DataValueField="id"
selectedvalue='<%# Bind("item_type_id") %>' />
</EditItemTemplate>
</asp:TemplateField>
I should clarify that my data source included "type_name" as the name of the type and "item_type_id" as the ID corresponding to that name. That worked great. Cool.
But I need to restrict the values appearing in the drop down depending on other data about the record. So okay, fine, I removed the datasourceid, and instead populated the dropdown with code:
Private Sub ItemsGridView_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Handles ItemsGridView.RowDataBound
If e.Row.RowState = DataControlRowState.Edit Then
Dim ctlItemType As DropDownList = e.Row.FindControl("ctlItemType")
Dim parent_id = ItemsGridView.DataKeys(e.Row.RowIndex).Values(1)
ctlItemType.DataSource = ItemTypeActions.List(parent_id)
ctlItemType.DataBind()
End If
End Sub
That blows up with a "SelectedValue not found" error, I presume because it's trying to set the selected value before I populate the values.
So I tried setting the SelectedValue in code also. After the DataBind above I added:
ctlItemType.SelectedValue = DataBinder.Eval(e.Row.DataItem, "item_type_id")
That displays fine when I go into edit mode, but when I click "Update", it blows up, because item_type_id doesn't get included in the list of parameters passed to the update function. Because it's not Bind'ed, it's just set with an Eval.
So how do I make this work? Is there a way to bind a control to a datasource with code? I could find anything like DataBinder.Eval that is equivalent to <%# bind("whatever") %>. Or ... what?

Repeater won't let me access controls like buttons, dropdown, etc

I'm using a repeater ListOfArticles and have controls inside it like ddlSizes and btnSelectArticle. Normally you can just double click the control and in the aspx.vb page you can specify an action. I have heard something about Findcontrol, but can't figure out or find much information that I understand. I don't want to sound like an ass, but I would really prefer help for the aspx.vb page and not in C# or Javascript.
An example of what I'm trying to do is, once you've clicked btnSelectArticle the label lblSelection receives the following values Amount: txtAmount - Size: ddlSizes.SelectedValue.
<asp:Repeater ID="rptListOfArticles" runat="server" DataSourceID="objdsArticleList">
<asp:DropDownList ID="ddlSizes" runat="server" AutoPostBack="True" DataSourceID="objdsSizes" DataTextField="SizeName" DataValueField="SizeID" OnSelectedIndexChanged="ddlSizes_SelectedIndexChanged" />
<asp:Button ID="btnSelect" runat="server" Text="Select" OnClick="btnSelect_OnClick" />
<asp:Label ID="lblSelection" runat="server" Text=""></asp:Label>
In the aspx.vb page I can only select this and my controls like ddlSizes and btnSelect aren't recognized.
Protected Sub rptListOfArticles_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rptListOfArticles.ItemCommand
End Sub
Any help towards a solution would be great!
What you need to do is use the FindControl method to find the specific control in the selected repeater Item.
so an example would be (within the ItemCommand method)
Dim lblSelection as Label = CType(e.Item.FindControl("lblSelection"), Label)
lblSelection.Text = "Your Text"
Edit **
To Answer your questions in the comments:
Yes to access the SelectedValue of the ddlSize DropDown you will need to create this:
Dim ddlSize As DropDownList = Ctype(e.Item.FindControl("ddlSize"), DropDownList)
The Repeater will know when to call this method when any Buttons are Clicked within the Repeater. Add a CommandName to your buttons so that you can then control what happens in the ItemCommand method.
e.g.
<asp:Button id="btnDoSomething" runat="server" text="Run ItemCommand" CommandName="Command1" />
In the ItemCommand use the code:
If e.CommandName = "Command1" Then
' run your code
End If
You can handle the event of dropdownlist in ItemCommand Event. Event bubbling concept comes here actually the child control bubble the evenet up to its parent i.e repeater control so you can handle it in parent control event eventually
for more details HERE you will have indepth insight of all events of repeater

ASP ListView - Eval() as formatted number, Bind() as unformatted?

I have an ASP ListView, and have a very simple requirement to display numbers as formatted w/ a comma (12,123), while they need to bind to the database without formatting (12123). I am using a standard setup - ListView with a datasource attached, using Bind().
I converted from some older code, so I'm not using ASP.NET controls, just form inputs...but I don't think it matters for this:
<asp:SqlDataSource ID="MySqlDataSource" runat="server"
ConnectionString='<%$ ConnectionStrings:ConnectionString1 %>'
SelectCommand="SELECT NUMSTR FROM MY_TABLE WHERE ID = #ID"
UpdateCommand= "UPDATE MY_TABLE SET NUMSTR = #NUMSTR WHERE ID = #ID">
</asp:SqlDataSource>
<asp:ListView ID="MyListView" runat="server" DataSourceID="MySqlDataSource">
<LayoutTemplate>
<div id="itemplaceholder" runat="server"></div>
</LayoutTemplate>
<ItemTemplate>
<input type="text" name="NUMSTR" ID="NUMSTR"
runat="server" value='<%#Bind("NUMSTR")%>' />
<asp:Button ID="UpdateButton" runat="server" Text="Update" Commandname="Update" />
</ItemTemplate>
</asp:ListView>
In the example above, NUMSTR is a number, but stored as a string in a SqlServer 2008 database. I'm also using the ItemTemplate as read and edit templates, to save on duplicate HTML. In the example, I only get the unformatted number. If I convert the field to an integer (via the SELECT) and use a format string like Bind("NUMSTR", "{0:###,###}"), it writes the formatted number to the database, and then fails when it tries to read it again (can't convert with the comma in there).
Is there any elegant/simple solution to this? It's so easy to get the two-way binding going, and I would think there has to be a way to easily format things as well...
Oh, and I'm trying to avoid the standard ItemTemplate and EditItemTemplate approach, just for sheer amount of markup required for that.
Thanks!
As seen in my comment above, I ended up just stripping commas from the NewValues collection in the ListView ItemUpdating event, and adding in commas on the ItemDataBound event.
If there are other ways to do this in a clean way, I'm interested!
Code in VB.NET, comment syntax made to be compatible with stackoverflow's highlighting:
Protected Sub myListView_OnItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles myListView.ItemDataBound
Dim intNumber As Integer
For Each c As Control In e.Item.Controls
If TypeOf c Is TextBox Then /*ASP textbox controls*/
Dim numberText As TextBox
numberText = DirectCast(c, TextBox)
If Integer.TryParse(numberText.Text, intNumber) Then /*If the text can be parsed, format it*/
numberText.Text = String.Format("{0:###,##0}", intNumber)
End If
Next
End Sub
Protected Sub myListView_OnItemUpdating(ByVal sender As Object, ByVal e As ListViewUpdateEventArgs) Handles myListView.ItemUpdating
Dim cleanNumber As String
Dim intNumber As Integer
For Each key As String In e.NewValues.Keys
cleanNumber = e.NewValues(key).ToString().Replace(",", Nothing) /*Remove all commas*/
If Integer.TryParse(cleanNumber, intNumber) Then /*If the text can be parsed, format it*/
e.NewValues(key) = intNumber.ToString()
End If
Next
End Sub
Cannot you use <%# Bind("expression"[, "format"]) %> style?
So in your case, devise a format string (I think it should be "#,###") and ASP.NET would be able to format the string both on input and output.

Problem finding web control inside of Gridview TemplateField

Okay, so I'm having issues getting the value of a DropDownList that's inside of a TemplateField when updating my GridView. Originally I was using the RowCommand event to check the command name and then performing the appropriate task (update/delete), but I had problems with the event firing twice, so I switched it out for separate events (RowUpdating, RowDeleting). After doing this, FindControl is returning null every time. Just FYI, the gridview is inside of an UpdatePanel that has an AsyncPostBackTriggers for RowEditing, RowUpdating and RowDeleting events.
Here's my TemplateField inside of the GridView:
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label
ID="lblMedTypeEdit"
Text='<%# Bind("medDesc") %>'
runat="server">
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList
ID="ddlMedTypeEdit"
DataSourceID="srcMedTypes"
SelectedValue='<%# Bind("medtype") %>'
runat="server"
DataTextField="medDesc"
DataValueField="medCode">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Here is the code I'm using inside of
Protected Sub gvCurrentMeds_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvCurrentMeds.RowUpdating
Dim intRowIndex As Integer = e.RowIndex
Dim ddlMedType As DropDownList = CType(Me.gvCurrentMeds.Rows(intRowIndex).Cells(1).FindControl("ddlMedTypeEdit"),DropDownList)
End Sub
I also tried using a recursive function to find the control (below), but it is still returning back null.
Public Function FindControlRecursive(ByVal root As Control, ByVal id As String) As Control
If root.ID = id Then
Return root
End If
For Each c As Control In root.Controls
Dim t As Control = FindControlRecursive(c, id)
If Not t Is Nothing Then
Return t
End If
Next
Return Nothing
End Function
If you just want to know what the new value of the dropdown is, this is already provided for you in the NewValues property of the GridViewUpdateEventArgs object passed to the event handler.
In your example, e.NewValues["medtype"] should be the updated value.
You've already specified <%# Bind(...) %> on the dropdown, so ASP.NET will do the work of finding the controls and getting the new values for you - you don't have to plumb the control hierarchy yourself.

Accessing data associated with the RepeaterItem on Command execution

I want to access the data associated with the RepeaterItem in which an ItemCommand fired up. The scenario is, I have multiple RepeaterItems which Button controls in which the Command is set declaratively like this:
<asp:Repeater ID="Repeater3"
runat="server"
DataSource='<%# ClientManager.GetClientEmployees(Eval("ClientID")) %>'
OnItemCommand="RemoveEmployeeFromClient">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1"
runat="server"
Text="(x)"
CommandName="RemoveEmployeeFromClient">
</asp:LinkButton>
</ItemTemplate>
<SeparatorTemplate>,<br /></SeparatorTemplate>
</asp:Repeater>
The code behind is:
Protected Sub RemoveEmployeeFromClient(ByVal source As Object,
ByVal e As RepeaterCommandEventArgs)
' I want to access the data associated with
' the RepeaterItem which the Button was clicked.
End Sub
You can use e.Item.DataItem to get down to the data for the object, or you could store it in a hidden field.
Building on what Mitchel said, make sure you check to see that the RowType is DataRow. Don't want to do crap when you can't. The cast from e.Item.DataItem to your type would fail on the header or footer row.

Resources