无法加载视图状态复合控件

发布于 2024-09-29 02:47:51 字数 21319 浏览 2 评论 0原文

我有一个复合控件,其中包含一组不同的子控件,这些子控件基于运行时其中一个属性的值。 每当有回发时,我都会收到以下错误:

Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.

我一直在谷歌上搜索这个问题并反复更改子控件实例化的顺序,但没有成功。谁能告诉我我在这里做错了什么?复合控制中的控件本身可以正确运行,不会出现错误。

这是复合控件:

    [Serializable]
public enum AddEditType
{
    SelectList,
    SelectSingleItem,
    SelectSingleItemWithForm,
    Form
}
[Themeable(true)]
[Serializable]
public class AddEdit<TBO, TCriteria> : CompositeControl
    where TBO : Bll.BOBase
    where TCriteria : Bll.BaseCriteria
{
    #region Constructor
    public AddEdit(ObjectType myObjectType, AddEditType myType, EquatableList<TBO> myDataList, EditPageViewType myViewType)
    {
        this.ObjectType = myObjectType;
        this.Type = myType;
        this.myViewType = myViewType;
        cachedOriginalList = myDataList.Clone();
        cachedCurrentList = myDataList.Clone();
    }
    #endregion

    #region Private Fields
    private EditPageViewType myViewType = EditPageViewType.Read;
    private EquatableList<TBO> cachedOriginalList
    {
        get
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Look for cached data.
            string cacheKey = GenerateCacheKey("cachedOriginalList");
            EquatableList<TBO> myList = (EquatableList<TBO>)cache.GetData(cacheKey);
            return myList;
        }
        set
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Store the value in the cache.
            string cacheKey = GenerateCacheKey("cachedOriginalList");
            cache.Add(cacheKey, value);
        }
    }
    private EquatableList<TBO> cachedCurrentList
    {
        get
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Look for cached data.
            string cacheKey = GenerateCacheKey("cachedCurrentList");
            EquatableList<TBO> myList = (EquatableList<TBO>)cache.GetData(cacheKey);
            return myList;
        }
        set
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Store the value in the cache.
            string cacheKey = GenerateCacheKey("cachedCurrentList");
            cache.Add(cacheKey, value);
        }
    }
    private Label myTitle;
    private UpdatePanel myCurrentEntriesUpdatePanel;
    private ButtonPanel myButtonPanel;
    private MyCompanygridview myCurrentEntriesGridView;
    private Panel myEditEntriesPanel;
    private HiddenField myModalPopupTargetControl;
    private ModalPopupExtender myEditEntriesPopup;
    private UpdatePanel myEditEntriesUpdatePanel;
    private Label myEditTitle;
    private Panel myEditContentPanel;
    private SearchGrid<TCriteria> mySearchGrid;
    private Button myConfirmEditEntriesChangesButton;
    private Button myCancelEditEntriesChangesButton;
    private TCriteria mySearchCriteria;

    #endregion

    #region Public Properties
    /// <summary>
    /// Gets or sets the type of display that should be shown in the Add/Edit Control.
    /// </summary>
    /// <summary>
    /// Gets or sets the type of display that should be shown in the Add/Edit Control.
    /// </summary>
    [Category("AddEdit"),
    Description("Gets or sets the type of display that should be shown in the Add/Edit Control."),
    DefaultValue(null)]
    public AddEditType Type
    {
        get
        {
            return (AddEditType)ViewState["AddEditType"];
        }
        set
        {
            ViewState["AddEditType"] = value;
        }

    }
    /// <summary>
    /// Gets or sets the type of items that should be shown in the Add/Edit Control.
    /// </summary>
    /// <summary>
    /// Gets or sets the type of items that should be shown in the Add/Edit Control.
    /// </summary>
    [Category("AddEdit"),
    Description("Gets or sets the type of items that should be shown in the Add/Edit Control."),
    DefaultValue(null)]
    public ObjectType ObjectType
    {
        get
        {
            return (ObjectType)ViewState["ObjectType"];
        }
        set
        {
            ViewState["ObjectType"] = value;
        }

    }
    public EquatableList<TBO> DataList
    {
        get
        {
            return cachedCurrentList;
        }
        set
        {
            cachedCurrentList = value;
        }
    }
    /// <summary>
    /// Gets or sets the search criteria.
    /// </summary>
    /// <value>The search criteria.</value>
    public TCriteria SearchCriteria
    {
        get
        {
            return mySearchCriteria;
        }
        set
        {
            mySearchCriteria = value;
        }
    }
    #endregion
    #region Overridden Methods
    protected override void RecreateChildcotrols()
    {
        EnsureChildcontrols();
    }
    protected override void CreateChildControls()
    {
        Controls.Clear();

        ButtonPanelType myButtonPanelType = ButtonPanelType.SelectList;
        string myEditEntriesTitle = "Select " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
        switch (Type)
        {
            case AddEditType.Form:
                myButtonPanelType = ButtonPanelType.SelectList;
                myEditEntriesTitle = "Edit " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                break;
            case AddEditType.SelectList:
                myButtonPanelType = ButtonPanelType.SelectList;
                myEditEntriesTitle = "Select " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                break;
            case AddEditType.SelectSingleItem:
                myButtonPanelType = ButtonPanelType.SelectSingleItem;
                myEditEntriesTitle = "Select " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                break;
            case AddEditType.SelectSingleItemWithForm:
                myButtonPanelType = ButtonPanelType.SelectSingleItem;
                myEditEntriesTitle = "Select/Edit " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                break;
        }


        AddEditParser parser = AddEditParserFactory.GetParser(this.ObjectType);

        // Define the Title Label
        myTitle = new Label();
        this.Controls.Add(myTitle);
        myTitle.ID = "lblTitle";
        myTitle.Text = Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";

        // Define the Current Entries Update Panel
        myCurrentEntriesUpdatePanel = new UpdatePanel();
        this.Controls.Add(myCurrentEntriesUpdatePanel);
        myCurrentEntriesUpdatePanel.ID = "updpnlCurrentEntries";
        myCurrentEntriesUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;


        // Define the Button Panel
        myButtonPanel = new ButtonPanel(myButtonPanelType, myViewType);
        myButtonPanel.AddButtonClick += new EventHandler(myButtonPanel_AddButtonClick);
        myButtonPanel.ResetButtonClick += new EventHandler(myButtonPanel_ResetButtonClick);
        myButtonPanel.RemoveSelectedButtonClick += new EventHandler(myButtonPanel_RemoveSelectedButtonClick);
        myCurrentEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myButtonPanel);            

        // Define the Current Entries MyCompanygridView using parser
        // and add it to the content template of the updatepanel.
        myCurrentEntriesGridView = new MyCompanygridview();
        parser.CreateGridViewColumns(ref myCurrentEntriesGridView);
        myCurrentEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myCurrentEntriesGridView);
        myCurrentEntriesGridView.ID = "gvCurrentEntries";
        myCurrentEntriesGridView.AutoGenerateColumns = false;
        myCurrentEntriesGridView.DataKeyNames = new string[] { "ID" };
        myCurrentEntriesGridView.DataSource = cachedCurrentList;
        myCurrentEntriesGridView.AllowSorting = true;
        myCurrentEntriesGridView.Width = new System.Web.UI.WebControls.Unit("100%");
        myCurrentEntriesGridView.AllowPaging = true;
        myCurrentEntriesGridView.EnableCustomPager = true;
        myCurrentEntriesGridView.SelectionType = MyCompanygridviewSelectionType.Multiple;



        // Define the Edit Entries Panel
        myEditEntriesPanel = new Panel();
        this.Controls.Add(myEditEntriesPanel);
        myEditEntriesPanel.ID = "pnlEditEntries";
        myEditEntriesPanel.CssClass = "modalWindow";


        // Define the HiddenField used as the TargetControlID 
        // for the ModalPopupExtender, and add it to the panel.
        myModalPopupTargetControl = new HiddenField();
        myEditEntriesPanel.Controls.Add(myModalPopupTargetControl);
        myModalPopupTargetControl.ID = "hfModalPopupTargetControl";


        // Define the ModalPopupExtender and add it to the panel.
        myEditEntriesPopup = new ModalPopupExtender();
        myEditEntriesPanel.Controls.Add(myEditEntriesPopup);
        myEditEntriesPopup.ID = "mpeEditEntries";
        myEditEntriesPopup.BackgroundCssClass = "modalBackground";
        myEditEntriesPopup.PopupControlID = "pnlEditEntries";
        myEditEntriesPopup.TargetControlID = "hfModalPopupTargetControl";



        // Define the Edit Entries Update Panel
        myEditEntriesUpdatePanel = new UpdatePanel();
        myEditEntriesPanel.Controls.Add(myEditEntriesUpdatePanel);
        myEditEntriesUpdatePanel.ID = "updpnlEditEntries";
        myEditEntriesUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;


        // Define the Edit Entries Title
        myEditTitle = new Label();
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myEditTitle);
        myEditTitle.ID = "lblEditTitle";
        myEditTitle.Text = myEditEntriesTitle;


        // Define the Edit Entries Content
        myEditContentPanel = new Panel();
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myEditContentPanel);
        myEditContentPanel.ID = "pnlEditContent";
        switch (Type)
        {
            case AddEditType.Form:
                parser.CreateFormControls(ref myEditContentPanel, new Dictionary<SearchPanelControlType, string>());
                break;
            case AddEditType.SelectList:
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                mySearchGrid.GridView.SelectionType = MyCompanygridviewSelectionType.Multiple;
                mySearchGrid.SearchCriteria = this.mySearchCriteria;
                myEditContentPanel.Controls.Add(mySearchGrid);
                break;
            case AddEditType.SelectSingleItem:
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                mySearchGrid.GridView.SelectionType = MyCompanygridviewSelectionType.Single;
                mySearchGrid.SearchCriteria = this.mySearchCriteria;
                myEditContentPanel.Controls.Add(mySearchGrid);
                break;
            case AddEditType.SelectSingleItemWithForm:
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                mySearchGrid.GridView.SelectionType = MyCompanygridviewSelectionType.Single;
                mySearchGrid.SearchCriteria = this.mySearchCriteria;
                myEditContentPanel.Controls.Add(mySearchGrid);
                parser.CreateFormControls(ref myEditContentPanel, new Dictionary<SearchPanelControlType, string>());
                break;
        }

        // Define the Confirm/Cancel buttons
        myConfirmEditEntriesChangesButton = new Button();
        myConfirmEditEntriesChangesButton.Click += new EventHandler(myConfirmEditEntriesChangesButton_Click);
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myConfirmEditEntriesChangesButton);
        myConfirmEditEntriesChangesButton.ID = "btnConfirmEditEntriesChanges";
        myConfirmEditEntriesChangesButton.Text = "Save";
        myConfirmEditEntriesChangesButton.CausesValidation = true;


        myCancelEditEntriesChangesButton = new Button();
        myCancelEditEntriesChangesButton.Click += new EventHandler(myCancelEditEntriesChangesButton_Click);
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myCancelEditEntriesChangesButton);
        myCancelEditEntriesChangesButton.ID = "btnCancelEditEntriesChanges";
        myCancelEditEntriesChangesButton.Text = "Cancel";
        myCancelEditEntriesChangesButton.CausesValidation = true;




        ConfigureDisplay();
    }


    //protected override void Render(HtmlTextWriter writer)
    //{
    //    AddAttributesToRender(writer);

    //    writer.RenderBeginTag(HtmlTextWriterTag.Div);

    //    myTitle.RenderControl(writer);
    //    myCurrentEntriesUpdatePanel.RenderControl(writer);
    //    myEditEntriesPanel.RenderControl(writer);

    //    writer.RenderEndTag();
    //}
    #endregion

    #region Public Event Handlers
    #region Make the OnCancel event of the AddEdit control visible
    private static readonly object EventCancelEditKey = new object();
    public event EventHandler CancelEdit
    {
        add
        {
            Events.AddHandler(EventCancelEditKey, value);
        }
        remove
        {
            Events.RemoveHandler(EventCancelEditKey, value);
        }
    }
    protected virtual void OnCancelEdit(EventArgs e)
    {
        EventHandler CancelEditHandler = (EventHandler)Events[EventCancelEditKey];
        if (CancelEditHandler != null)
        {
            CancelEditHandler(this, e);
        }
    }
    private void myCancelEditEntriesChangesButton_Click(object source, EventArgs e)
    {
        myEditEntriesPopup.Hide();
        ResetEditEntriesControls();
        OnCancelEdit(EventArgs.Empty);
    }
    #endregion
    #region Make the OnConfirmEdit event of the AddEdit control visible
    private static readonly object EventConfirmEditKey = new object();
    public event EventHandler ConfirmEdit
    {
        add
        {
            Events.AddHandler(EventConfirmEditKey, value);
        }
        remove
        {
            Events.RemoveHandler(EventConfirmEditKey, value);
        }
    }
    protected virtual void OnConfirmEdit(EventArgs e)
    {
        EventHandler ConfirmEditHandler = (EventHandler)Events[EventConfirmEditKey];
        if (ConfirmEditHandler != null)
        {
            ConfirmEditHandler(this, e);
        }
    }
    private void myConfirmEditEntriesChangesButton_Click(object source, EventArgs e)
    {

        if (Type != AddEditType.Form)
        {
            EquatableList<TBO> myOldList = cachedCurrentList.Clone();

            try
            {
                List<Guid> mySelectedValues = mySearchGrid.GridView.SelectedValues;

                // Add each item in the SelectedValues list
                // to the cachedCurrentList
                foreach (Guid currentGUID in mySelectedValues)
                {
                    ObjectMetaDataDictionary myOMD = ObjectMetaDataDictionary.Instance;
                    Type _objectType = myOMD[this.ObjectType].BOClass;

                    TBO myObject = (TBO)Activator.CreateInstance(_objectType);

                    // Check to see if it already exists in the 
                    // cachedCurrentList. If it doesn't, add it.
                    if (!cachedCurrentList.ExistByID<TBO>(currentGUID))
                    {
                        Type _managerType = myOMD[this.ObjectType].ManagerClass;
                        Object[] myStaticMethodArguments = new Object[1];
                        myStaticMethodArguments.SetValue(currentGUID, 0);
                        MethodInfo myStaticMethodInfo = _managerType.GetMethod("GetItem");
                        myObject = (TBO)myStaticMethodInfo.Invoke(null, myStaticMethodArguments);


                        // If the Object is not null add it to the cachedCurrentList.
                        if (myObject != null)
                        {
                            cachedCurrentList.Add(myObject);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                cachedCurrentList = myOldList.Clone();
                bool rethrow = ExceptionPolicy.HandleException(ex, "Base Policy");
                if (rethrow)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendFormat("Error: {0}", ex.Message);
                }
            }
        }



        myEditEntriesPopup.Hide();
        BindCurrentGrid();
        myCurrentEntriesUpdatePanel.Update();
        ResetEditEntriesControls();
        OnConfirmEdit(EventArgs.Empty);
    }
    #endregion
    #endregion

    #region Private Event Handlers

    #endregion

    #region Private Methods
    /// <summary>
    /// Creates a string used to identify this control in the cache.
    /// </summary>
    private string GenerateCacheKey(string key)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("{0}:{1}:{2}:{3}", "AddEditControl", Enum.GetName(typeof(ObjectType), this.Type), this.Context.Session.SessionID, key);
        return sb.ToString();
    }
    private void BindCurrentGrid()
    {
        myCurrentEntriesGridView.DataSource = cachedCurrentList;
        myCurrentEntriesGridView.DataBind();

    }
    protected void myButtonPanel_AddButtonClick(object sender, EventArgs e)
    {
        myEditEntriesPopup.Show();
    }
    protected void myButtonPanel_ResetButtonClick(object sender, EventArgs e)
    {
        cachedCurrentList = cachedOriginalList.Clone();
        BindCurrentGrid();
        myCurrentEntriesUpdatePanel.Update();
        ResetEditEntriesControls();
        myEditEntriesUpdatePanel.Update();
    }
    protected void myButtonPanel_RemoveSelectedButtonClick(object sender, EventArgs e)
    {
        EquatableList<TBO> myOldList = cachedCurrentList.Clone();

        try
        {
            List<Guid> mySelectedValues = mySearchGrid.GridView.SelectedValues;
            // Remove each item in the SelectedValues list from the cachedCurrentList
            foreach (Guid currentGUID in mySelectedValues)
            {
                cachedCurrentList.RemoveAll(delegate(TBO x) { return x.Id == currentGUID; });
            }
            BindCurrentGrid();
            myCurrentEntriesUpdatePanel.Update();
            ResetEditEntriesControls();
        }
        catch (Exception ex)
        {
            cachedCurrentList = myOldList.Clone();
            bool rethrow = ExceptionPolicy.HandleException(ex, "Base Policy");
            if (rethrow)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("Error: {0}", ex.Message);
            }
        }
    }
    private void ResetEditEntriesControls()
    {
        if (Type != AddEditType.Form)
        {
            // RESET SEARCH GRID
            mySearchGrid.GridView.SelectedValues = cachedOriginalList.ToListOfIDs();
            if (typeof(IDisabledFlg).IsAssignableFrom(typeof(TBO)))
            {
                foreach (TBO item in cachedOriginalList)
                {
                    IDisabledFlg castedItem = (IDisabledFlg)item;
                    if (castedItem.DisabledFlg)
                    {
                        mySearchGrid.GridView.DisabledValues.Add(castedItem.Id);
                    }
                }
            }
            mySearchGrid.GridView.DataBind();
            mySearchGrid.SearchCriteria = this.mySearchCriteria;
        }
        if (Type == AddEditType.Form || Type == AddEditType.SelectSingleItemWithForm)
        {
            // Call parser to reset any other controls
            AddEditParser parser = AddEditParserFactory.GetParser(this.ObjectType);
            parser.SetFormControls<TBO>(null, ref myEditEntriesPanel);
        }
    }
    private void ConfigureDisplay()
    {
        myButtonPanel.ViewType = this.myViewType;
        switch (myViewType)
        {
            case EditPageViewType.Update:
                myCurrentEntriesGridView.Enabled = true;
                break;
            case EditPageViewType.Create:
                myCurrentEntriesGridView.Enabled = true;
                break;
            case EditPageViewType.Read:
                myCurrentEntriesGridView.Enabled = false;
                break;
            case EditPageViewType.Disable:
                myCurrentEntriesGridView.Enabled = false;
                break;
        }
    }
    #endregion
}

