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

C# 覆盖自定义表单模板中的SharePoint:SaveButton,c#,asp.net,sharepoint-2010,overriding,C#,Asp.net,Sharepoint 2010,Overriding,首先让我澄清一下,并发表一些文章,其中已经解释了如何覆盖SaveButton: 我已经阅读并理解了这些内容,但我不知道如何在我的具体案例中充分实施这些内容: 我有一个自定义渲染模板CustomRender,其中包括真实表单。真实表单的代码在以下几行中显示: <%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBa

首先让我澄清一下,并发表一些文章,其中已经解释了如何覆盖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>
现在我只是不知道如何在我的另一个模板中注册这个模板。我能不能不在模板的代码隐藏中覆盖SaveButton?我将如何做到这一点并在以后引用它

选项一:表单RealForm.ascx.cs的代码隐藏-我可以把覆盖方法放在那里吗?我如何在表单中引用按钮?我如何获取? 选项二:仅针对按钮的另一个模板,例如SaveButton.ascx-我如何通过引用该模板,即当通过功能部署时,我如何知道PublicKeyToken等。这里也是一样:我的目标是对表单进行某种控制。
执行此操作时,您正在创建一个新的服务器控件,因此需要在页面上或在本例中在template.ascx文件中注册新控件

<%@ Register TagPrefix="MyPrefix" Namespace="ControlNamespace" Assembly="MyFullyQualifiedAssembly" %>
现在,您应该可以将表单上的“保存”按钮替换为以下内容:

<MyPrefix:NewSaveButton runat="server"></MyPrefix:NewSaveButton>
您基本上是按照asp.net的规则创建一个新的服务器控件,这里没有特定于sharepoint的内容


有关更多信息,请查看此页面:

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

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