3

I have a web part that contains a number of custom properties. Only one of those customer properties shall not be set by the user. This property is an int, that represent a unique identifier.

I want to set this unique identifier the first time the web part is created. Certainly that means that if the identifier is 0, I set it to a new value that is incremented each time a value was used.

However, the value in the property doesn't get saved at all. It is available for the time the webpart is on the page, on refresh, the value will be set with the next unique value. (Actually the unique identifier is nothing else than an autoincremented number)

The property looks like this: [Personalizable()] public int InstanceId { get { return _instanceId; } set { _instanceId = value; } }

The property itself works fine when it gets set by the editor part applychanges method. I tried some samples with the GetLimitedWebPartManager, but it raises me an exception that the web part is not on the page. Most of those samples are used for changing an arbitrary webpart, the point here, I want to change the web part's property when it gets loaded.

So my question is, when the webpart's properties get saved and how? Is there a possibility to save the customer properties of the web part from inside the webpart?

Anyone an idea what i am doing wrong?

[Update] Thanks for hint djeeg. Tried this variant: (Is there a reason why new users are not allowed to use image tags?) http://www.freeimagehosting.net/image.php?8eb1892142.jpg and get the message that the webpart is not on the page (like before). I already searched for that exception and I am sure, this is the only WebPartManager instance that is used.

thanks

Holger

4 Answers 4

2

Try this

public class CustomWebPart : System.Web.UI.WebControls.WebParts.WebPart {
    private int _instanceId = 0;
    [Personalizable()] 
    public int InstanceId { 
        get { return _instanceId; } 
        set { _instanceId = value; } 
    }
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        if (!Page.IsPostBack) { 
            if(InstanceId == 0) {
                InstanceId = 0; //set it to something   
                //this.WebPartManager.SaveChanges(this);
                using(SPLimitedWebPartManager manager = SPContext.Current.Web.GetLimitedWebPartManager(Page.Url, PersonalizationScope.Shared)) {
                    foreach(AspNetWebpart webpart in manager.WebParts) {
                        using(webpart) {
                            if(webpart == this) {
                                manager.SaveChanges(this);
                                manager.SaveChanges(webpart);
                            }
                        }
                    }
                }
            }
        }
    }
}
5
  • I've already seen this sample. I am kind of speechless because I simply do not have that method available and I also don't find it here: msdn.microsoft.com/en-us/library/…. I use exactly this base class. Do I miss something really evident? I do use Sharepoint 2010. Does that make a difference?
    – user2174
    Jan 14, 2011 at 8:29
  • and you tried using the SPLimitedWebPartManager like i have edited?
    – djeeg
    Jan 14, 2011 at 9:32
  • Looks pretty much like I did (seen my answer?). Two things: 1. What is Page.Url? Didn't find it. 2. The comparison with the current web part didn't work in my sample. They seem to be different objects with the same content. As I would like to distinguish between multiple web parts on one page, so did it really work? (sorry for asking)
    – user2174
    Jan 14, 2011 at 10:49
  • Used SPUtility.GetPageUrlPath(HttpContext.Current) to get the Page's URL. The code doesn't work as the comparison webpart == this doesn't work. I tried ClientID but it seems it is not set propertly in the instance that is available in the WebPartManager. Any other suggestions?
    – user2174
    Jan 14, 2011 at 10:59
  • it works when checking the ID like in my sample below. It didn't work to save the changes of "this", as than the error message like described above comes up, but it does work when leaving that out. Thanks!
    – user2174
    Jan 14, 2011 at 11:23
2

Finally found the solution:

http://www.sharepointdev.net/sharepoint--development-programming/save-web-part-settings-45128.shtml

Here's a snippet:

        SPContext.Current.Web.AllowUnsafeUpdates = true;
        SPFile file = SPContext.Current.File;
        SPLimitedWebPartManager mgr = file.GetLimitedWebPartManager(PersonalizationScope.Shared);

        for (int index = 0; index < mgr.WebParts.Count;index++ )
        {
            if (mgr.WebParts[index].ID == this.ID)
            {
               // Do your changes                   
               mgr.SaveChanges(mgr.WebParts[index]);
            }
        }
        SPContext.Current.Web.AllowUnsafeUpdates = false;
2

We can also use:

base.SetPersonalizationDirty();
1
  • Thanks a lot for this answer, thats much easier and works in sandbox solutions as well! (the other solution does not work in sandbox because there is no SPLimitedWebPartManager in sandbox solutions)
    – Marc
    Mar 14, 2013 at 5:21
0

As far as finding your web part in the SPLimitedWebPartManager, instead of looping through you can use the StorageKey property.

using(SPLimitedWebPartManager manager = SPContext.Current.Web.GetLimitedWebPartManager(SPContext.Current.Web.Url, PersonalizationScope.Shared))
{
MyWebPartType part = (MyWebPartType)manager.WebParts[((SPWebPartManager(WebPartManager.GetCurrencWebPartManager(Page))).GetStorageKey(this)];
...the rest of your code.

Or if you're inheriting your web part from Microsoft.SharePoint.WebPartPages.WebPart it's simply this.StorageKey.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.