【发布时间】:2012-05-17 13:53:24
【问题描述】:
我有一个包含以下 3 个主要区域的 ASP.NET 页面:
1 - 左侧用于过滤结果的复选框列表
2 - 在中间显示匹配结果的中继器(每个项目都有一个按钮)
3 - 在右侧显示所选项目的中继器
在初始页面加载时,页面将显示数据绑定复选框并显示所有结果(因为没有在过滤器中检查任何内容)。当用户选中或取消选中复选框时,页面将重新加载并且匹配结果将发生变化。到目前为止,这部分效果很好。
在结果重复器中,每个项目都有一个按钮。当用户单击结果中某个项目的按钮时,想法是该项目将被添加到右侧的 Selected Repeater 中。发生的情况是,在我选中或取消选中过滤器复选框后 - 第一次 次我尝试单击结果中继器中的按钮,但没有任何反应。页面只是重新加载。然后,如果我再次单击该按钮,Repeater 命令将触发,并且该项目将被添加到右侧的 Repeater。然后,只要我不更改任何复选框,我就可以单击其中一个命令按钮,它会立即工作。但是,如果我选中过滤器区域中的一个复选框(这会导致结果重新绑定),那么我必须单击其中一个按钮两次才能触发它。
我感觉这与 ViewState 有关,但我不知道。有谁知道为什么会这样?
下面是我的 ASPX 页面代码和后面的代码。
ASPX 代码:
<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>
下面是代码:
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();
}
}
【问题讨论】:
-
您是否 100% 确定您的
rptMatchingSlides_Command第一次不会触发,但在您第二次单击结果中继器中的按钮时会触发?换句话说,你在那里设置了断点吗? -
是的。我已将其放入调试中,第一次单击该按钮时,我看到页面加载触发,但没有触发 rptMatchingSlides_Command。然后当我第二次单击该按钮时,它会触发。
-
有趣...想知道它是否会丢失其事件信息。试试这个,删除
_btnSelect.ID =代码,看看是否有帮助......仅供参考,这不是必需的,因为按钮将自动唯一命名。