I have an asp.net page which uses a listview to show 2 columns of data.
The first column has just labels and the second one has dropdowns.
My concern is, the dropdowns in second column has same items 100% of the time, they never change and since it is databound, and datasource to these dropdown is also same. As these dropdowns are in a list view this repetition happens on each row added to my list view!
So, I was thinking of removing this data redundancy being transported over the wire. Any ideas?
If you are using an ObjectDataSource, you can reduce the load time enabling the cache:
<asp:objectdatasource ID="ObjectDataSource1" runat="server"
EnableCaching="true" .... >
</asp:objectDataSource>
If your datasource is a database call then you can reduce that by storing the result of the call in a DataView object, and then binding your dropdowns to that object rather than making the call to the database for each dropdown.
You could use the following approach:
It loads the items in to the very first DropDownList and then uses JQuery to retrieve that DropDownList and and replicate the items into all of the others.
Markup
<div id="listViewContainer">
<asp:ListView ID="listView1" runat="server">
<ItemTemplate>
<div><asp:DropDownList ID="dropDownList1" runat="server"></asp:DropDownList></div>
</ItemTemplate>
</asp:ListView>
</div>
Script
$(function () {
var sourceDropDown = $('#listViewContainer').find('select').first();
$('#listViewContainer').find('select').not(sourceDropDown).each(function () {
var dropdown = $(this);
dropdown.find('option').remove();
sourceDropDown.find('option').each(function () {
var option = $(this);
dropdown.append($('<option />').text(option.text()).val(option.val()));
});
});
});
Code
void listView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.DisplayIndex == 0)
{
DropDownList dropDownList1 = (DropDownList)e.Item.FindControl("dropDownList1");
dropDownList1.DataSource = dataTable;
dropDownList1.DataTextField = "Text";
dropDownList1.DataValueField = "Value";
dropDownList1.DataBind();
}
}
Hope this helps.
Related
At the moment i have a method that retrieves a list of name from my database and return as an arraylist.
public static ArrayList GenerateFolderLocation(String username)
{
// Get User ID
SqlDataReader sqlUserID = GetUserInformation(username);
sqlUserID.Read();
int userid = int.Parse(sqlUserID["userid"].ToString());
SqlCommand cmd = new SqlCommand("SELECT distinct foldername FROM mb_folder WHERE userid=#userid", SQLGetMBoxConnection());
cmd.Parameters.AddWithValue("#userid", userid);
SqlDataReader sqldr = cmd.ExecuteReader();
ArrayList locationList = new ArrayList();
while (sqldr.Read())
{
locationList.Add(sqldr["foldername"].ToString());
}
locationList.Sort();
return locationList;
}
And in my page load method, i use DataSource and DataBind to fill up a dropdownlist i have on my main page. Note UploadLocation is the id of my dropdownlist
UploadLocation.DataSource= MBFolder.GenerateFolderLocation(Context.User.Identity.Name);
UploadLocation.DataBind();
And in my main page i have this dropdownlist and i also have a submit button
<asp:DropDownList ID="UploadLocation" runat="server"
AutoEventWireup="true" EnableViewState="true">
</asp:DropDownList>
<asp:Button ID="NewUploadFile" runat="server" Text="Upload" OnClick="NewUploadFile_Click" ValidationGroup="UploadFileValidation" AutoPostBack="true"/>
What my problem is that when i click my submit button it fires the "NewUploadFile_Click" and in that method i want to retrieve the selected value of my dropdownlist. However right now i am able to retrieve the value but it is the first value in my dropdownlist. So for example, in my arraylist there would be (test1,test2,test3) and if i select "test2" my method would retrieve "test1" instead.
In "NewUploadFile_click" i use UploadLocation.SelectedItem.Text; to get the selected value. What am i doing wrong? How can i retrieve the selected data. Thx
Try wrapping your list initialisation code within an !IsPostBack {} section in the PageLoad Event.
ie in Page_Load
if (!IsPostback)
{
... Initialise List here
}
Looks like you may be rebinding the list before you have got the data you need.
When you are calling a method to bind dropdownlist, try to add it inside
In PageLoad event:
if(!IsPostBack)
{
fillvalues();
}
So, It will not fire everytime you change your selections
Try setting AutoPostBack="true"; into your DropDownList
<asp:DropDownList ID="UploadLocation" runat="server"
AutoEventWireup="true" EnableViewState="true" AutoPostBack="true";>
</asp:DropDownList>
Confirm that you page level ViewState is enabled
and also confirm that your databinding code is inside !IsPostback condition
if (!IsPostback)
{
.... databinding code..
}
I need to bind an Asp.net DropDownList inside an ItemTemplate of a ListView. I am using LINQ to query data from using the LINQ db context as follow:
.cs
protected void ListView_AllTickets_ItemDataBound(object sender, ListViewItemEventArgs e)
{
DataClassesDataContext db = new DataClassesDataContext();
DropDownList ddl_spList = (DropDownList)e.Item.FindControl("DropDownList_SpList");
//Getting all service providers users
var spusers = (from x in db.User1s where x.usertype == "200" select x);
ddl_spList.DataSource = spusers;
ddl_spList.DataTextField = "email";
ListView_AllTickets.DataBind();
}
.aspx
<asp:DropDownList ID="DropDownList_SpList" runat="server" class="form-control" ClientIDMode="AutoID"> </asp:DropDownList>
Notice how I am finding the control then binding it to the result of the LINQ query. When I use the debugger, the data is retrieved successfully and the "email" field exists in the returned data. However, and for some reason, the ListView_AllTickets will have an item count of 0 even after the DataBind() statment.
You'll need to add this line:
ddl_spList.DataBind();
You're rebinding ListView_AllTickets, but that's the parent object and is already being bound (hence the event you're handling with this method). Is that a typo?
Bind ddl_spList instead.
I have the following markup:
<td>
<asp:DropDownList runat="server" ID="ddlExtRouteBusyID" style="width: 320px;" />
</td>
And code behind that executes on page load:
//Bind the route busy drop down list:
DataTable dr = /*[some DataTable returned from a wrapper to an RDBMS*/;
this.ddlExtRouteBusyID.DataSource = dt;
this.ddlExtRouteBusyID.DataTextField = "description";
this.ddlExtRouteBusyID.DataValueField = "id";
this.ddlExtRouteBusyID.DataBind();
I cannot seem to access the description and ID data based upon the value of the SelectedItem/Value. For example if I select the second list item, the SelectedIndex is 1, but the description might be "server2" and the ID might be 1118. How can I pull the description and ID values?
Thanks.
You can use the following to get the text and the value:
ddlExtRouteBusyID.SelectedItem.Text
ddlExtReouteBusyID.SelectedItem.Value
If this doesn't work there may be some other problem with what the page is doing, since I just verified that these worked for me.
There are some things not cleared in question, so here are some of the Options I thought about..
1) If you want to access value and text client side you can use simple JQUERY as follows..
$("#ddlExtRouteBusyID.ClientID").change(function() {
selectval();
});
$("#ddlExtRouteBusyID.ClientID").click(function() {
selectval();
});
function selectval(){
alert('Text:' + $('#ddlExtRouteBusyID.ClientID :selected').text() + ', value = ' + $("#ddlExtRouteBusyID.ClientID").val());
}
2) Use the values on server side then HOW?, I mean onSelectedIndexChange or On Any ButtonClick event
Note : to use any way the dropdownlist databind method should be kept in if(!IsPostBack)
You need to add two properties to your DropDownList definition, OnSelectedIndexChanged and AutoPostBack, like this:
<asp:DropDownList runat="server" ID="ddlExtRouteBusyID" style="width: 320px;"
OnSelectedIndexChanged="Index_Changed" AutoPostBack="true" />
Now you need to write code in your code-behind to handle the SelectedIndexChanged event, like this:
protected void Index_Changed(Object sender, EventArgs e)
{
// Put logic here to grab values from drop down list
Label1.Text = "You selected " + ddlExtRouteBusyID.SelectedItem.Text +
" with a value of " + ddlExtRouteBusyID.SelectedItem.Value +
".";
}
Note: AutoPostBack=true is what causes the page to post back to the server when the drop down list value changes; otherwise the drop down list change event will not fire.
I have the following scenario:
My page has a dropdown list that allows user to choose a category.
For each category, there is a set of attributes, whose values should be fetched from the user. The number of attributes are different for each category.
Depending on the category the user chooses, a set of dropdown lists should be created corresponding to the attributes and filled with corresponding attribute values.
Since it is required that the page should not reload, I plan to fetch the data (from SQL Server 2008) using AJAX (?). I'm new to ASP.NET and have not used AJAX though I'm comfortable with C#. Need advice on how to proceed.
EDIT: Is this useful if I need to dynamically generate combo boxes?
You can use UpdatePanel or PageMethods
in both cases and in any case, I would say, you do need to know JavaScript when you want to use AJAX and make dynamic web applications. It take some time but it pays off don't worry.
you can search here in SO about PageMethod, for example see this one:
Regarding PageMethod in asp.net
You could use the following approach (if you do not feel comfortable building a more complex UI with javascript).
It works by dynamically creating the attribute DropDownLists when the page loads (you would implement it based on the result of a DB query) and hiding each one, ready for display later on.
Upon the selection of a category the correct DropDownLists would then be made visible (again a query here could determine which attribute DropDownLists become visible).
Obviously it will require some modifications to probably generate a Panel which contains each DropDownList and a Label control, instead of just creating a number of DropDownLists.
You would then show/hide the Panel instead of the DropDownList, but hopefully it points you in the right direction.
Hope this helps.
Markup
<style type="text/css">
select
{
display:block;
margin-top:10px;
}
</style>
....
<asp:ScriptManager ID="scriptManager" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<!-- Category selection -->
<asp:DropDownList ID="categoryDropDownList" runat="server" AutoPostBack="true" OnSelectedIndexChanged="categoryDropDownList_SelectedIndexChanged">
<asp:ListItem Text="Please select a category" Value="0"></asp:ListItem>
</asp:DropDownList>
<br />
<!-- Used to store the drop downs -->
<asp:Panel ID="dropDownContainer" runat="server"></asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Code
protected void Page_Load(object sender, EventArgs e)
{
LoadDropDownLists();
}
private void LoadDropDownLists()
{
//Dummy data, you would pull your categories/attributes from whichever datasource
//you are using
var categories = new[]{
new { Name = "Category 1", Id = 1, Attributes = new string[]{"GA", "FA", "RA"} },
new { Name = "Category 2", Id = 2, Attributes = new string[]{"GA", "NA"} }
};
//Loop through the categories, load the dropdown
foreach (var category in categories)
{
if (!IsPostBack)
categoryDropDownList.Items.Add(new ListItem(category.Name, category.Id.ToString()));
//For each attribute create a drop down and populate with data as required
foreach (var attribute in category.Attributes)
{
string dropDownListId = FormatDropDownListId(attribute);
if (!DropDownListExists(dropDownListId))
{
DropDownList dropDownList = new DropDownList();
dropDownList.ID = dropDownListId;
dropDownList.Visible = false;
dropDownList.Items.Add(new ListItem(attribute));
dropDownContainer.Controls.Add(dropDownList);
}
}
}
}
private bool DropDownListExists(string id)
{
DropDownList dropDownList = (DropDownList)dropDownContainer.FindControl(id);
return dropDownList != null;
}
protected void categoryDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
//Reset all visible dropdowns
HideAllDropDownLists();
//Get the selected category
string selectedItem = categoryDropDownList.SelectedItem.Value;
switch (selectedItem)
{
case "1":
{
//Here you would connect to db and pull correct attributes
//then set the visible dropdowns as required
SetDropDownVisibility(FormatDropDownListId("GA"));
SetDropDownVisibility(FormatDropDownListId("FA"));
SetDropDownVisibility(FormatDropDownListId("RA"));
} break;
case "2":
{
SetDropDownVisibility(FormatDropDownListId("GA"));
SetDropDownVisibility(FormatDropDownListId("NA"));
} break;
}
}
private void SetDropDownVisibility(string id)
{
DropDownList dropDownList = (DropDownList)dropDownContainer.FindControl(id);
if(dropDownList != null)
dropDownList.Visible = true;
}
private void HideAllDropDownLists()
{
foreach (Control control in dropDownContainer.Controls)
{
control.Visible = false;
}
}
private string FormatDropDownListId(string id)
{
return string.Format("dropDown{0}", id);
}
If you're using ASP.NET webforms then I don't believe you need to use AJAX or JavaScript.
I would do the following
Set autopostback = true on your combobox
Add an event handler for the OnChanged event of the combobox
Inside the event handler, apply rules at to load / generate / populate child comboboxes
Add those combo boxes to the form
You can either hide the comboboxes (as I see in #jdavies answer), or start without any and dynamically create & add them to the form.
This question deals with the same issue:
DropDownList and Update Panel
I have a GridView with a DataSource (SQL Database). I want to hide a column, but still be able to access the value when I select the record. Can someone show me how to do this?
This is the column I want to hide and still want to access its value:
<asp:BoundField DataField="Outlook_ID" HeaderText="OutlookID" />
I tried everything to hide the column (property Visible="false"), but I can't access its value.
<head runat="server">
<title>Accessing GridView Hidden Column value </title>
<style type="text/css">
.hiddencol
{
display: none;
}
</style>
<asp:BoundField HeaderText="Email ID" DataField="EmailId" ItemStyle-CssClass="hiddencol" HeaderStyle-CssClass="hiddencol" >
</asp:BoundField>
ArrayList EmailList = new ArrayList();
foreach (GridViewRow itemrow in gvEmployeeDetails.Rows)
{
EmailList.Add(itemrow.Cells[YourIndex].Text);
}
If I am not mistaken, GridView does not hold the values of BoundColumns that have the attribute visible="false". Two things you may do here, one (as explained in the answer from V4Vendetta) to use Datakeys. Or you can change your BoundColumn to a TemplateField. And in the ItemTemplate, add a control like Label, make its visibility false and give your value to that Label.
Define a style in css:
.hiddencol { display: none; }
Then add the ItemStyle-CssClass="hiddencol" and the HeaderStyle-CssClass="hiddencol" attribute to the grid field:
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-CssClass="hiddencol" HeaderStyle-CssClass="hiddencol" ClientIDMode="Static" />
You can use DataKeys for retrieving the value of such fields, because (as you said) when you set a normal BoundField as visible false you cannot get their value.
In the .aspx file set the GridView property
DataKeyNames = "Outlook_ID"
Now, in an event handler you can access the value of this key like so:
grid.DataKeys[rowIndex]["Outlook_ID"]
This will give you the id at the specified rowindex of the grid.
You can do it programmatically:
grid0.Columns[0].Visible = true;
grid0.DataSource = dt;
grid0.DataBind();
grid0.Columns[0].Visible = false;
In this way you set the column to visible before databinding, so the column is generated.
The you set the column to not visible, so it is not displayed.
If you do have a TemplateField inside the columns of your GridView and you have, say, a control named blah bound to it. Then place the outlook_id as a HiddenField there like this:
<asp:TemplateField HeaderText="OutlookID">
<ItemTemplate>
<asp:Label ID="blah" runat="server">Existing Control</asp:Label>
<asp:HiddenField ID="HiddenOutlookID" runat="server" Value='<%#Eval("Outlook_ID") %>'/>
</ItemTemplate>
</asp:TemplateField>
Now, grab the row in the event you want the outlook_id and then access the control.
For RowDataBound access it like:
string outlookid = ((HiddenField)e.Row.FindControl("HiddenOutlookID")).Value;
Do get back, if you have trouble accessing the clicked row. And don't forget to mention the event at which you would like to access that.
You can make the column hidden on the server side and for some reason this is different to doing it the aspx code. It can still be referenced as if it was visible. Just add this code to your OnDataBound event.
protected void gvSearchResults_DataBound(object sender, EventArgs e)
{
GridView gridView = (GridView)sender;
if (gridView.HeaderRow != null && gridView.HeaderRow.Cells.Count > 0)
{
gridView.HeaderRow.Cells[UserIdColumnIndex].Visible = false;
}
foreach (GridViewRow row in gvSearchResults.Rows)
{
row.Cells[UserIdColumnIndex].Visible = false;
}
}
Leave visible columns before filling the GridView. Fill the GridView and then hide the columns.
Here is how to get the value of a hidden column in a GridView that is set to Visible=False: add the data field in this case SpecialInstructions to the DataKeyNames property of the bound GridView , and access it this way.
txtSpcInst.Text = GridView2.DataKeys(GridView2.SelectedIndex).Values("SpecialInstructions")
That's it, it works every time very simple.
I have a new solution hide the column on client side using css or javascript or jquery.
.col0
{
display: none !important;
}
And in the aspx file where you add the column you should specify the CSS properties:
<asp:BoundField HeaderText="Address Key" DataField="Address_Id" ItemStyle-CssClass="col0" HeaderStyle-CssClass="col0" > </asp:BoundField>
I used a method similar to user496892:
SPBoundField hiddenField = new SPBoundField();
hiddenField.HeaderText = "Header";
hiddenField.DataField = "DataFieldName";
grid.Columns.Add(hiddenField);
grid.DataSource = myDataSource;
grid.DataBind();
hiddenField.Visible = false;
I found this solution, an elegant(IMO) quick 2 parter.
1.
On your gridview, add a column as normal, no need to do anything differently:
<asp:BoundField DataField="AccountHolderName" HeaderText="Account Holder"
ReadOnly="true"/>
You can keep the header text if this is useful to you for later processing.
2.
In the rowdatabound method for the grid hide the header, footer and row for that column index:
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[10].Visible = false;
}
if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.Cells[10].Visible = false;
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[10].Visible = false;
}
You can do it code behind.
Set visible= false for columns after data binding .
After that you can again do visibility "true" in row_selection function from grid view .It will work!!
I searched a lot but no luck. The most of them was working with some errors. Finally I used this code and it worked for me.
probably you should change 1 to some other value. for me I would hide second col.
protected void FoundedDrGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType!=DataControlRowType.Pager)e.Row.Cells[1].Visible = false;
}
I just set the width to 0. and it works.
columns.AddFor(m => m.Id).Name("hide-id").Width(0);
When I want access some value from GridView before GridView was appears.
I have a BoundField and bind DataField nomally.
In RowDataBound event, I do some process in that event.
Before GridView was appears I write this:
protected void GridviewLecturer_PreRender(object sender, EventArgs e)
{
GridviewLecturer.Columns[0].Visible = false;
}