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

发布于 2024-07-27 14:22:32 字数 896 浏览 2 评论 0原文

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

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

我调试了它并弄清楚了它在做什么 - 在编辑模式下单击“确定”后,首先调用 WebPart.CreateChildControls(),然后调用 EditorPart.ApplyChanges()。 所以数据已更新,但显示的是未更新的数据。

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

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

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

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

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?

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

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

发布评论

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

评论(4

没有心的人 2024-08-03 14:22:32

调用方法和事件的顺序是这样的:
创建子控件
应用更改
OnPreRender

因此,如果您访问 CreateChildControls 中的属性,它们不是当前的。
因此,我将访问 webpart 属性的代码从 CreateChildControls 移至 OnPreRender
一切正常。

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.

萌酱 2024-08-03 14:22:32

我不确定这是否是您遇到的问题,但我遇到的问题似乎有些相似,所以我将在这里描述它以及我的解决方案。

我的编辑器部分与某些类型的 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;
    }
}

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;
    }
}
み格子的夏天 2024-08-03 14:22:32

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

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

You can force a refresh of the page using :

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

心作怪 2024-08-03 14:22:32

使用这些方法的顺序是

protected override void CreateChildControls()
{

}

public override void SyncChanges()
{

}

public override bool ApplyChanges()
{

}

The order of using the methods would be

protected override void CreateChildControls()
{

}

public override void SyncChanges()
{

}

public override bool ApplyChanges()
{

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