tags:

views:

74

answers:

4

I have the following structure

<asp:UpdatePanel ID="MyUpdatePanel" runat="server">
    <ContentTemplate>
        <asp:MultiView ID="MyViews" runat="server">
            <asp:View ID="List" runat="server">
                <asp:Repeater runat="server" ID="Repeater1">
                    <ItemTemplate>
                        <asp:LinkButton ID="Button1" runat="server" Text="Button1" CommandName="View" />
                    </ItemTemplate>
                </asp:Repeater>
            </asp:View>
            <asp:View ID="Single" runat="server">
                <asp:LinkButton ID="Button2" runat="server" Text="Button2" />
            </asp:View>
        </asp:MultiView>
    </ContentTemplate>
</asp:UpdatePanel>

On the code behind I get the repeater ItemDataBound event, get the control using var button1 = e.Item.FindControl("Button1") as LinkButton; then I assign a CommandArgument with the ID of the current element.

This is being executed immediately after the CreateChildControls method.

Repeater1.ItemDataBound += (s, e) =>
{
    if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
    {
        var Button1 = e.Item.FindControl("Button1") as LinkButton;
        Button1.CommandArgument = item.ID.ToString();
    }
};

Repeater1.ItemCommand += (s, e) =>
{
    if (e.CommandName == "View")
    {
        var item = provider.Get(Convert.ToInt64(e.CommandArgument));
        BuildSingleView(item);
    }
};

This method just change the view...

public void BuildSingleView(var item)
{
    MyViews.ActiveViewIndex = 1;
    /* Edit
       I've tried to call here
       Initialize(), EnsureChildControls(), CreateChildControls()
       but it was a useless try. I also tried to catch exceptions,
       but none happened.
     */
}

The problem is that the view doesn't change. When I click the LinkButton it executes the CreateChildControls and after it calls the event ItemCommand, the event calls the BuildSingleView, the ActiveViewIndex is changed but nothing happens on the page.

I don't understand why it doesn't change. Is it a problem with the order of events? What could I do to change the view when I click a LinkButton?


Here is the full code-behind code (the Initialize method is the method that executes immediately after CreateChildControls) http://pastebin.com/2qwrKNxf

And here the full ascx file http://pastebin.com/P8RSbY9U

A: 

How about using MultiView.SwitchViewByIndexCommandName value as CommandName to button?

Another way would be to set hidden field on page on button click and then checking value of hidden field to switch the active view.

VinayC
That is interesting, but doesn't seem to solve my problem...
BrunoLM
A: 

You just need to do the below:

Repeater1.ItemDataBound += (s, e) =>
{
    if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
    {
        var Button1 = e.Item.FindControl("Button1") as LinkButton;
        Button1.CommandArgument = item.ID.ToString();
    }
};

before Repeater1.DataBind();

That will solve the problem, because ItemDataBound event will fired right after you call DataBind() method. If you add new handler to ItemDataBound event after Binding the Repeater, it will never be fired.

I mean,

Repeater1.DataSource = List;
Repeater1.DataBind();

Repeater1.ItemDataBound += (s, e) =>
{
    if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
    {
        var item = e.Item.DataItem as Person;
        var Button1 = e.Item.FindControl("Button1") as LinkButton;
    }
};

will not work, but:

Repeater1.ItemDataBound += (s, e) =>
{
    if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
    {
        var item = e.Item.DataItem as Person;
        var Button1 = e.Item.FindControl("Button1") as LinkButton;
    }
};

Repeater1.DataSource = List;
Repeater1.DataBind();

will work.

Musa Hafalır
The DataBind is already the last thing I call. I've added the full source.
BrunoLM
Sorry, I thought it was the problem because I just tried myself and solved that way, I will check the sources that you have added.
Musa Hafalır
A: 

Just a thought... But why not just assign the ID as an Eval/Bind? (It's the same in VB.net asn C#... right? Below is how I would do it in VB)

<asp:LinkButton ID="Button1" runat="server" Text="Button1" CommandName="View" CommandArgument='<%# Eval("WhateverYourIDFieldIs")' />
Patricker
A: 

I figured out that when the update panel posts back it doesn't call the event handler first. So in order to get it to execute I need to re-assign the event.

My problem was that the control wasn't saving the ViewState, so it kept creating the wrong events. I replaced the ViewState with a Session and I got the behavior I wanted.

BrunoLM