如何让UpdatePanel拦截CompositeControl的DropDownList

时间:2008-10-22 13:11:23

标签: asp.net asp.net-ajax

我有一个包含DropDownList的CompositeControl。

我已将DropDownList的AutoPostBack属性设置为true。

在页面上,我有:

<asp:UpdatePanel ID="UpdatePanel" runat="server">
    <ContentTemplate>
        <MyControl:Control ID="CustomControl" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

我也尝试过设置 ChildrenAsTriggers =“true” UpdateMode =“Always,”,但都没有解决问题。

问题是UpdatePanel没有拦截CompositeControl的DropDownList的回发。 (更改DropDownList时正在执行完整的POST)

如何让UpdatePanel处理回发?

谢谢!

修改 - 请求的信息

Country和States都是CompositeControl中的DropDownLists。

country.SelectedIndexChanged += new EventHandler(country_SelectedIndexChanged);

protected void country_SelectedIndexChanged(Object sender, EventArgs e)
{
    states.DataSource = XXX;
    states.DataBind();
}

4 个答案:

答案 0 :(得分:3)

好的,所以这可能不是最好的答案,但我认为你遇到的问题是UpdatePanel无法看到子控件的事件。好消息是,它很容易修复。假设您有一个控件(CatchMyEvent,顺便说一下,它是一个疯狂的聪明名字)并且它上面有一个DropDownList。现在,您希望父页面在该列表上查看SelectedIndexChanged事件,并更新标签以匹配SelectedItem.Text。事实上,父母不能真的这样做。所以让我们改变一下:

public partial class CatchMyEvent : System.Web.UI.UserControl
{
    public delegate void ChangedIndex(object sender, EventArgs e);
    public event ChangedIndex SelectedIndexChanged;

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        dropDownListThrow.SelectedIndexChanged += new EventHandler(dropDownListThrow_SelectedIndexChanged);
        labelOutput.Text = "no";
    }

    public void dropDownListThrow_SelectedIndexChanged(object sender, EventArgs e)
    {
        labelOutput.Text = ((DropDownList)sender).SelectedItem.Text;
        if(SelectedIndexChanged != null)
        {
            SelectedIndexChanged(sender, e);
        }
    }
}

基本上我所做的就是让控件捕获DropDownList的SelectedIndexChanged事件并触发它,以便任何父页面或控件都可以看到它。基本上我所做的就是传递它。现在在父页面上,它非常容易捕获。

您只需添加一个带有触发器的UpdatePanel:

<asp:AsyncPostBackTrigger ControlID="catchMyEventMain" EventName="SelectedIndexChanged" />

...当然,将其添加到父页面后面的代码中:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    catchMyEventMain.SelectedIndexChanged += dropDownListThrow_SelectedIndexChanged;
}

public void dropDownListThrow_SelectedIndexChanged(object sender, EventArgs e)
{        
    labelSelectedValue.Text = ((DropDownList)sender).SelectedItem.Text;
}

标签是前面提到的标签。然后让魔法发生。

还有两个注意事项:

1)不要像我在测试时那样白痴,忘记将DropDownList上的AutoPostBack属性设置为true。

2)确保标签位于UpdatePanel的ContentTemplate中。

希望这有帮助。

答案 1 :(得分:2)

我在UpdatePanel内的ListView中重复了子控件(文本框和标签)。

更改文本框会导致完整(同步)回发。

我添加了PAGE元素(.aspx页面的第一行):ClientIDMode =“AutoID”

这解决了我的问题,现在只根据需要刷新UpdatePanel。

答案 2 :(得分:0)

我在BuildControlHierarchy的末尾做了以下内容:

        ...
        if (DesignMode || Page == null) return;

        var sm = ScriptManager.GetCurrent(Page);
        if (sm == null)
        {
            throw new MissingFieldException("The ScriptManager is needed on the page!");
        }
        sm.RegisterAsyncPostBackControl(<control which initiates async postback>);

答案 3 :(得分:0)

只需确保整个层次结构中的每个控件都设置了ID。

请参阅this question