【原创】如何在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" />
但当我这样做的时候,其结果是:
我晕,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视图显示的是:
从提示上看到,原来是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视图:
终于显示出来了,大功告成了吗?让我们来在浏览器中看一下:
提示的是我自定义的标签未能解析,我仔细了看了源码,在上面我明明写了<%@ 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也不再崩溃了。
运行起页面,看一下效果:
展现没有问题,SaveButtonEx控件是上篇文章中写的控制客户端跳转的,看一下效果:
大功告成~~
SaveButtonEx的实现请参见:http://www.cnblogs.com/fxwdl/archive/2012/08/30/2663093.html