在SharePoint Web部件中调用CreateChildControls()和ApplyChanges()方法的顺序

时间:2009-07-23 07:35:40

标签: sharepoint web-parts

我正在为SharePoint创建Web部件。我有一个自定义编辑器部分,它覆盖了SyncChanges()和ApplyChanges()方法(等等)。

问题在于,当我在编辑模式下单击“确定”时,页面将切换到浏览模式,但不会更新在EditorPart中更改并保存在ApplyChanges()方法中的数据(属性)。我必须再次“进入页面”(重新加载而不再重新发布数据)以查看所做的更改。

我调试了它并弄明白它在做什么 - 在编辑模式下单击OK之后,首先调用WebPart.CreateChildControls(),然后调用EditorPart.ApplyChanges()。因此数据已更新,但显示的是未更新的数据。

我在这种行为中想到了其他的东西:在CreateChildControls()中向我的WebPart添加一个特定控件会导致调用WebPart.CreateChildControls()和EditorPart.ApplyChanges()的顺序错误。在我的情况下,它会导致添加WebDataTree或UltraWebTree控件(来自Infragistics),但它也可能发生在常见的ASP.NET TextBox中(如此处详细描述的相同问题:ASP.net forum thread)。

因此,如果我添加树,则首先调用CreateChildControls(),然后调用ApplyChanges,因此它不是实际的。我必须刷新才能看到我在编辑器部分所做的更改。

如果我评论将树添加到控件集合中,首先调用ApplyChanges并且一切正常(除了我需要那个树:))...

有谁知道什么会导致这种奇怪的行为?

4 个答案:

答案 0 :(得分:4)

调用方法和evetns的顺序是这样的: 的CreateChildControls 应用更改 的OnPreRender

因此,如果您访问CreateChildControls中的属性,则它们不是最新的。 所以我将访问webpart属性的代码从CreateChildControls移动到OnPreRender 一切正常。

答案 1 :(得分:2)

我不确定这是否是您遇到的问题,但我遇到的问题似乎有点类似,所以我将在此处与我的解决方案一起描述。

我的编辑器部分中存在某些类型的UI控件(即下拉菜单)的同步问题。我的问题是我的web部件属性有下拉值/键,但是当我构建我的编辑器部分时,调用SynchChanges()时它还没有下拉列表项,所以我无法设置我的下拉列表当时的价值。我通过使用同步成员变量来处理这个问题,如下所示。

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;
    }
}

答案 2 :(得分:0)

您可以使用以下方式强制刷新页面:

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

答案 3 :(得分:0)

使用方法的顺序是

protected override void CreateChildControls()
{

}

public override void SyncChanges()
{

}

public override bool ApplyChanges()
{

}