覆盖SharePoint:自定义表单模板中的SaveButton

时间:2011-03-09 16:57:59

标签: c# asp.net sharepoint-2010 override

首先让我清空并发布已解释如何覆盖SaveButton的文章:

我已阅读并了解它们,我只是不知道如何在我的特定情况下完全实现它:

我有一个自定义渲染模板“ CustomRender ”,其中包含“真实表单”。真实表单的代码看起来像这些行:

<%@ Register TagPrefix="wssuc" TagName="ToolBar"
             src="~/_controltemplates/ToolBar.ascx" %>
<%@ Control Language="C#" AutoEventWireup="true"
    CodeBehind="RealForm.ascx.cs" Inherits="CustomNameSpace.CustomForm" %>
<p>Test</p>
<wssuc:ToolBar runat="server" id="toolbar">
    <TemplateButtons>
        <SharePoint:SaveButton runat="server" />
    </TemplateButtons>
</wssuc:ToolBar>

现在我要覆盖此保存按钮。上面的网站声明我只需要编写另一个覆盖按钮的控件。 E.g:

public class NewSaveButton: SaveButton

{
    protected override bool SaveItem()

    {
        bool success = base.SaveItem();

        RedirectUrl = String.Concat(List.ParentWeb.ServerRelativeUrl, "/",
                      List.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, @"?ID=", 
                      ListItem.ID, @"&Source=", ListItem.ParentList.DefaultViewUrl);
        return success;

    }
}

现在我只是不知道如何在我的其他模板中注册此模板。我可以不只是覆盖我的模板背后的代码中的SaveButton - 我将如何做到这一点并在以后引用它?

  • 选项一:表单的代码隐藏(RealForm.ascx.cs) - 我可以将覆盖方法放在那里吗?如何在表单中引用该按钮(如何获取<NewSaveButton>)?
  • 选项二:仅用于按钮的另一个模板,例如SaveButton.ascx“ - 我如何通过<%@ Register... %>引用它,即如何通过功能部署时知道PublicKeyToken等。同样的事情:我的目标是得到某种”{ {1}}“控制表单。

2 个答案:

答案 0 :(得分:3)

当您执行此操作时,您正在创建新的服务器控件,因此您需要在页面上注册新控​​件(或者在本例中,在模板.ascx文件中)。

<%@ Register TagPrefix="MyPrefix" Namespace="ControlNamespace" Assembly="MyFullyQualifiedAssembly" %>

在您的代码文件中,您可以将ToolboxDataAttribute添加到课程中(只有在视觉工作室中拖动和删除工具箱中的控件时才需要这样做)

[ToolboxData("<{0}:NewSaveButton runat=\"server\"></{0}:NewSaveButton>")]
public class NewSaveButton : SaveButton {}

现在,您应该可以使用以下内容替换表单上的“保存”按钮:

<MyPrefix:NewSaveButton runat="server"></MyPrefix:NewSaveButton>

你基本上是按照asp.net的规则创建一个新的服务器控件(这里没有特定于sharepoint的东西)。

有关详细信息,请查看此页面:http://msdn.microsoft.com/en-us/library/yhzc935f(v=VS.85).aspx

答案 1 :(得分:2)

在使用SaveButton的页面上,您可以执行以下操作(在我的情况下,在DataFormWebPart的XSL标记中添加了保存按钮):

// On your page with SaveButton you could do the following trick 
// (in my case save button is added in DataFormWebPart's XSL markup):

SPContext itemContext;
DataFormWebPart dataForm; // from designer's code behind

void Page_Init(object sender, EventArgs e)
{
    // NOTE: by some reason ItemContexts of controls in DFWP are differ,
    // so only SaveButton's OnSaveHandler is invoked
    itemContext = dataForm.Controls.FindControlRecursive<SaveButton>().ItemContext;
}

void Page_Load(object sender, EventArgs e)
{
    if (itemContext.FormContext.FormMode == SPControlMode.New ||
        itemContext.FormContext.FormMode == SPControlMode.Edit)
    {
        itemContext.FormContext.OnSaveHandler += OnSaveHandler;
    }
}

void OnSaveHandler(object sender, EventArgs eventArgs)
{
    // TODO: Add your code before saving the item
    SaveButton.SaveItem(saveButton.ItemContext, false, string.Empty);
    // TODO: Add your code after saving the item
}

FindControlRecursive()扩展实现是

public static class ControlExtensions
{
    public static TControl FindControlRecursive<TControl>
    (
        this ControlCollection controls
    ) where TControl : Control
    {
        if (controls != null)
        {
            foreach (Control control in controls)
            {
                var foundControl = control as TControl 
                    ?? control.Controls.FindControlRecursive();
                if (foundControl != null)
                {
                    return foundControl;
                }
            }
        }
        return null;
    }
}