1

我有一个 ASP.NET 页面,其中包含以下 3 个主要区域:

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();
        }
    }
4

1 回答 1

1

感谢 Jeremy - 删除我设置 ID 的代码行修复了它。嗬!在其他地方我读到您需要为中继器中按钮的 ID 设置唯一值。所以这一定是罪魁祸首。感谢杰里米。

于 2012-05-17T14:11:13.697 回答