I have a composite control that contains a different set of child controls based on the value of one of it's properties at runtime.
Whenever there is a postback, I get the following error:

Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.

I have been googling this issue and changing the order of my child controls instantiation repeatedly without success. Can anyone tell me what I am doing wrong here? The controls within the composite control function correctly by themselves without error.

Here is the composite control:

    [Serializable]
public enum AddEditType
{
    SelectList,
    SelectSingleItem,
    SelectSingleItemWithForm,
    Form
}
[Themeable(true)]
[Serializable]
public class AddEdit<TBO, TCriteria> : CompositeControl
    where TBO : Bll.BOBase
    where TCriteria : Bll.BaseCriteria
{
    #region Constructor
    public AddEdit(ObjectType myObjectType, AddEditType myType, EquatableList<TBO> myDataList, EditPageViewType myViewType)
    {
        this.ObjectType = myObjectType;
        this.Type = myType;
        this.myViewType = myViewType;
        cachedOriginalList = myDataList.Clone();
        cachedCurrentList = myDataList.Clone();
    }
    #endregion

    #region Private Fields
    private EditPageViewType myViewType = EditPageViewType.Read;
    private EquatableList<TBO> cachedOriginalList
    {
        get
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Look for cached data.
            string cacheKey = GenerateCacheKey("cachedOriginalList");
            EquatableList<TBO> myList = (EquatableList<TBO>)cache.GetData(cacheKey);
            return myList;
        }
        set
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Store the value in the cache.
            string cacheKey = GenerateCacheKey("cachedOriginalList");
            cache.Add(cacheKey, value);
        }
    }
    private EquatableList<TBO> cachedCurrentList
    {
        get
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Look for cached data.
            string cacheKey = GenerateCacheKey("cachedCurrentList");
            EquatableList<TBO> myList = (EquatableList<TBO>)cache.GetData(cacheKey);
            return myList;
        }
        set
        {
            // Get reference to cache
            ICacheManager cache = CacheFactory.GetCacheManager();
            // Store the value in the cache.
            string cacheKey = GenerateCacheKey("cachedCurrentList");
            cache.Add(cacheKey, value);
        }
    }
    private Label myTitle;
    private UpdatePanel myCurrentEntriesUpdatePanel;
    private ButtonPanel myButtonPanel;
    private MyCompanygridview myCurrentEntriesGridView;
    private Panel myEditEntriesPanel;
    private HiddenField myModalPopupTargetControl;
    private ModalPopupExtender myEditEntriesPopup;
    private UpdatePanel myEditEntriesUpdatePanel;
    private Label myEditTitle;
    private Panel myEditContentPanel;
    private SearchGrid<TCriteria> mySearchGrid;
    private Button myConfirmEditEntriesChangesButton;
    private Button myCancelEditEntriesChangesButton;
    private TCriteria mySearchCriteria;

    #endregion

    #region Public Properties
    /// <summary>
    /// Gets or sets the type of display that should be shown in the Add/Edit Control.
    /// </summary>
    /// <summary>
    /// Gets or sets the type of display that should be shown in the Add/Edit Control.
    /// </summary>
    [Category("AddEdit"),
    Description("Gets or sets the type of display that should be shown in the Add/Edit Control."),
    DefaultValue(null)]
    public AddEditType Type
    {
        get
        {
            return (AddEditType)ViewState["AddEditType"];
        }
        set
        {
            ViewState["AddEditType"] = value;
        }

    }
    /// <summary>
    /// Gets or sets the type of items that should be shown in the Add/Edit Control.
    /// </summary>
    /// <summary>
    /// Gets or sets the type of items that should be shown in the Add/Edit Control.
    /// </summary>
    [Category("AddEdit"),
    Description("Gets or sets the type of items that should be shown in the Add/Edit Control."),
    DefaultValue(null)]
    public ObjectType ObjectType
    {
        get
        {
            return (ObjectType)ViewState["ObjectType"];
        }
        set
        {
            ViewState["ObjectType"] = value;
        }

    }
    public EquatableList<TBO> DataList
    {
        get
        {
            return cachedCurrentList;
        }
        set
        {
            cachedCurrentList = value;
        }
    }
    /// <summary>
    /// Gets or sets the search criteria.
    /// </summary>
    /// <value>The search criteria.</value>
    public TCriteria SearchCriteria
    {
        get
        {
            return mySearchCriteria;
        }
        set
        {
            mySearchCriteria = value;
        }
    }
    #endregion
    #region Overridden Methods
    protected override void RecreateChildcotrols()
    {
        EnsureChildcontrols();
    }
    protected override void CreateChildControls()
    {
        Controls.Clear();

        ButtonPanelType myButtonPanelType = ButtonPanelType.SelectList;
        string myEditEntriesTitle = "Select " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
        switch (Type)
        {
            case AddEditType.Form:
                myButtonPanelType = ButtonPanelType.SelectList;
                myEditEntriesTitle = "Edit " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                break;
            case AddEditType.SelectList:
                myButtonPanelType = ButtonPanelType.SelectList;
                myEditEntriesTitle = "Select " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                break;
            case AddEditType.SelectSingleItem:
                myButtonPanelType = ButtonPanelType.SelectSingleItem;
                myEditEntriesTitle = "Select " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                break;
            case AddEditType.SelectSingleItemWithForm:
                myButtonPanelType = ButtonPanelType.SelectSingleItem;
                myEditEntriesTitle = "Select/Edit " + Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                break;
        }


        AddEditParser parser = AddEditParserFactory.GetParser(this.ObjectType);

        // Define the Title Label
        myTitle = new Label();
        this.Controls.Add(myTitle);
        myTitle.ID = "lblTitle";
        myTitle.Text = Enum.GetName(typeof(ObjectType), this.ObjectType) + ":";

        // Define the Current Entries Update Panel
        myCurrentEntriesUpdatePanel = new UpdatePanel();
        this.Controls.Add(myCurrentEntriesUpdatePanel);
        myCurrentEntriesUpdatePanel.ID = "updpnlCurrentEntries";
        myCurrentEntriesUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;


        // Define the Button Panel
        myButtonPanel = new ButtonPanel(myButtonPanelType, myViewType);
        myButtonPanel.AddButtonClick += new EventHandler(myButtonPanel_AddButtonClick);
        myButtonPanel.ResetButtonClick += new EventHandler(myButtonPanel_ResetButtonClick);
        myButtonPanel.RemoveSelectedButtonClick += new EventHandler(myButtonPanel_RemoveSelectedButtonClick);
        myCurrentEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myButtonPanel);            

        // Define the Current Entries MyCompanygridView using parser
        // and add it to the content template of the updatepanel.
        myCurrentEntriesGridView = new MyCompanygridview();
        parser.CreateGridViewColumns(ref myCurrentEntriesGridView);
        myCurrentEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myCurrentEntriesGridView);
        myCurrentEntriesGridView.ID = "gvCurrentEntries";
        myCurrentEntriesGridView.AutoGenerateColumns = false;
        myCurrentEntriesGridView.DataKeyNames = new string[] { "ID" };
        myCurrentEntriesGridView.DataSource = cachedCurrentList;
        myCurrentEntriesGridView.AllowSorting = true;
        myCurrentEntriesGridView.Width = new System.Web.UI.WebControls.Unit("100%");
        myCurrentEntriesGridView.AllowPaging = true;
        myCurrentEntriesGridView.EnableCustomPager = true;
        myCurrentEntriesGridView.SelectionType = MyCompanygridviewSelectionType.Multiple;



        // Define the Edit Entries Panel
        myEditEntriesPanel = new Panel();
        this.Controls.Add(myEditEntriesPanel);
        myEditEntriesPanel.ID = "pnlEditEntries";
        myEditEntriesPanel.CssClass = "modalWindow";


        // Define the HiddenField used as the TargetControlID 
        // for the ModalPopupExtender, and add it to the panel.
        myModalPopupTargetControl = new HiddenField();
        myEditEntriesPanel.Controls.Add(myModalPopupTargetControl);
        myModalPopupTargetControl.ID = "hfModalPopupTargetControl";


        // Define the ModalPopupExtender and add it to the panel.
        myEditEntriesPopup = new ModalPopupExtender();
        myEditEntriesPanel.Controls.Add(myEditEntriesPopup);
        myEditEntriesPopup.ID = "mpeEditEntries";
        myEditEntriesPopup.BackgroundCssClass = "modalBackground";
        myEditEntriesPopup.PopupControlID = "pnlEditEntries";
        myEditEntriesPopup.TargetControlID = "hfModalPopupTargetControl";



        // Define the Edit Entries Update Panel
        myEditEntriesUpdatePanel = new UpdatePanel();
        myEditEntriesPanel.Controls.Add(myEditEntriesUpdatePanel);
        myEditEntriesUpdatePanel.ID = "updpnlEditEntries";
        myEditEntriesUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;


        // Define the Edit Entries Title
        myEditTitle = new Label();
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myEditTitle);
        myEditTitle.ID = "lblEditTitle";
        myEditTitle.Text = myEditEntriesTitle;


        // Define the Edit Entries Content
        myEditContentPanel = new Panel();
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myEditContentPanel);
        myEditContentPanel.ID = "pnlEditContent";
        switch (Type)
        {
            case AddEditType.Form:
                parser.CreateFormControls(ref myEditContentPanel, new Dictionary<SearchPanelControlType, string>());
                break;
            case AddEditType.SelectList:
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                mySearchGrid.GridView.SelectionType = MyCompanygridviewSelectionType.Multiple;
                mySearchGrid.SearchCriteria = this.mySearchCriteria;
                myEditContentPanel.Controls.Add(mySearchGrid);
                break;
            case AddEditType.SelectSingleItem:
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                mySearchGrid.GridView.SelectionType = MyCompanygridviewSelectionType.Single;
                mySearchGrid.SearchCriteria = this.mySearchCriteria;
                myEditContentPanel.Controls.Add(mySearchGrid);
                break;
            case AddEditType.SelectSingleItemWithForm:
                mySearchGrid = new SearchGrid<TCriteria>(this.ObjectType);
                mySearchGrid.GridView.SelectionType = MyCompanygridviewSelectionType.Single;
                mySearchGrid.SearchCriteria = this.mySearchCriteria;
                myEditContentPanel.Controls.Add(mySearchGrid);
                parser.CreateFormControls(ref myEditContentPanel, new Dictionary<SearchPanelControlType, string>());
                break;
        }

        // Define the Confirm/Cancel buttons
        myConfirmEditEntriesChangesButton = new Button();
        myConfirmEditEntriesChangesButton.Click += new EventHandler(myConfirmEditEntriesChangesButton_Click);
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myConfirmEditEntriesChangesButton);
        myConfirmEditEntriesChangesButton.ID = "btnConfirmEditEntriesChanges";
        myConfirmEditEntriesChangesButton.Text = "Save";
        myConfirmEditEntriesChangesButton.CausesValidation = true;


        myCancelEditEntriesChangesButton = new Button();
        myCancelEditEntriesChangesButton.Click += new EventHandler(myCancelEditEntriesChangesButton_Click);
        myEditEntriesUpdatePanel.ContentTemplateContainer.Controls.Add(myCancelEditEntriesChangesButton);
        myCancelEditEntriesChangesButton.ID = "btnCancelEditEntriesChanges";
        myCancelEditEntriesChangesButton.Text = "Cancel";
        myCancelEditEntriesChangesButton.CausesValidation = true;




        ConfigureDisplay();
    }


    //protected override void Render(HtmlTextWriter writer)
    //{
    //    AddAttributesToRender(writer);

    //    writer.RenderBeginTag(HtmlTextWriterTag.Div);

    //    myTitle.RenderControl(writer);
    //    myCurrentEntriesUpdatePanel.RenderControl(writer);
    //    myEditEntriesPanel.RenderControl(writer);

    //    writer.RenderEndTag();
    //}
    #endregion

    #region Public Event Handlers
    #region Make the OnCancel event of the AddEdit control visible
    private static readonly object EventCancelEditKey = new object();
    public event EventHandler CancelEdit
    {
        add
        {
            Events.AddHandler(EventCancelEditKey, value);
        }
        remove
        {
            Events.RemoveHandler(EventCancelEditKey, value);
        }
    }
    protected virtual void OnCancelEdit(EventArgs e)
    {
        EventHandler CancelEditHandler = (EventHandler)Events[EventCancelEditKey];
        if (CancelEditHandler != null)
        {
            CancelEditHandler(this, e);
        }
    }
    private void myCancelEditEntriesChangesButton_Click(object source, EventArgs e)
    {
        myEditEntriesPopup.Hide();
        ResetEditEntriesControls();
        OnCancelEdit(EventArgs.Empty);
    }
    #endregion
    #region Make the OnConfirmEdit event of the AddEdit control visible
    private static readonly object EventConfirmEditKey = new object();
    public event EventHandler ConfirmEdit
    {
        add
        {
            Events.AddHandler(EventConfirmEditKey, value);
        }
        remove
        {
            Events.RemoveHandler(EventConfirmEditKey, value);
        }
    }
    protected virtual void OnConfirmEdit(EventArgs e)
    {
        EventHandler ConfirmEditHandler = (EventHandler)Events[EventConfirmEditKey];
        if (ConfirmEditHandler != null)
        {
            ConfirmEditHandler(this, e);
        }
    }
    private void myConfirmEditEntriesChangesButton_Click(object source, EventArgs e)
    {

        if (Type != AddEditType.Form)
        {
            EquatableList<TBO> myOldList = cachedCurrentList.Clone();

            try
            {
                List<Guid> mySelectedValues = mySearchGrid.GridView.SelectedValues;

                // Add each item in the SelectedValues list
                // to the cachedCurrentList
                foreach (Guid currentGUID in mySelectedValues)
                {
                    ObjectMetaDataDictionary myOMD = ObjectMetaDataDictionary.Instance;
                    Type _objectType = myOMD[this.ObjectType].BOClass;

                    TBO myObject = (TBO)Activator.CreateInstance(_objectType);

                    // Check to see if it already exists in the 
                    // cachedCurrentList. If it doesn't, add it.
                    if (!cachedCurrentList.ExistByID<TBO>(currentGUID))
                    {
                        Type _managerType = myOMD[this.ObjectType].ManagerClass;
                        Object[] myStaticMethodArguments = new Object[1];
                        myStaticMethodArguments.SetValue(currentGUID, 0);
                        MethodInfo myStaticMethodInfo = _managerType.GetMethod("GetItem");
                        myObject = (TBO)myStaticMethodInfo.Invoke(null, myStaticMethodArguments);


                        // If the Object is not null add it to the cachedCurrentList.
                        if (myObject != null)
                        {
                            cachedCurrentList.Add(myObject);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                cachedCurrentList = myOldList.Clone();
                bool rethrow = ExceptionPolicy.HandleException(ex, "Base Policy");
                if (rethrow)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendFormat("Error: {0}", ex.Message);
                }
            }
        }



        myEditEntriesPopup.Hide();
        BindCurrentGrid();
        myCurrentEntriesUpdatePanel.Update();
        ResetEditEntriesControls();
        OnConfirmEdit(EventArgs.Empty);
    }
    #endregion
    #endregion

    #region Private Event Handlers

    #endregion

    #region Private Methods
    /// <summary>
    /// Creates a string used to identify this control in the cache.
    /// </summary>
    private string GenerateCacheKey(string key)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("{0}:{1}:{2}:{3}", "AddEditControl", Enum.GetName(typeof(ObjectType), this.Type), this.Context.Session.SessionID, key);
        return sb.ToString();
    }
    private void BindCurrentGrid()
    {
        myCurrentEntriesGridView.DataSource = cachedCurrentList;
        myCurrentEntriesGridView.DataBind();

    }
    protected void myButtonPanel_AddButtonClick(object sender, EventArgs e)
    {
        myEditEntriesPopup.Show();
    }
    protected void myButtonPanel_ResetButtonClick(object sender, EventArgs e)
    {
        cachedCurrentList = cachedOriginalList.Clone();
        BindCurrentGrid();
        myCurrentEntriesUpdatePanel.Update();
        ResetEditEntriesControls();
        myEditEntriesUpdatePanel.Update();
    }
    protected void myButtonPanel_RemoveSelectedButtonClick(object sender, EventArgs e)
    {
        EquatableList<TBO> myOldList = cachedCurrentList.Clone();

        try
        {
            List<Guid> mySelectedValues = mySearchGrid.GridView.SelectedValues;
            // Remove each item in the SelectedValues list from the cachedCurrentList
            foreach (Guid currentGUID in mySelectedValues)
            {
                cachedCurrentList.RemoveAll(delegate(TBO x) { return x.Id == currentGUID; });
            }
            BindCurrentGrid();
            myCurrentEntriesUpdatePanel.Update();
            ResetEditEntriesControls();
        }
        catch (Exception ex)
        {
            cachedCurrentList = myOldList.Clone();
            bool rethrow = ExceptionPolicy.HandleException(ex, "Base Policy");
            if (rethrow)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("Error: {0}", ex.Message);
            }
        }
    }
    private void ResetEditEntriesControls()
    {
        if (Type != AddEditType.Form)
        {
            // RESET SEARCH GRID
            mySearchGrid.GridView.SelectedValues = cachedOriginalList.ToListOfIDs();
            if (typeof(IDisabledFlg).IsAssignableFrom(typeof(TBO)))
            {
                foreach (TBO item in cachedOriginalList)
                {
                    IDisabledFlg castedItem = (IDisabledFlg)item;
                    if (castedItem.DisabledFlg)
                    {
                        mySearchGrid.GridView.DisabledValues.Add(castedItem.Id);
                    }
                }
            }
            mySearchGrid.GridView.DataBind();
            mySearchGrid.SearchCriteria = this.mySearchCriteria;
        }
        if (Type == AddEditType.Form || Type == AddEditType.SelectSingleItemWithForm)
        {
            // Call parser to reset any other controls
            AddEditParser parser = AddEditParserFactory.GetParser(this.ObjectType);
            parser.SetFormControls<TBO>(null, ref myEditEntriesPanel);
        }
    }
    private void ConfigureDisplay()
    {
        myButtonPanel.ViewType = this.myViewType;
        switch (myViewType)
        {
            case EditPageViewType.Update:
                myCurrentEntriesGridView.Enabled = true;
                break;
            case EditPageViewType.Create:
                myCurrentEntriesGridView.Enabled = true;
                break;
            case EditPageViewType.Read:
                myCurrentEntriesGridView.Enabled = false;
                break;
            case EditPageViewType.Disable:
                myCurrentEntriesGridView.Enabled = false;
                break;
        }
    }
    #endregion
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听风吹 2024-10-06 02:47:51

