Repeater Containing Custom Control Doesn't Work With Page ViewState On Unless I Don't ReBind...

I have create a custom composite drop down list control that does not save view state for all properties.  There is a requirement that this contol work in a Repeater.  I have tested the contol in a repeater in various ways.  This is my first post ever, so I apologive if I have provided too little, too much or the wron info.

Note: The Repeater was always created in the aspx file. 

1) Page.EnableViewState = true , and my control added to the repeater programmatically via the ItemDataBound event.

2) Page.EnableViewState = false, and my control added to the repeater in the aspx file.

3) Page.EnableViewState = false, and my control added to the repeater programmatically via the ItemDataBound event.

4) Page.EnableViewState = true ,  and my control added to the repeater in the aspx file.

#4 is not working well.  The only way I can get this to work is if I do not rebind the repeater on postback AND all of the properties of my custom control are persisted via viewstate or controlstate.  This prevents the user from choosing to override  some properties on postback and clogs up the viewstate.  Is providing all of the properties of the child controls via viewstate (or control state)  a requirement of a repeater or is something wrong with my code?

Note: All four cases work if the contol is placed in directly in the page.  I only have problems in the Repeater.

If I try to rebind my Repeater under the condition of #4, then weird things happen:

1) LoadPostData fires 4 times for a two line repeater.  All four firings occur during the 1st ProcessPostData event. 

2) My RaisePostDataChangedEvent never fires.

3) CreateChildControls (and thus ItemDataBound) fires off in LoadState and agin during the page Load event and at this time it seems to have forgotten the selected key of my drop down list and other properites nor does this get corrected during the ProcessPostData Second try.  In fact the control seems to have forgotten the data it got when it ran LoadPostData in step 1.

Note: My control does not get a list of data from the user for the drop down.  It will be obtained elsewhere, by the control,  in the final control, so it is hardcoded in the sample control provided. 

 Sample files are provided below ( your can assume that Page.EnableViewState = true)

<asp:Repeater ID="testRepeater" runat="server">
<HeaderTemplate>
<tr>
<th class="icon">
Header HNc1
</th>
<th class="icon">
Header 2
</th>
<th class="icon">
Header 3
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="numeric">
<asp:TextBox ID="AllocationPercent" runat="server"></asp:TextBox>
</td>
<td class="icon">
<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox>
</td>
<td>
<asp:Panel ID="panel1" runat="server">
<pv:MyControl ID="picker2" runat="server" />
</asp:Panel>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>

----------------------------------------------------------------------------

public partial class TestMyControlR : PlanViewPage
{   
    protected void Page_Load(object sender, EventArgs e)
    {

    //*********************************************** Bind repeater ********************************************
      testRepeater.ItemDataBound += new RepeaterItemEventHandler(testRepeater_ItemDataBound);
      testRepeater.ItemCommand += new RepeaterCommandEventHandler(testRepeater_ItemCommand);

      Hashtable hash = new Hashtable();
      hash.Add(1, "One");
      hash.Add(2, "Two");

      testRepeater.DataSource = hash;
      testRepeater.DataBind();


      if (!Page.IsPostBack)
      {

        Page.Trace.Write("Time to Bind the page");
        Page.DataBind();
      }
    }

    public void TestControl_TextChanged(object sender, EventArgs e)
    {

      MyControl myTestControl = (MyControl) sender;
    }


    void testRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
      {
 
        // Command handler goes here
      }
    }

    void testRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {

      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
      {
        Page.Trace.Write("In testRepeater_ItemDataBound");

        MyControl picker2 =
          (MyControl)e.Item.FindControl("picker2");

        if (!Page.IsPostBack)
        {
          picker2.SelectedKey = "THREE";
        }
        else
        {
          picker2.SelectedKey = "FOUR";
        }
        picker2.LabelText = "My Struct Picker";
        picker2.SelectedIndexChanged += TestControl_TextChanged;
        picker2.AutoPostBack = true;

      }

    }

  }

  --------------------------------------------------------------------------------------------------------

