views:

1779

answers:

3

I am creating a web part for SharePoint. I have a custom editor part which is overriding the SyncChanges() and ApplyChanges() methods (among others).

The problem is that when I click OK in edit mode, the page is switched to browse mode, but data (propeties) which were changed in the EditorPart and saved in the ApplyChanges() method are not updated. I must 'enter the page' again (reload without POSTing the data again) to see the change that was made.

I debugged it and figured out what it is doing - after clicking OK in edit mode, WebPart.CreateChildControls() is called first, and EditorPart.ApplyChanges() second. So the data was updated but being displayed was the non-updated data.

I figured something else in this behavior: Adding one specific control to my WebPart in CreateChildControls() causes the wrong order of calling WebPart.CreateChildControls() and EditorPart.ApplyChanges(). In my case it causes adding of the WebDataTree or UltraWebTree controls (from Infragistics) but it can also happen with the common ASP.NET TextBox (as described the same problem in detail here: ASP.net forum thread).

So if I add the tree, CreateChildControls() is called first and ApplyChanges second, so it is not actual. I must refresh to see the changes I made in the editor part.

If I comment adding the tree to the controls collection, ApplyChanges is called first and everything is ok (except I need that tree :) )...

Does anyone know what can cause this weird behavior?

A: 

I'm not sure if this is what you are running into, but an issue I have had seems somewhat similar, so I will describe it here along with my solution.

I have synchronization issues in my editor parts with certain types of UI controls (namely drop downs). My problem is that my web part property has the drop down value/key, but when I am building my editor part it does not yet have the drop down list items when SynchChanges() is called, so I can't set my drop down value at that time. I handle this by using a synchronization member variable as follows.

private DropDownList _dropDownList;
private string _syncDropDownId;

public override SyncChanges()
{
    // This will make sure CreateChildControls() is called
    // but that doesn't help me with my drop down list data
    // which is loaded in OnPreRender()
    this.EnsureChildControls();

    MyWebPart webPart = this.WebPartToEdit as MyWebPart;

    // Temporarily store the drop down value for now
    // since our drop down is not fully built yet
    _syncDropDownId = myWebPart.SomeId;
}

protected override void CreateChildControls()
{
    base.CreateChildControls();

    // Create our drop down list, but don't populate it yet
    _dropDownList = new DropDownList();
    this.Controls.Add(_dropDownList);
}

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

    // Load drop down list items
    _dropDownList.Items.AddRange(GetListItems());

    // Select item in drop down list based on web part property
    if (_syncDropDownId != null)
    {
        if (_dropDownList.Items.FindByValue(_syncDropDownId) != null)
        {
            _dropDownList.SelectedValue = _syncDropDownId;
        }
        _syncDropDownId = null;
    }
}
Kirk Liemohn
A: 

You can force a refresh of the page using :

Page.Response.Redirect(Page.Request.Url.ToString());

Ciprian Grosu
+1  A: 

The order of calling methods and evetns is this: CreateChildControls ApplyChanges OnPreRender

So if you access the properties in CreateChildControls they are not current. So I moved the code that access webpart properties from CreateChildControls to OnPreRender and everything works correctly.

Vojtech Nadvornik