Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I am dynamically adding items to a CheckBoxList that configures some settings in my web part. When I set the properties and click "OK" everything on my page works as expected and displays that data it should for the check boxes selected.

My problem is that if I leave the page and come back, it no longer has the values selected and my web part displays as if no check boxes are selected.

Below is the code I am using to create the custom web part property and save the values:

[ToolboxItemAttribute(false)]
public class MultiPart : WebPart
{
    // Visual Studio might automatically update this path when you change the Visual Web Part project item.
    private const string _ascxPath = @"~/_CONTROLTEMPLATES/MultiPart/MultiPart/MultiPartUserControl.ascx";
    public List<ListItem> SelectedTabs { get; set; }


    protected override void CreateChildControls()
    {
        MultiPartUserControl control = Page.LoadControl(_ascxPath) as MultiPartUserControl;
        if (control != null)
            control.myWebPart = this;
        Controls.Add(control);
    }

    public override EditorPartCollection CreateEditorParts()
    {
        ArrayList editorArray = new ArrayList();
        MyEditorPart edPart = new MyEditorPart();
        edPart.ID = this.ID + "_editorPart1";
        editorArray.Add(edPart);
        EditorPartCollection editorParts = new EditorPartCollection(editorArray);
        return editorParts;
    }

}

public class MyEditorPart : EditorPart
{
    private Label lbl_Options;
    private CheckBoxList cbl_WebParts;

    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        cbl_WebParts = new CheckBoxList();
        lbl_Options = new Label();
        lbl_Options.Text = "<strong>Select which web parts to include:</strong><br />";

        string _ascxPath = @"~/_CONTROLTEMPLATES/MultiPart/MultiPart/MultiPartUserControl.ascx";
        Control ascxControl = Page.LoadControl(_ascxPath);

        foreach (Control c in ascxControl.FindControl("tabs").Controls)
        {
            if(c.GetType().Equals(typeof(HtmlGenericControl)) && ((HtmlGenericControl)c).TagName.ToLower() == "div")
            {
                cbl_WebParts.Items.Add(new ListItem(((HtmlGenericControl)c).Attributes["title"], c.ID));
            }
        }

        Controls.Add(lbl_Options);
        Controls.Add(cbl_WebParts);
    }

    public override bool ApplyChanges()
    {
        EnsureChildControls();
        MultiPart webPart = WebPartToEdit as MultiPart;
        if (webPart != null)
        {
            if (webPart.SelectedTabs == null)
            {
                webPart.SelectedTabs = new List<ListItem>();
            }

            foreach (ListItem li in cbl_WebParts.Items)
            {
                if (li.Selected)
                {
                    webPart.SelectedTabs.Add(li);
                }
            }
        }
        return true;
    }

    public override void SyncChanges()
    {
        EnsureChildControls();
        MultiPart webPart = WebPartToEdit as MultiPart;

        if (webPart != null && webPart.SelectedTabs != null)
        {
            foreach (ListItem li in webPart.SelectedTabs)
            {
                cbl_WebParts.Items.FindByValue(li.Value).Selected = true;
            }
        }
    }

Is there anything else I should be doing to get these values to persist across visits?

share|improve this question
add comment

1 Answer 1

up vote 8 down vote accepted

Your SelectedTabs property should be persisted. Try use this code:

[Personalizable(PersonalizationScope.Shared),
 WebBrowsable(false)]
public List<ListItem> SelectedTabs { get; set; }

Update:

Also, you should not store ListItem's. I changed List<ListItem> to List<string> and fixed some code, and it is working on my machine now. Here is the resulting code:

[ToolboxItemAttribute(false)]
public class VisualWebPart1 : WebPart
{
    // Visual Studio might automatically update this path when you change the Visual Web Part project item.
    private const string _ascxPath = @"~/_CONTROLTEMPLATES/MultiPart/MultiPart/MultiPartUserControl.ascx";

    [Personalizable(PersonalizationScope.Shared),
    WebBrowsable(false)]
    public List<string> SelectedTabs { get; set; }


    protected override void CreateChildControls()
    {
        Control control = Page.LoadControl(_ascxPath);
        Controls.Add(control);
    }

    public override EditorPartCollection CreateEditorParts()
    {
        ArrayList editorArray = new ArrayList();
        MyEditorPart edPart = new MyEditorPart();
        edPart.ID = this.ID + "_editorPart1";
        editorArray.Add(edPart);
        EditorPartCollection editorParts = new EditorPartCollection(editorArray);
        return editorParts;
    }

}

public class MyEditorPart : EditorPart
{

    private Label lbl_Options;
    private CheckBoxList cbl_WebParts;

    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        cbl_WebParts = new CheckBoxList();
        lbl_Options = new Label();
        lbl_Options.Text = "<strong>Select which web parts to include:</strong><br />";

        string _ascxPath = @"~/_CONTROLTEMPLATES/MultiPart/MultiPart/MultiPartUserControl.ascx";
        Control ascxControl = Page.LoadControl(_ascxPath);

        foreach (Control c in ascxControl.FindControl("tabs").Controls)
        {
            if(c.GetType().Equals(typeof(HtmlGenericControl)) && ((HtmlGenericControl)c).TagName.ToLower() == "div")
            {
                cbl_WebParts.Items.Add(new ListItem(((HtmlGenericControl)c).Attributes["title"], c.ID));
            }
        }

        Controls.Add(lbl_Options);
        Controls.Add(cbl_WebParts);
    }

    public override bool ApplyChanges()
    {
        EnsureChildControls();
        VisualWebPart1 webPart = WebPartToEdit as VisualWebPart1;
        if (webPart != null)
        {
            if (webPart.SelectedTabs == null)
            {
                webPart.SelectedTabs = new List<string>();
            }

            foreach (ListItem li in cbl_WebParts.Items)
            {
                if (li.Selected)
                {
                    webPart.SelectedTabs.Add(li.Value);
                }
            }
        }
        return true;
    }

    public override void SyncChanges()
    {
        EnsureChildControls();
        VisualWebPart1 webPart = WebPartToEdit as VisualWebPart1;

        if (webPart != null && webPart.SelectedTabs != null)
        {
            foreach (string value in webPart.SelectedTabs)
            {
                cbl_WebParts.Items.FindByValue(value).Selected = true;
            }
        }
    }
}
share|improve this answer
    
When I add that I get the following error at the top of the Edit pane: Cannot save all of the property settings for this Web Part. An error has occurred. –  Abe Miessler May 3 '11 at 17:35
    
That's much better :) Now you can observe your ULS logs and grab the exception message from there. –  Andrey Markeev May 3 '11 at 17:39
    
When I monitor the ULS logs all I see is Leaving Monitored Scope (PostResolveRequestCacheHandler). Execution Time=60.653588654424 when I click OK or Apply. No errors are being thrown in the log. –  Abe Miessler May 3 '11 at 17:49
2  
I'm not Jon Skeet, so I can't explain accurately. But it is always a bad idea for me - to store somewhere in db webcontrols instances and their helper classes instances. These are very complex classes with much logic and bindings inside, so better to deal with more lightweight classes instead. For example, if you want to store Text+Value, you can use Dictionary<string,string>. –  Andrey Markeev May 3 '11 at 18:50
2  
@omlin thats exactly right. ListItem isnt serializable so it cannot be used msdn.microsoft.com/en-us/library/…. ArrayList is, btw.msdn.microsoft.com/en-us/library/… –  Anders Rask May 3 '11 at 22:18
show 6 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.