public class MyControl : CompositeControl, IPostBackDataHandler
  {
    private Label _label;
    private string _labelText = String.Empty;
    private DropDownList _dropdownlist;
    private string _selectedKey = String.Empty;
    private StandardButton _btnViewAll;
    private bool _autoPostBack = false;
    private string _commandName = "CHANGE";
    private string _commandArgument = String.Empty;

    public event EventHandler SelectedIndexChanged;

    public string LabelText
    {
      get
      {
        object o = ViewState["LabelText"];
        if (o == null)
        {
          return "Null String";
        }
        return (string) o;
      }
      set { ViewState["LabelText"] = value; }
    }

    public string SelectedKey
    {
      get
      {
        return _selectedKey;
      }
      set
      {
        _selectedKey = value;
      }
    }

    public bool AutoPostBack
    {
      get { return _autoPostBack; }
      set { _autoPostBack = value; }
    }

    public string CommandName
    {
      get { return _commandName; }
      set { _commandName = value; }
    }

    public string CommandArgument
    {
      get { return _commandArgument; }
      set { _commandArgument = value; }
    }

    protected override void OnInit(EventArgs e)
    {
      base.OnInit(e);
      Page.RegisterRequiresControlState(this);
      Page.RegisterRequiresPostBack(this);
    }

    protected override void CreateChildControls()
    {
      Page.Trace.Write("In CreateChildControlsForTesting for " + "ddList" + ID);

      if (_dropdownlist == null)
      {
        _dropdownlist = new DropDownList();
      }

      if (_label == null)
      {
        _label = new Label();
      }

      if (_btnViewAll == null)
      {
        _btnViewAll = new StandardButton();
      }

      Controls.Add(_label);
      Controls.Add(_dropdownlist);
      Controls.Add(_btnViewAll);


      _btnViewAll.Label = "View";


      // DropDownList
      _dropdownlist.SelectedIndexChanged += OnSelectedIndexChanged;

    }

    protected override void OnPreRender(EventArgs e)
    {
      base.OnPreRender(e);

      if (AutoPostBack)
      {
        _dropdownlist.AutoPostBack = true;
      }

      _label.Text = LabelText;

      //  fill list
     // _dropdownlist.ID = "ddList" + ID;
      if (!Page.EnableViewState || !Page.IsPostBack || _dropdownlist.Items.Count == 0)
      {
        _dropdownlist.Items.Add(new ListItem("one", "ONE"));
        _dropdownlist.Items.Add(new ListItem("two", "TWO"));
        _dropdownlist.Items.Add(new ListItem("three", "THREE"));
        _dropdownlist.Items.Add(new ListItem("four", "FOUR"));
      }

      // can't set this until 1) have the list 2) have postback data
      // You want the postback data to do the updating unless this is not a postback
      if (SelectedKey != String.Empty)
      {
        _dropdownlist.SelectedValue = SelectedKey;
      }
      else
      {
        _dropdownlist.SelectedIndex = 0;
      }
    }

    protected virtual void OnSelectedIndexChanged(object sender, EventArgs e)
    {
      if (SelectedIndexChanged != null)
      {
        SelectedIndexChanged(this, e);
      }
    }

    protected static readonly object EventCommandObj = new object();

    public event CommandEventHandler Command
    {
      add
      {
        Events.AddHandler(EventCommandObj, value);
      }
      remove
      {
        Events.RemoveHandler(EventCommandObj, value);
      }
    }

    //this will raise the bubble event
    protected virtual void OnCommand(CommandEventArgs commandEventArgs)
    {
      CommandEventHandler eventHandler = (CommandEventHandler)Events[EventCommandObj];
      if (eventHandler != null)
      {
        eventHandler(this, commandEventArgs);
      }
      base.RaiseBubbleEvent(this, commandEventArgs);
    }

    protected virtual void OnCommandHandler(CommandEventArgs e)
    {
        OnCommand(e);
    }

    #region IPostBackDataHandler Members

    public bool LoadPostData(string postDataKey, NameValueCollection postData)
    {
      //TBD: Need to return true only if AutoPostBack is tu

      Page.Trace.Write("In LoadPostData");
      // You do not always have an instantiated dropdownlist and you do not
      // have control over its postback data.  In order to ensure that the
      // dropdownlist gets the latest data, update your SelectedKey property
      // which you will then use to set the dropdownlist.
      bool changed = false;
      string postedValue = postData[_dropdownlist.UniqueID];

      if (postedValue != SelectedKey)
      {
        changed = true;
      }

      SelectedKey = postedValue;
      return changed;
    }

    public void RaisePostDataChangedEvent()
    {
      if (
          (!Page.EnableViewState || !EnableViewState) &&
          String.IsNullOrEmpty(CommandName)
         )
      {
        OnSelectedIndexChanged(this, new EventArgs());
      }
      else
      {
        OnCommandHandler(new CommandEventArgs(CommandName, CommandArgument));
      }
    }

    protected override object SaveControlState()
    {
      Page.Trace.Write("In SaveControlState for " + "ddList_" + ID);

      object baseState = base.SaveControlState();
      Pair pair = new Pair(baseState, SelectedKey);
      return pair;
    }

    protected override void LoadControlState(object savedState)
    {
      Page.Trace.Write("In LoadControlState for " + "ddList_" + ID);

      Pair pair = savedState as Pair;
      if (pair != null)
      {
        base.LoadControlState(savedState);
        SelectedKey = (string)pair.Second;
      }
    }

    #endregion
  }
}

 

 

