Reputation: 7340
I have an ASP.NET page with the following 3 main areas:
1 - list of checkboxes on the left for fitlering results
2 - Repeater that displays the matching results in the middle (with a button for each item)
3 - Repeater that displays the selected items on the right
On initial page load the page will show the data bound checkboxes and will show all results (since nothing has been checked in the filters). As the user checks or unchecks the checkboxes, the page will reload and the matching results will change. So far this part works great.
In the Results Repeater, each item has a Button. When the user clicks the button for an item in the Results the idea is that the item will get added to the Selected Repeater on the right. What is happening is that after I check or uncheck filter checkboxes - the first time that I then try and click on the buttons in the Results repeater, nothing happens. The page just reloads. Then if I click the button a second time, the Repeater Command will fire and the item will get added to the Repeater on the right hand side. Then, as long as I don't change any of the checkboxes I can click on one of the command buttons and it will work right away. But if I check one of the checkboxes in the filters area (which causes the Results to get re-bound) then I have to click one of the buttons twice to get it to fire.
I have a sense that this has something to do with ViewState but I have no idea. Does anyone know why this would be happening?
Below is my code for both the ASPX page and the code behind.
ASPX Code:
<h3>Filters</h3>
<asp:Repeater ID="rptTechnologies" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Technology</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptVerticals" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Vertical</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptIndustries" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Industry</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptSolutions" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Solution</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<h3>Results</h3>
<asp:Repeater ID="rptMatchingSlides" runat="server" OnItemDataBound="rptMatchingSlides_ItemDataBound" OnItemCommand="rptMatchingSlides_Command">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
<asp:Button ID="btnSelect" runat="server" Text="Select" CommandName="Select" />
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<h3>Selected</h3>
<asp:Repeater ID="rptSelectedSlides" runat="server" OnItemDataBound="rptSelectedSlides_ItemDataBound">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
Here is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.BindData();
}
}
public List<string> SelectedSlides
{
get
{
if (Session["SelectedIDs"] != null)
{
string[] _ids = Session["SelectedIDs"].ToString().Split(new char[] { '|' });
List<String> _retVal = new List<string>();
foreach (string _id in _ids)
{
_retVal.Add(_id);
}
return _retVal;
}
else
{
return new List<string>();
}
}
set
{
//Set the session value
string _val = "";
foreach (string _id in value)
{
if (_val == "")
{
_val = _id;
}
else
{
_val += "|" + _id;
}
}
Session["SelectedIDs"] = _val;
}
}
protected void BindData()
{
//Filters
rptTechnologies.DataSource = Repository.GetTaxonomyItems();
rptTechnologies.DataBind();
rptVerticals.DataSource = Repository.GetTaxonomyItems();
rptVerticals.DataBind();
rptIndustries.DataSource = Repository.GetTaxonomyItems();
rptIndustries.DataBind();
rptSolutions.DataSource = Repository.GetTaxonomyItems();
rptSolutions.DataBind();
this.BindMatchingSlides();
}
protected void BindMatchingSlides()
{
...build list of ids from checkboxes...
rptMatchingSlides.DataSource = Repository.GetMatchingSlides(_selectedIDs);
rptMatchingSlides.DataBind();
}
protected void BindSelectedSlides()
{
if (this.SelectedSlides.Count > 0)
{
rptSelectedSlides.DataSource = this.SelectedSlides;
rptSelectedSlides.DataBind();
}
else
{
divSelectedSlides.Visible = false;
}
}
protected void rptMatchingSlides_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Literal _litName = (Literal)e.Item.FindControl("litName");
Button _btnSelect = (Button)e.Item.FindControl("btnSelect");
_litName.Text = ...set name here...
_btnSelect.CommandArgument = ...use unique ID of item from database...
_btnSelect.ID = "btnSelect_" + e.Item.ItemIndex;
}
}
protected void rptMatchingSlides_Command(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Select")
{
Item _slide = ...get data from database based on Command Argument...
if (_slide != null)
{
List<string> _selectedSlides = this.SelectedSlides;
_selectedSlides.Add(_slide.ID.ToString());
this.SelectedSlides = _selectedSlides;
}
this.BindSelectedSlides();
}
}
Upvotes: 1
Views: 1382
Reputation: 7340
Thanks to Jeremy - removing the line of code where I was setting the ID fixed it. Doh! Somewhere else I had read that you needed to set a unique value for the IDs of the buttons in a repeater. So that must have been the culprit. Thanks to Jeremy.
Upvotes: 1