【原创】如何在DataFormWebPart中嵌入自定义控件[How to embeded custom control in DFWP]

DataFormWebPart(DFWP)控件在SharePoint中自带的广泛使用数据展现控件,内部通过定义数据源以及XSLT定义数据的展现形式,并对数据进行相应的控制。在SharePoint Designer中,在Code视图中以及Designer视图可以对其进行配置,这给了我一个错觉:我以为DataFormWebPart允许将自定义控件插入到其内部。

我将我的自定义控件加入到DataFormWebPart中的某个位置

<Only:savebuttonex runat="server" IsClientRedirect="true" RedirectMessage="数据成功保存" ControlMode="New" id="savebutton1" />

但当我这样做的时候,其结果是:

image

我晕,SharePoint Designer直接就崩溃鸟~~~~

好吧,看来是我的自定义控件加入到DataFormWebPart中引发的崩溃,那我就试着用XSLT的方式来加入控件

<xsl:element name="Only:SaveButtonEx">
    <xsl:attribute name="runat">server</xsl:attribute>
    <xsl:attribute name="RedirectMessage">data is saved</xsl:attribute>
    <xsl:attribute name="IsClientRedirect">true</xsl:attribute>
    <xsl:attribute name="ControlMode">New</xsl:attribute>
    <xsl:attribute name="id">btnSave</xsl:attribute>
</xsl:element>

这回来了,SPD不于崩溃了,但是在Design视图显示的是:

image

从提示上看到,原来是DataFormWebPart中的XSLT中没有名称空间,顺藤摸瓜找到DataFormWebPart中定义名称空间的位置,在xsl:stylesheet中加入我控件的命名空间:

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" 
xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal"
xmlns:Only="Only.SPLibraryExtend.WebControls">

再看Design视图:

image

终于显示出来了,大功告成了吗?让我们来在浏览器中看一下:

image

提示的是我自定义的标签未能解析,我仔细了看了源码,在上面我明明写了<%@ Register tagprefix="Only" namespace="Only.SPLibraryExtend.WebControls" assembly="SPLibraryExtend, Version=1.0.0.0, Culture=neutral, PublicKeyToken=77c9affec54a974f" %>,怎么会找不到呢?另外,如果真的是我源码中未定义Only:SaveButtonEx,那么页面的Design视图应该也会有问题啊?事情再次陷入僵局,我仔细了想了一下,如果在设计视图没有问题,而在运行时有问题,那肯定就是DataFormWebPart的运行时处理上出现了问题,所以又回到DataFormWebPart上,好吧,用反编译工具看一下它的代码,我看到下面的代码就惊诧了

protected string[] _assemblyReferences = new string[] { "<%@ Register TagPrefix=\"SharePoint\" Namespace=\"Microsoft.Sharepoint.WebControls\" Assembly=\"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c\" %>", "<%@ Register TagPrefix=\"GroupBoard\" Namespace=\"Microsoft.SharePoint.Applications.GroupBoard.WebControls\" Assembly=\"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c\" %>" };

原来如此,DataFormWebPart在里面强制性的让其只引用两个TagPrefix,那我在整个页面中加入的根本就没起作用。_assemblyReferences 是一个Field,而且还是protected,另外更幸运的是,DataFormWebPart不是sealed,可以进行继承。好吧,那我就继承一个吧。

    [Designer(typeof(DataFormWebPartDesigner)), SupportsAttributeMarkup(true), XmlRoot(Namespace = "http://schemas.microsoft.com/WebPart/v2/DataView"), ParseChildren(true), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true)]
    public class DataFormWebPart : Microsoft.SharePoint.WebPartPages.DataFormWebPart
    {
        public DataFormWebPart():base()
        {
            _assemblyReferences = new string[] { 
                "<%@ Register TagPrefix=\"SharePoint\" Namespace=\"Microsoft.Sharepoint.WebControls\" Assembly=\"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c\" %>", 
                "<%@ Register TagPrefix=\"GroupBoard\" Namespace=\"Microsoft.SharePoint.Applications.GroupBoard.WebControls\" Assembly=\"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c\" %>",
                "<%@ Register TagPrefix=\"Only\" Namespace=\"Only.SPLibraryExtend.WebControls\" Assembly=\"SPLibraryExtend, Version=1.0.0.0, Culture=neutral, PublicKeyToken=77c9affec54a974f\" %>"
            };
        }
    }

我在构造函数中对_assemblyReferences 进行了重新定义,加入了我自己控件的TagPrefix。

同样,修改SharePoint Designer中对于DataFormWebPart的标签,使其指到我自己的控件上。这样操作以后,我又尝试将XSLT定义的SaveButtonEx控件重新改回<Only:SaveButton runat="server" IsClientRedirect="true" RedirectMessage="数据成功保存" ControlMode="New" id="savebutton1"/>,发现SPD也不再崩溃了。

运行起页面,看一下效果:

image

展现没有问题,SaveButtonEx控件是上篇文章中写的控制客户端跳转的,看一下效果:

image

大功告成~~

SaveButtonEx的实现请参见:http://www.cnblogs.com/fxwdl/archive/2012/08/30/2663093.html

posted @ 2012-08-30 10:12  吴东雷  阅读(776)  评论(0编辑  收藏  举报