0
fuzzy42
2/6/2008 1:42:07 AM
asp.net.presentation-controls 72751 articles. 3 followers. Follow

1 Replies
1006 Views

Similar Articles

[PageSpeed] 19

 Hi,

 It's a shame this post never got an answer. I'm getting very similar behaviour. I have a Repeater whose ItemTemplate contains a single UserControl (which is contained in another .ascx file). This UserControl, and any controls inside it, are completely losing their ViewState on every postback. The Repeater was previously a ListView; I only changed it to a Repeater to test if that would make a difference.

 The weird thing is, ViewState was working fine before. Since I've done a little restructuring of some parts of my application, suddenly the ViewState is disappearing. None of the restructuring should have significantly changed the lifecycle of the related controls, however something has changed.

 The whole ViewState business seems very poorly worked out. I spend most of my development time battling against arcane nuances of this system. I've read up a number of detailed explanations of the page lifecycle and the mechanisms by which state is loaded, and every time I think I understand it all, something new goes wrong. I keep fighting to get my application working stably, only to find that as soon as I introduce some new feature, everything collapses again. It's getting really frustrating!

I'm now considering writing my own implementation of something similar to ViewState, so I can choose when to reload the state, rather than just vaguely pointing everything in the right direction and hoping (and/or praying) that ASP.NET gets it right.

In my particular scenario:

- The Repeater or ListView must have EnableViewState="false". The dataset it uses is large and I have no wish to bloat my ViewState when I can simply requery the required data on every postback.

- There is an additional point to the above, which is that if ViewState is enabled on the Repeater, then various things drastically stop working (like Button clicks). I think this might have something to do with issues described in this article: http://scottonwriting.net/sowblog/posts/1268.aspx

- The UserControl inside it therefore has EnableViewState="true", because that's where I need state data, each of these controls can be interacted with independently. As I say, this used to work fine. Suddenly, ViewState is being lost, even though Button clicks (and therefore all actual Post data within the control) are working.

Whatever I've done to break it, I now have to look back through my SVN logs and work out which particular innocent and insignificant-seeming code change actually resulted in this.

I don't really know where I can go with this, as it seems every time I fix one thing, something else breaks. I think constructing my own analog of ViewState is probably the best way, unfortunately that's yet another feature of the framework that I'll have had to drop, and I'm seeing less and less production benefits from using ASP.NET at all.

If anyone can point me in the direction of further information about exactly how I'm supposed to use ViewState, it'll provide fascinating reading, although I can never help thinking, "couldn't they have made this slightly simpler?"


/Serializer
0
randomaccess
11/20/2008 12:27:22 AM
Reply:

