I have a checkbox list that I want to populate and perhaps I could use the page_load and do the job from there, right?
protected void Page_Load(object sender, EventArgs e)
{
//...
var query = logic.GetPlanCoverages(planName);
cbl_MemberCoverages.DataSource = coverages;
cbl_MemberCoverages.DataBind();
}
But because Asp.Net has introduced Model Binding, now I can have this:
<asp:CheckBoxList runat="server" ID="cbl_MemberCoverages"
SelectMethod="BindMemberCoverages" DataTextField="CoverageName" DataValueField="CoverageCode">
</asp:CheckBoxList>
And in the code-behind:
public IEnumerable<PlanCoveragesDomainModel> BindMemberCoverages()
{
var planName = logic.GetShortPlanName();
var query = logic.GetPlanCoverages(planName);
return query;
}
BUT... There is something I still don't like in Model Binding, or perhaps it's just me that cannot work out how to use it properly when you have to prepopulate a form.
A typical scenario is when from a list of users, I want to edit one. I open a new page and I have this form with lots of fields to populate. Perhaps one of the users has already assigned some of these coverages. But at the moment, the only workaround I found is:
public IEnumerable<PlanCoveragesDomainModel> BindMemberCoverages([QueryString]string mode)
{
if (!"edit".Equals(mode, StringComparison.InvariantCultureIgnoreCase))
{
var planName = logic.GetShortPlanName();
var query = logic.GetPlanCoverages(planName);
return query;
}
var coverages = logic.GetPlanCoverages(CurrentModel.PlanName).Select(c => new ListItem(c.CoverageName, c.CoverageCode)).ToArray();
cbl_MemberCoverages.Items.AddRange(coverages);
cbl_MemberCoverages.DataSource = coverages;
cbl_MemberCoverages.DataBind();
foreach (ListItem listItem in cbl_MemberCoverages.Items)
{
listItem.Selected = CurrentModel.Coverages.Any(c => c.Value == listItem.Value);
}
return null;
}
Guys, any ideas?
Implement OnDataBound event for your CheckBoxList control.
<asp:CheckBoxList runat="server" ID="cbl_MemberCoverages"
SelectMethod="BindMemberCoverages" DataTextField="CoverageName"
DataValueField="CoverageCode"
OnDataBound="cblMemberCoverages_DataBound">
</asp:CheckBoxList>
Code
protected void cblMemberCoverages_DataBound(object sender, EventArgs e)
{
var chkBoxList = sender as CheckBoxList;
var item = chkbox.Items.FindByValue(queryStringCoverageCode);
if(item != null)
item.Selected = true;
}
Related
i have a datalist contains checkboxlist.
<asp:DataList ID="dtlstfilter" runat="server">
<ItemTemplate>
<asp:CheckBoxList ForeColor="Gray" AutoPostBack="true" OnSelectedIndexChanged="chklist_SelectedIndexChanged" ID="chklist"
runat="server">
</asp:CheckBoxList>
</ItemTemplate>
</asp:DataList>
when i check one from the checkbox list in the SelectedIndexChanged event i got the selected value using
CheckBoxList c = (CheckBoxList)sender;
string selectedvalue= c.SelectedValue;
likewise how can get the value from a checkboxlist if i uncheck one from the checkboxlist
The SelectedIndexChanged gets also fired if you uncheck a CheckBox. So it works the same way. But if you want to know the (now) unchecked item(s), you have to store the old selection somewhere, for example in the ViewState:
private IEnumerable<string> SelectedValues
{
get
{
if (ViewState["SelectedValues"] == null && dtlstfilter.SelectedIndex >= -1)
{
ViewState["SelectedValues"] = dtlstfilter.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.ToList();
}else
ViewState["SelectedValues"] = Enumerable.Empty<string>();
return (IEnumerable<string>)ViewState["SelectedValues"];
}
set { ViewState["SelectedValues"] = value; }
}
protected void chklist_SelectedIndexChanged(Object sender, EventArgs e)
{
CheckBoxList c = (CheckBoxList)sender;
var oldSelection = this.SelectedValues;
var newSelection = c.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value);
var uncheckedItems = newSelection.Except(oldSelection);
}
This should even work if multiple checkboxes can be selected.
You can take the jQuery Route if it suits you...
if (!IsPostBack)
{
foreach (ListItem item in chkList.Items)
{
//adding a dummy class to use at client side.
item.Attributes.Add("class", "chkItem");
}
}
Put one button on your form with style display : none. And a Hidden Field to track the currently checked checkbox.
<asp:Button ID="hdnButton" runat="server" style="display:none;" OnClick="hdnButton_Click"/>
<asp:HiddenField ID="hdnCurrent" runat="server" />
The jQuery Part....
$(".chkItem input:checkbox").change(function(){
$("#hdnCurrent").val($(this).attr("id") + "|" + $(this).attr("checked"));
$("#hdnButton").click();
});
You can use more hidden fields if you don't want to do string operations on backend. Depends on your taste.
Then handle the button click event like below.
protected void hdnButton_Click(object sender, EventArgs e)
{
String[] Value = hdnCurrent.Value.Split('|');
if (Value[1] == "true")
{
//Do operations here when the check box is checked
}
else
{
//Do operations here when the check box is unchecked
}
//Value[0] contains the id of the check box that is checked/unchecked.
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Display DB values in a dropdownlist
I am fetching DB values and displaying them in the Dropdown list. I have country and state drop down lists:
DropDownList1.Items.Add(new ListItem(Session["country"].ToString()));
DropDownList2.Items.Add(new ListItem(Session["state"].ToString()));
I am unable to show the DB values in the DDL. I am getting --select a state--
in the state Dropdown list how to show the DB values in the Dropdown list?
<asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="True">
<asp:ListItem Value="Select a state" >Select a state</asp:ListItem>
<asp:ListItem Value="value 1" >Maharastra</asp:ListItem>
<asp:ListItem Value="value 2" >Goa</asp:ListItem>
<asp:ListItem Value="value 3" >Kashmir</asp:ListItem>
</asp:DropDownList>
i am cacthing the DB values here and sending them to the next page
if (dt.Rows.Count > 0)
{
DataTable dt1 = new DataTable();
dt1 = bll.getnewid(TextBox1.Text);
if (dt1.Rows.Count > 0)
{
Session["country"] = dt1.Rows[0]["Country"].ToString();
Session["state"] = dt1.Rows[0]["State"].ToString();
Well, you must somehow bind your ddlist to the db results. Looks like this:
ddlist1.DataSource = MyDBAccessClass.GetSomeValues();
ddlist1.DataBind();
Based on more comments... I'll have to play a little roulette and guess what's your intentions. Your code has multiple problems and you've obviously some issues explaining yourself.
If I understood you correctly, you have 2 dropdownlists. You want to populate one with countries and based on the selection, populate the second dropdownlist.
The basic principle looks like this:
DataAccessClass.cs
public class DataAccessClass
{
public static IEnumerable<string> GetCountries()
{
// access the database and retrieve all the values
// returns IEnumerable (a list of items)
}
public static IEnumerable<string> GetStates(string selectedCountry)
{
// access the database and retrieve all the corresponding states
// linq2sql: var states = from o in db.States
// where o.country = selectedCountry
// select o;
// returns IEnumerable (a list of items)
}
}
YourPage.aspx
<asp:DropDownList id="ddlistCountries" runat="server" AutoPostBack="True" /><br />
<asp:DropDownList id="ddlistStates" runat="server" />
YourPage.aspx.cs
public partial class YourPage
{
protected void Page_Init(object sender, EventArgs e)
{
ddlistCountries.SelectedIndexChanged += new EventHandler(ddlist_SelectedIndexChanged);
}
protected void Page_Load(object sender, EventArgs e)
{
if (!isPostBack)
{
PopulateCountries();
ddlistStates.Enabled = false; // no country selected yet!
}
}
protected void PopulateCountries()
{
ddlistCountries = DataAccessClass.GetCountries();
ddlistCountries.DataBind();
ddlist.Items.Insert(0, "Select a country");
}
void ddlist_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlistCountries.SelectedIndex != 0)
{
ddlistStates.DataSource = DataAccessClass.GetStates(ddlistCountries.SelectedValue);
ddlistStates.DataBind();
ddlistStates.Enabled = true;
}
else
{
ddlistStates.Items.Clear();
ddlistStates.Enabled = false;
}
}
}
If you can't understand this, either go back to basics or forget about programming altogether.
DropDownList2.DataSource = {your data source};
DropDownList2.DataTextField = "text column name";
DropDownList2.DataValueField = "data column name of id";
DropDownList2.DataBind();
You need to set your data source to the DDL, then set which values to display, then bind it.
I would suggest to use the dropdownlist like this :
ddl.DataSource = YourDBSource.Get();
ddl.DataBind();
you can then decide what to be displayed here with :
ddl.DataTextField = ...;
or
ddl.DataValueField = ...;
First of all, there is no reason to build your listItem in the .aspx page because you will populate your ddl programmatically.
Secondly I don't know what you mean by 'i am cacthing the DB values here and sending them to the next page'. Just fill the dataSource with the appropriate query on you DB.
If you want to perform more easy filtering / wahtever you want, try to use Linq2SQL.
Additionally, you need to perform this databinding in the *Page_Load()* like this :
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ddlErreur.DataSource = ...;
ddlErreur.DataTextField = ...;
ddlErreur.DataBind();
}
}
I have 2 list boxes.
<asp:ListBox ID="ListBox_Region" runat="server"
DataTextField="arregion" DataValueField="arregion" AutoPostBack="True"
Height="96px"
Width="147px" DataSourceid="sqldatasource1"></asp:ListBox>
<asp:ListBox ID="ListBox_Area" runat="server"
DataTextField="ardescript" DataValueField="ardescript"
AutoPostBack="True"
OnSelectedIndexChanged="ListBox_Area_SelectedIndexChanged"
Height="96px"
Width="147px" >
So, when I select a value from ListBox_Region , the corresponding values get updated in ListBox_Area in this way:
protected void ListBox_Region_SelectedIndexChanged(object sender, EventArgs e)
{
this.ListBox_Area.Items.Clear();
string selectedRegion = ListBox_Region.SelectedValue;
var query = (from s in DBContext.areas
where s.arregion == selectedRegion
select s);
ListBox_Area.DataSource = query;
ListBox_Area.DataBind();
}
The event for ListBoxRegion_SelectedIndexChaged is written in page Load.
However, the problem is on initial page load, where the first value of ListBox_Region should be Selected by default. The second listbox should be updated to corresponding values but this should happen before selected index changed gets fired. So, can u please let me know how to do this?
Move the logic on ListBox_Region_SelectedIndexChanged to a separated method and call it from page_load when postback is false.
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
// Bind ListBox_Region and set the first value as selected
...
//
BindAreaList();
}
}
protected void ListBox_Region_SelectedIndexChanged(object sender, EventArgs e)
{
BindAreaList();
}
protected void BindAreaList()
{
this.ListBox_Area.Items.Clear();
string selectedRegion = ListBox_Region.SelectedValue;
var query = (from s in DBContext.areas
where s.arregion == selectedRegion
select s);
ListBox_Area.DataSource = query;
ListBox_Area.DataBind();
}
I have to set a LinkButton's OnClientClick attribute but I don't know what this value is until the LinkButton is bound to. I'm trying to set the value when the repeater binds, but I can't workout how to get the 'boundItem/dataContext' value...
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:LinkButton Text="HelloWorld" ID="Hyper1" runat="server" OnDataBinding="Repeater1_DataBinding" >
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
var list = new List<TestObject>();
list.Add(new TestObject() {TestValue = "testing1"});
list.Add(new TestObject() { TestValue = "testing2" });
list.Add(new TestObject() { TestValue = "testing3" });
this.Repeater1.DataSource = list;
this.Repeater1.DataBind();
}
public void Repeater1_DataBinding(object sender, EventArgs e)
{
var link = sender as HyperLink;
//link.DataItem ???
}
Is there anyway to find out what the current rows bound item is?
Maybe you need to use ItemDataBound event. It provides RepeaterItemEventArgs argument which has DataItem available
this.Repeater1.ItemDataBound += Repeater1_ItemDataBound;
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var dataItem = e.Item.DataItem;
}
I assume you are trying to get the value for the row that is currently being databound?
You can change your function to:
public void Repeater1_DataBinding(object sender, EventArgs e)
{
var link = sender as HyperLink;
string valueYouWant = Eval("TestValue").ToString();
// You could then assign the HyperLink control to whatever you need
link.Target = string.Format("yourpage.aspx?id={0}", valueYouWant);
}
valueYouWant now has the value of the field TestValue for the current row that is being databound. Using the DataBinding event is the best way to do this compared to the ItemDataBound because you don't have to search for a control and localize the code specifically to a control instead of a whole template.
The MSDN library had this as a sample event handler:
public void BindData(object sender, EventArgs e)
{
Literal l = (Literal) sender;
DataGridItem container = (DataGridItem) l.NamingContainer;
l.Text = ((DataRowView) container.DataItem)[column].ToString();
}
(see http://msdn.microsoft.com/en-us/library/system.web.ui.control.databinding.aspx)
As you can see it is a simple demonstration of how to access the data item and get data from it. Adapting this to your scenario is an exercise left to the reader. :)
I have a repeater control with a check box, if I check the box then my delete functionality will delete an item in the underlying table.
When I test the delete functionality on an aspx page with a code behind page, everything works fine. Hooray!
However, when I take the repeater and put it into a User Control, the delete functionality thinks that my repeater control has no items.
Code as below, I've tried to strip out the unnecessary code. I asked this question on the asp.net forums but no-one responded!
asxc:
<%# Control AutoEventWireup="true" Inherits="Moto.Web.UI.UserControls.Messages.MessageListForm" Language="C#" %>
<asp:button id="btnDelete" runat="server" text="Delete" OnClick="btnDelete_Click" ></asp:button>
<asp:Repeater ID="RepeaterMessageList" runat="server" EnableViewState="true" >
<ItemTemplate >
<div class="messageContainer item" >
<div class="messageListLeft">
<div class="messageList">
<asp:Image ID="imgUser" runat="server" CssClass="" />
<asp:CheckBox ID="chkDeleteMe" runat="server" Text="test" />
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
Code file:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Collections.Generic;
using System.IO;
namespace Moto.Web.UI.UserControls.Messages
{
public class MessageListForm : Moto.Web.UI.UserControls.UserControl//System.Web.UI.UserControl
{
private string userGUID;
private MembershipUser MembershipUser;
private Moto.Business.UserComponent userComponent;
private Moto.Business.User user;
private Button cmdPrev;
private Button cmdNext;
private Button cmdNewest;
private Button cmdOldest;
private Label lblCurrentPage;
private Label lblMessage;
private HyperLink hypPageRedirect;
private Repeater RepeaterMessageList;
private MessageView DisplayMessages = MessageView.Inbox;//default setting
private Button btnDelete;
private Label lblConfirmDelete;
protected Button btnConfirmDelete;
protected Button btnCancelDelete;
enum MessageView
{
Inbox, //0
Sent //1
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.InitializePage();
}
protected void InitializePage()
{
this.cmdNext = (Button)FindControl("cmdNext");
this.cmdPrev = (Button)FindControl("cmdPrev");
this.cmdOldest = (Button)FindControl("cmdOldest");
this.cmdNewest = (Button)FindControl("cmdNewest");
this.lblCurrentPage = (Label)FindControl("lblCurrentPage");
// this.RepeaterMessageList = (Repeater)FindControl("RepeaterMessageList");
this.RepeaterMessageList = (Repeater)FindControlRecursive(this, "RepeaterMessageList");
this.hypPageRedirect = (HyperLink)FindControl("hypPageRedirect");
this.lblMessage = (Label)FindControl("lblMessage");
//delete functionality
this.btnDelete = (Button)FindControl("btnDelete");
this.lblConfirmDelete = (Label)FindControl("lblConfirmDelete");
this.btnConfirmDelete = (Button)FindControl("btnConfirmDelete");
this.btnCancelDelete = (Button)FindControl("btnCancelDelete");
//where are we coming from - are we the Logged in user or just a voyeur?
if (Page.User.Identity.IsAuthenticated)
{
this.userComponent = new Moto.Business.UserComponent();
this.MembershipUser = Membership.GetUser();//user logged in
this.userGUID = this.MembershipUser.ProviderUserKey.ToString();//signed in user
this.user = this.userComponent.GetByUserGUID(this.userGUID);
}
else
{
Response.Redirect("~/default.aspx");
}
if (null != this.Page.Request.QueryString["viewing"])
{
//reset the enum value
DisplayMessages = this.Page.Request.QueryString["viewing"].ToLower() == "sent" ? MessageView.Sent : MessageView.Inbox;
CurrentPage = 0;//if it's a redirect then reset the Current Page
}
}
void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ItemsGet();//on post back we'll call it elsewhere
}
switch (DisplayMessages)
{
case MessageView.Sent:
this.hypPageRedirect.Text += "Inbox";
this.hypPageRedirect.NavigateUrl += "?viewing=Inbox";
break;
case MessageView.Inbox:
this.hypPageRedirect.Text += "Sent Items";
this.hypPageRedirect.NavigateUrl += "?viewing=Sent";
break;
}
}
protected void cmdPrev_Click(object sender, EventArgs e)
{
// Set viewstate variable to the previous page
CurrentPage -= 1;
// Reload control
ItemsGet();
}
protected void cmdNext_Click(object sender, EventArgs e)
{
// Set viewstate variable to the next page
CurrentPage += 1;
// Reload control
ItemsGet();
}
protected void cmdNewest_Click(object sender, EventArgs e)
{
// Set viewstate variable to the previous page
CurrentPage = 0;
// Reload control
ItemsGet();
}
protected void cmdOldest_Click(object sender, EventArgs e)
{
}
public void RepeaterMessageList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//Are we vieing the Inbox or Sent items?
if (DisplayMessages == MessageView.Inbox)
{
.........Do stuff
}
else
{
.........Do stuff
}
}
}
private void ItemsGet()
{
// this.RepeaterMessageList = (Repeater)FindControl("RepeaterMessageList");
this.RepeaterMessageList.ItemDataBound += new RepeaterItemEventHandler(RepeaterMessageList_ItemDataBound);
// Populate the repeater control with the Items DataSet
PagedDataSource objPds = new PagedDataSource();
if (DisplayMessages == MessageView.Inbox)//which table are we getting data from?
{
List<Moto.Business.MessageReceived> messages;
Moto.Business.MessageReceivedComponent messageComponent =
new Moto.Business.MessageReceivedComponent();
messages = messageComponent.GetByReceiverGUID(this.user.UserGUID);
objPds.DataSource = messages;
}
else
{
List<Moto.Business.MessageSent> messages;
Moto.Business.MessageSentComponent messageComponent =
new Moto.Business.MessageSentComponent();
messages = messageComponent.GetBySenderGUID(this.user.UserGUID);
objPds.DataSource = messages; //Items.Tables[0].DefaultView;
}
// Indicate that the data should be paged
objPds.AllowPaging = true;
// Set the number of items you wish to display per page
objPds.PageSize = 25;
// Set the PagedDataSource's current page
objPds.CurrentPageIndex = CurrentPage;
this.lblCurrentPage.Text = "Page " + (CurrentPage + 1).ToString() + " of "
+ objPds.PageCount.ToString();
// Disable Prev or Next buttons if necessary
this.cmdPrev.Enabled = !objPds.IsFirstPage;
this.cmdNext.Enabled = !objPds.IsLastPage;
this.cmdOldest.Enabled = !objPds.IsLastPage;
this.cmdNewest.Enabled = !objPds.IsFirstPage;
this.RepeaterMessageList.DataSource = objPds;
this.RepeaterMessageList.DataBind();
}
public int CurrentPage
{
get
{
// look for current page in ViewState
object o = this.ViewState["_messagesCurrentPage"];
if (o == null)
return 0; // default page index of 0
else
return (int)o;
}
set
{
this.ViewState["_messagesCurrentPage"] = value;
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
foreach (RepeaterItem item in this.RepeaterMessageList.Items)
{
CheckBox chkDeleteMe = item.FindControl("chkDeleteMe") as CheckBox;
TextBox test = item.FindControl("test") as TextBox;
if (chkDeleteMe.Checked)
{
if (DisplayMessages == MessageView.Inbox)//which table are we getting data from?
{
.........Do stuff
}
else
{
.........Do stuff
}
}
}
// Reload control
ItemsGet();
}
protected Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
}
Any help greatly appreciated!
I think the problem is that when the delete button is clicked the Page_Load is fired again and since its a postback it does not execute the ItemsGet method and hence the repeater does not have the data.
Try putting the ItemsGet method call in the OnPreRender event instead of Page_Load.
Jomit
The Delete event fires but in the fornext...loop the repeater thinks it has no items.
After looping it then calls the ItemsGet() Method which returns all data from the table.
So it binds to the repeater and displays all the items correctly but when repeating through the list of items on postback nothing is found?
Is the delete event definately being fired? What is visible after you have hit the delete button? (e.g. is the table empty or does it still display all the items)
Update:
Comment out the GetItems method and see if the table is empty or not on postback. It sounds like your repeaters viewstate isn't populating the control again or something.
Try to move the InitializePage() method to another place. I donĀ“t know why, but I had the same problem and the problem was when I try to access some controls in the OnInit event. I moved to event OnPreLoad() and works.
I hope to help you...
The PreRender solution also worked in our case, where we had such code in two pages of our application. This was working perfect in .Net 1.1 but however broke when we ported this code to .Net 2.0.
Not sure why it broke without any major changes to codebase.
Thanks for the OnPreRender tip!
-Ghanshyam