I have a FormView which contains 5 dynamic DropDownLists. By dynamic, I mean the lists of dropdowns can be increased or decreased - depending on how many questions I have in my DB.
When I click the save button, I'm able to retrieve and store the content of the text boxes. But I'm not able to retrieve the DropDownLists.
One of the problems is that the ID of the DropDownLists changes name after I click the Save Button.
Why? Because upon Databinding of my DropDownLists, I rename the ID's so that I can identify which is which and store the appropriate data in the DB.
I'm not sure if I'm "attacking" this all wrong.
Here's my aspx code:
<asp:FormView runat="server" (...)>
//Lots of textfields here
<asp:Repeater runat="server" id="myRepeater"> //Datasource is bound in codebehind.
<ItemTemplate>
<li>
<div class="value"> <asp:DropDownList id="score" runat="server" OnDataBinding="hotelCriterias_DataBinding" /> </div>
</li>
</ItemTemplate>
</asp:Repeater>
</asp:FormView>
Here I rename the ID's and databind the datasource
protected void myDropDownList_DataBinding(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)(sender);
ddl.ID = "question" + Eval("questionID").ToString(); //Rename ID to 'question1, question2...)
Repeater rep = (Repeater)myFormView.FindControl("myRepeater");
rep.DataSource = this.dtQuestions;
rep.DataBind();
}
Try using an ObservableCollection object class as an intermediary between your drop down list and DB access.
By setting the ObservableCollection based class to be the data context for the list and handling a DataContextChanged event, you will always know what data is being displayed without having to worry about keeping track of where it is displayed.
When you hit save button, you need to iterate your repeater, should be like
protected void btnSave_Click(object sender, EventArgs e)
{
if (Repeater1.Items.Count > 0)
{
for (int count = 0; count < Repeater1.Items.Count; count++)
{
DropDownList ddl = (DropDownList)Repeater1.Items[count].FindControl("ddl");
ddl.SelectedValue//
}
}
}
Related
I would like to parse a row of data from Gridview in ASP.NET to a second page displaying contents of the row data from the previous page. My Gridview has already been linked to the database.
My current Gridview looks something like this:
I would like to achieve this when I click on the send details hyperlink:
If I click on the second row the data from that row will display in the next page
The following codes are what I had put under my link button itemTemplate:
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("name") %>'></asp:Label>
<asp:LinkButton ID="viewTours" runat="server" CommandName="view" CommandArgument='<%# Bind("name") %>' PostBackUrl='<%#"~/details.aspx?RowIndex=" + Container.DataItemIndex %>'>View</asp:LinkButton>
</ItemTemplate>
This is my page load method from the second page where I want to load the data from.
protected void Page_Load(object sender, EventArgs e)
{
if (this.Page.PreviousPage != null)
{
int rowIndex = int.Parse(Request.QueryString["RowIndex"]);
GridView GridView = (GridView)this.Page.PreviousPage.FindControl("GridView");
GridViewRow row = GridView.Rows[rowIndex];
name.Text = (row.FindControl("name") as Label).Text;
//name.Text = row.Cells[0].Text; (this did not work either, i got the same error)
}
}
However I get a squiggly line on name.Text saying that it does not exist, even though I do have a label with the id name in the design view of my html (second) page.
How can I make it such that I can parse data from the selected Gridview row to another page? Assuming that I can customize the second page and put the labels wherever I like.
This is the code from my gridview. As my binding has been done through the UI I dont have much codes for it, except to redirect the selected gridview row to another page.
protected void GridView_SelectedIndexChanged(object sender, EventArgs e)
{
Session["tour"] = GridView;
Response.Redirect("tourDetails.aspx");
}
I still get the error that the label text does not exist, when it actually exists in the page itself.
Image of the Label with the id=name:
My label DOES contain runat="server":
You are confusing binding data with structure. When you try to get a control with the name key, you really mean Label1, so change
name.Text = (row.FindControl("name") as Label).Text;
to
name.Text = (row.FindControl("Label1") as Label).Text;
I have a gridview which gets populated with the help of a sqldatasource.
Once the gridview is created I want to add a manual column created Notes so that the user can enter notes for each row and then click the submit the form.
In the <Columns> field of the grid view I have this:
<asp:TemplateField HeaderText="Notes">
<ItemTemplate>
<asp:TextBox ID="txtNotes" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
This actually creates the new column just fine but when I enter data in the textboxes it disappears when clicking submit.
In the submit even I iterate through each gridview row like so:
foreach (GridViewRow row in gvResults.Rows)
{
row.Cells[0].Text =
...
string notes = (row.Cells[10].FindControl("txtNotes") as TextBox).Text;
}
So the string notes is always empty, it seems that on postback the value is reset; because it recreates the txtNotes textbox.
How can I keep the value on postback?
When you bind the GridView, make sure you check to see if it's a postback.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
LoadData(); //if you did this without checking IsPostBack, you'd rebind the GridView and lose the existing rows
}
protected void LoadData()
{
//bind GridView etc
}
I have a listbox inside of a gridview which appears when you click edit, it has a list of event types which you can select multiple. I cannot figure out how to update my entity when the update button is clicked. I need to be able to update the entity collection with the selection made from the listbox inside the gridview. The gridview is using an entity datasource. Below is the list box in the gridview.
<asp:TemplateField HeaderText="Event Type">
<ItemTemplate>
<asp:Label runat="server" ID="eventTypeLabel" Text="<%#VenueExplorer.Utilities.StringUtils.convertEventsToCommaString(Container.DataItem) %>" />
</ItemTemplate>
<EditItemTemplate>
<asp:ListBox ID="eventListbox" runat="server" DataSourceID="eventTypeDataSource" DataValueField="EventTypeID" DataTextField="EventType" SelectionMode="Multiple"></asp:ListBox>
</EditItemTemplate>
</asp:TemplateField>
Is there a way I can update the entity binded to the gridview before the actual save is performed?
During the RowUpdating event of your GridView, you can capture the ListBox's selected values.
Without knowing your full markup or database structure, I can only mock up the intended code. Something like this, though you'll obviously have to modify it to suit your needs:
protected void grdView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
ListBox eventListbox = (ListBox)grdViewName.Rows[e.RowIndex].Cells[ZeroBasedCellNumberOfTheListBox].FindControl("eventListbox");
// Retrieve the currently selected entity (row) from the database
ParentEntity yourParentEntity = from entity in DataContext.ParentEntity where entity.ID == grdViewName.Rows[e.RowIndex].Cells[IndexOfYourEntitysID].Text;
foreach (ListItem item in eventListbox.Items)
{
if (item.Selected)
{
EventType eventType = new EventType();
eventType.ID = item.Value;
eventType.Name = item.Text;
yourParentEntity.EventTypes.Add(eventType); }
}
DataContext.Commit();
}
I've been trying to get this working for a couple of hours now but nothing from google could help me fix the problem.
I have a very simple repeater control:
<asp:Panel ID="userDefDiv" Visible="false" runat="server">
<asp:Repeater ID="userDefRepeater" EnableViewstate="false" runat="server">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" EnableViewState="false"></asp:TextBox><br/>
</ItemTemplate>
</asp:Repeater>
</asp:Panel>
the userDefDiv panel is inside another panel, which is inside contentPLaceHolder.
the parent panel to userDefDiv does NOT have the "enableviewstate="false"".
So.
Everything on this page happens after a couple of linkbuttons_click. so nothing happens during page_load. And after i click another linkbutton i want to get the data from the different textboxes that is within the repeater.
C# code:
This is the code to create all the repeater items.
public void createUserDef()
{
DataTable userDefData;
userDefData = ..... (data from Database.)
userDefDiv.Visible = true;
userDefRepeater.DataSource = userDefData;
userDefRepeater.DataBind();
}
The code for the linkbutton:
protected void linkButton_Click(object sender, EventArgs e)
{
createUserDef();
Label2.Visible = true;
foreach (RepeaterItem item in userDefRepeater.Items)
{
TextBox box = (TextBox)item.FindControl("TextBox1");
string b = box.Text;
Label2.Text += b + " . ";
}
}
As you see i create the repeater once again during the click. But the only thing i can read in label2. is a a number of " .", on dot for each textbox.
but the text from the textbox is empty..
What am I doing wrong??
thanks for reading!
Mattias
SOLUTION:
add EnableVIewState="true" to textbox & repeater.
Dont call call dataBind() before you get the values.
Thanks!
You need to set EnableViewState to 'true' for linkbuttons to work properly in a repeater
I have a ListView setup with LinqDataSource and a button that triggers search function. To avoid display data on page_load, I set ListView's DataSourceID in the Click event of the search button, bind it and set result data in LinqDataSource's Selecting event. It works as I expected but It does't look pretty to set DataSourceId in the button Click event every time the search button is clicked. How can I do this in a better and clearer way?
ASPX code:
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="WebApplication1.DataClasses1DataContext" EntityTypeName=""
TableName="Persons" onselecting="LinqDataSource1_Selecting">
</asp:LinqDataSource>
<asp:ListView ID="ListView1" runat="server" >...</asp:ListView>
<asp:Button ID="Search" Text="Search" runat="server" Click="Search_Clicked"/>
ASPX.CS code:
protected void Search_Clicked(object sender, EventArgs e)
{
ListView1.DataSourceID = LinqDataSource1.ID;
ListView1.DataBind();
}
protected void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
//Search Criteria from CheckBoxList and TextBox applied here.
DataClasses1DataContext data = new DataClasses1DataContext();
var query = from result in data.Persons
where result.ID > 2
select result;
e.Result = query;
}
I honestly don't see anything wrong with your approach, however, if you don't like it, an alternate approach would be to just statically set the DataSourceID in your ListView markup as usual, but set Visible="False", and only make it visible once the button has been clicked.