Similar Artilces:

Don't waste your time: IE Web Controls doesn't work for 1.1
From MSDN: "This product is only compatible with machines running builds of the .NET Framework (1.0.3705.0) and Visual Studio® .NET (7.0.9466)." http://msdn.microsoft.com/downloads/samples/internet/ASP_DOT_NET_ServerControls/WebControls/default.asp Works just fine for me. And Microsoft uses it with Content Management Server 2002 on Windows 2003...... I've had no problems with the IE Web Controls on 1.1 whatsoever. As a matter of fact, I have them running on a 8-node web farm. VladTheImpaler, MSDN contains outdated data (readme January 22, 2003). If that was...

'Tab' control 's visible doesn't work.Why?
I use tab control in my applition. And I set visible=false, but it doesn't work. my code is: ----------------------------------------------- <asp:ScriptManager ID="ScriptManager1" runat="server" />  <div>   <ajaxToolkit:TabContainer runat="server" ID="Tabs" Height="138px" ActiveTabIndex="0"    Width="402px">    <ajaxToolkit:TabPanel runat="server" ID="Panel1" HeaderText="Tab1" Visible="f...

I don't know why paging, sorting doesn't work in firefox
Hi. I have a gridview and paging and soring enabled but I tested on IE it works perfectly fine but when I load it on Firefox, the page link and sort link don't work at all. I don't know what the problem is. Anybody knows how to make them work on Firefox?  Hi:   It seems your problem is solved here: http://forums.asp.net/p/1183698/2015763.aspx#2015763   This post will be closed. ThanksSincerely,Allen ChenMicrosoft Online Community SupportPlease remember to mark the replies as answers if they help and unmark them if they provide no help....

Can't get the Web Controls to work.. The Build.Bat file doesn't work? HELP>> ARGGG>.
Hi.. I was wanting to use the IE Web Controls, the Tab Strip, etc, and play with it.. Since I have IIS 5, I thought I'd copy them there using the Read me.txt instructions and then copy to a dev server that I use at a web host.. Well, everything worked except the Build file doesn't build the Microsoft.UI.Webcontrols.DLL file? When I try to run it by double clicking on it, it runs really fast in  the DOS window, but I can't see what it says and it closes.. So I tried to do so manually and I received an error that the "cse.exe is not recognized as an internal or external command or batch...

Label control's text doesn't appear to be set (in the page which has a user control )when trying to update the text property in the FormView's ItemUpdated event
Hi There,I have a user control which hosts a formview control, gridview control and a label control. The grid view is usedto show rows in the DB and when clicked to edit each row, a form view opens up in edit mode with that particular row info. So I have nothing in the item template.My first question is..is it mandatory to have smth in the itemtemplate of the form view.I have controls in edititemtemplate and insertitemtemplate.When a particular row is edited, I would like to show a status msg showing that the row has been updated.For this, I use the ItemUpdated event of the formview and try ...

Custom Datagrid: Doesn't display and doesn't work
Hi all,Hope someone can share their experience! I am trying to make a custom datagrid, only in appearance for now. Results:1. On dragging the control from the VS toolbox: get a grey rectangle, not the table like look. 2. On running the Web page: no HTML.<code>Imports System.ComponentModelImports System.Web.UI.WebControlsImports System.Web.UI<DefaultProperty("Text"), ToolboxData("<{0}:custDG runat=server></{0}:custDG>")> Public Class custDG    Inherits DataGrid    Public Sub New()        Me.BorderColor = ...

3.0.12
Add an Image module and select an image for it. Go to Module settings Unselect Display Container. The container stills shows up.Do you know the truth when you hear it? I've noticed that the 'Don't Display Container' option does not apply when logged in as host or admin- the container still shows. Logging out and browsing seems to hide the container. I don't know if this applies with registered users though.Kirk The behavior of all containers is erratic as well, some don't even show the picture. This happens in both preview and design views.Do you know the truth when you hear it?...