CreateChildControls 中的代码至少存在一个问题,即它是控件创建和数据绑定代码的混合体。这是不合适的,因为 ViewState 是在控件创建和数据绑定之间加载的!

将代码拆分为控件创建代码 (CreateChildControls) 和数据绑定代码,稍后在页面生命周期中运行。 load 事件是数据绑定的好地方。

进一步确保在使用控件之前确实调用了 CreateChildControls。我更喜欢在页面初始化中调用 EnsureChildControls。

At least one problem with your code in CreateChildControls is that it is a mixture of control creation and data binding code. This isn’t appropriate, because ViewState is loaded between control creation and data binding!

Split your code in control creation code (CreateChildControls) and data binding code, running later in the page life cycle. The load event is a good place for data binding.

Further make sure that CreateChildControls is really called before your controls are used. I prefer to call EnsureChildControls in page init.

梦里的微风 2024-10-06 02:47:51

错误说:

视图状态所在的控制树
正在加载必须与控件匹配
用于保存视图状态的树

这意味着,如果您在保存视图状态期间对页面有一些控制,那么在回发后加载视图状态期间它必须存在。我认为您应该检查复合控件如何创建子控件,并确保它们是在回发后创建的。

Error says:

control tree into which viewstate is
being loaded must match the control
tree that was used to save viewstate

This means that if you had some control on your page during save of the view state then it must be there during load of the view state after postback. I think you should check how your composite control creates children controls and make sure they are created after postback.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文