superreview granted: [Bug 245619] Don't bother converting result of scripts into a string when the caller doesn't care about the value. : [Attachment 150056] Don't convert the result to a string if t
Brendan Eich <brendan@mozilla.org> has granted Johnny Stenback <jst@mozilla.jstenback.com>'s request for superreview: Bug 245619: Don't bother converting result of scripts into a string when the caller doesn't care about the value. http://bugzilla.mozilla.org/show_bug.cgi?id=245619 Attachment 150056: Don't convert the result to a string if the caller doesn't care about the return value. http://bugzilla.mozilla.org/attachment.cgi?id=150056&action=edit ------- Additional Comments from Brendan Eich <brendan@mozilla.org> Duh, thanks. r+sr=me....

i'm not happy that Firefox 2 doesn't work with Flash, and you don't even list it as a known issue
Name: kb Product: Firefox Summary: i'm not happy that Firefox 2 doesn't work with Flash, and you don't even list it as a known issue Comments: doesn't sound loke good DevTest before release if you haven't listed the problems with Flash. I have to close Firefox and resort to IE. So IE, is still widely used on my computer since Firefox continues to not work all the time. Browser Details: Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11 ...

Urgent: AutoCompleteExtender doesn't work/Updatepanel doesn't work
This is my code for the AutoCompleteExtender <asp:textbox id="txtQuickSearch" runat="server" CssClass="inputText" style="width:145px; "></asp:textbox> <atlas:AutoCompleteExtender runat="server" ID="acSearch"> <atlas:AutoCompleteProperties TargetControlID="txtQuickSearch" Enabled="True" ServicePath="http://localhost/Sony.BusinessSuite.Web.UI/AtlasServices/MasterData.asmx" ServiceMethod="GetAllModels" minimumprefixlength="2" /> </atlas:AutoCompleteExtender> When i start typing fiddler shows: # Result Host URL Body Caching Content-Type User-...

Spellchecker doesn't work: no error, just doesn't work
Hey all. This is only happening with one person. It's all GW7 no SP. has worked fine before. Anyway when they type along it doesn't catch that spelling and it doesn't fire up spell check before it's sent like it is checked off to do. It does nothing. It just sends it when you click send; no error, nothing. I did a rebuild, analyze/fix. I have it set at all levels for this user. any ideas Mark, well, I'd try a more recent client version first. GW7 was less than stellar before SP1. Uwe -- Novell Support Connection Volunteer SysOp Please don...

I don't know why my code don't work(it's for shopping cart)
I wrote this code for shopping cart.I used c lass for it and i want to store orders in cache.the customer username is in a session.customer select the product from a datalist.but and I want to show the orders in gridview .but when I select some product and go to the page that gridview is in it (shopping cart page)I could,t see any thing.please look at my code and see if I wrote my code incorrect.thanks for your helping me.-------------------------------------------------------------------------  //the code for add product to shopping cart(products are in data list)protected void order(o...

Installation 'Sybase DataWindow PS' printer on W98 doesn't work (so PDF export can't work either)
I have a problem with export DataWindow content to PDF on W98 systems. (I don't have any problem with PDF export on other systems like as WINNT, W2K, WXP). I found out that the problem is in the Sybase DataWindow PS printer. It looks like installed but it DOESN'T WORK on W98. When I try print something on this printer then no PostScript file is created. So I tried manual installation of it but it occurs an error during manual installation (I used description of instalation from Bruce Armstrong). The error said that printer driver (PSCRIPT.DLL) can't be loaded. I use...

Sending email via the port 465 of Gmail don't work! I don't know if there are bugs in .NET.
I use the following code to send  email via  Gmail , it works well when I use client.Port = 587, but it doesn't work if I use client.Port = 465 !  but If I use email client software such as Outlook Express with port 465, it woks well, I don't know if there are bugs in .NET.     protected void btnSend_Click(object sender, EventArgs e)    {        //Add Async="true" to .ASPX page         SmtpClient client=new SmtpClient();     ...

Web resources about - Repeater Containing Custom Control Doesn't Work With Page ViewState On Unless I Don't ReBind... - asp.net.presentation-controls

Resources last updated: 12/28/2015 1:20:01 PM