随笔 - 79  文章 - 1 评论 - 778 trackbacks - 105
<2008年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

camlquery 类库下载:
 http://www.codeplex.com/camlquery
SPCAMLEditor 下载:
 http://www.codeplex.com/SPCAMLEditor

与我联系

搜索

 

留言簿(27)

我参与的团队

随笔分类(68)

My Friends

SilverLight

wss

积分与排名

  • 积分 - 87901
  • 排名 - 461

最新随笔

最新评论

阅读排行榜

评论排行榜

   sharepoint表单定制已经连续写了三篇文章:
WSS3.0开发--页面定制(1)--修改列表的表单页面
WSS页面定制系列(1)--如何启用表单页面的编辑模式
WSS页面定制系列(2)---定制单个列表的表单页面
按照计划,本篇应该讲述使用用用户控件定制表单了。

    用用户控件定制表单的原理很简单:
    用户控件里放置表单控件,然后采用QuickPart类似的机制来加载这个控件,并且设置表单控件的上下文信息。具体的实现机制以后讲述。

    这里为简化大家的工作,发布一个写好的WebPart--SmartFormWebPart,SmartForm整合了前面几篇文章提到的模板定制方式和用户控件定制方式。
在文章后面可以找到下载链接。

    为什么叫SmartForm呢? 这个名字含义是:你可以写一个简单的用户控件,然后利用wss的功能,自动实现数据的增加,修改,查看,
简单的表单用户控件依靠wss实现了智能化~

SmartForm的使用介绍

    SmartForm 通过加载模板文件,使sharepoint的列表表单页面可以按照我们的需要显示成任意的样子.
    表单保存后,可以转向默认页面或者是指定的页面.

    SmartForm支持两种模板文件:

    1)通过RenderingTemplate,这种方式定制后的表单可以放到任何地方,包括表单页面,站点首页。但是不能内嵌代码。

    2)通过UserControl,这种方式定制的表单只能放到表单页面(Dispform.aspx,EditForm.aspx,NewForm.aspx), 用户控件内可以内嵌代码,写一些判断逻辑。

使用方法:

1)将SmartForm.dll加入gac.

2)添加SafeControl
修改站点的web.config文件,在SafeControls节点下添加以下配置:
<SafeControl Assembly="SmartForm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=aff738ac50c8cf48" Namespace="CodeArt.SharePoint.SmartForm" TypeName="*" Safe="True" />

3)将SmartFormWebPart添加到站点
网站操作菜单->网站设置->web部件->新建->选中CodeArt.SharePoint.SmartForm.SmartFormWebPart,导入.

4)现在你可以到需要修改的页面,添加SmartFormWebPart了.

如果你发现表单页面没办法修改,请参考这篇文章--WSS页面定制系列(1)--如何启用表单页面的编辑模式

下面演示一下两种模板文件的开发和配置.

RenderingTemplate的使用.

用一个现实中的需求: 客户希望把某个调查直接放到页面上,这样,浏览用户就不需要点击链接转到另一个页面去填写调查而直接就可以在首页填写.

1)新建一个调查列表,名称为"SmartForm调查",并添加一个调查问题:关于SmartForm的调查
键入两个选项:
您需要SmartForm吗?
您认为SmartForm还有哪些需要改进的地方?

2)编写RenderingTemplate
把以下内容保持到"12\TEMPLATE\CONTROLTEMPLATES\CodeArt_SurveyRenderingTemplate.ascx
<%@ Control Language="C#" AutoEventWireup="false" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %><%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Namespace
="Microsoft.SharePoint.WebControls" %>
    
<SharePoint:RenderingTemplate ID="HomeSurveyForm" runat="server">
    
<Template>
        
<TABLE class="ms-formtable" style="margin-top: 8px;" border=0 cellpadding=0 cellspacing=0 width=100%>
        
<SharePoint:SurveyFieldIterator ID="SurveyFieldIterator1" runat="server"/>
        
</TABLE>
         
<div align="center">
         
<asp:Button runat="Server" ID="btnSave" Text="提交" CommandName="SaveItem" />
         
</div>
    
</Template>
</SharePoint:RenderingTemplate>

2)重启IIS

3)在首页添加SmartFormWebPart.


4)在SmartFormWebPart的杂项属性面板,设置以下属性:
列表名称为:    SmartForm调查
呈现模板ID为:    HomeSurveyForm
提交后重定向Url为:    /
提交后显示信息为:    感谢您填写此调查!


5)保存,刷新页面,可以看到效果了.

用户控件的使用.

假设我们要修改通知列表,使它的字段重新排列

1)开发用户控件

用户控件没有特殊的要求,注意一下几点:
  • 用FormField来呈现某个字段,
  • 用ListFieldIterator来呈现所有的字段.
  • 如果要实现保存功能,必须有一个按钮控件,可以是Button,ImageButton,LinkButton,控件的CommandName必须为SaveItem
将以下内容保存为CodeArt_NoticeControlTemplate.ascx
<%@ Control Language="C#" AutoEventWireup="false" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %><%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Namespace
="Microsoft.SharePoint.WebControls" 
%>
通知主题:
<SharePoint:FormField  ID="FormField1" runat="server" FieldName="Title" />
通知内容:                    
<SharePoint:FormField ID="FormField2" runat="server" FieldName="Body" />
<hr />
<div>              
 
<asp:Button runat="server" ID="saveButton" CommandName="SaveItem" Text=" 保存 "></asp:Button>
  
<input type="button" value=" 返回 " onclick="history.back()" />                 
</div>

2)到某个通知列表的新建页面(NewForm.aspx),进入设计模式.

3)添加SmartFormWebPart,并设置它的属性:

模板控件路径为:~/_CONTROLTEMPLATES/CodeArt_NoticeControlTemplate.ascx
控件模式选择:New

此时,列表名称属性不需要指定,控件自动获取当前列表。

4)保存,可以看效果了.


5)如果要修改查看,编辑页面,请按照同样的步骤操作,不同的是,在查看页面,控件模式需要选择Display,在编辑页面,控件模式选择Edit

6)用户控件里面可以嵌入代码,甚至,使用code-behind也是可以的.
假设,我们要校验通知主题中不能包含一些脏字,并且,要控制那个保存按钮在查看页面不显示,可以这么写:
<%@ Control Language="C#" AutoEventWireup="false" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Namespace
="Microsoft.SharePoint.WebControls" 
%>
    
<script runat="server">        
        protected override 
void OnLoad(EventArgs e)
        
{
            base.OnLoad(e);
            
if (Microsoft.SharePoint.SPContext.Current.FormContext.FormMode == SPControlMode.Display)
                
this.saveButton.Visible = false;
        }
    
        protected override bool OnBubbleEvent(object source, EventArgs args)
        
{
            string title 
= "" + FormField1.Value;
            
if (title.IndexOf("fuck", StringComparison.OrdinalIgnoreCase) != -1)
            
{
                
throw new Microsoft.SharePoint.SPException("您输入的主题不合法,不能包含[fuck]");
                
return true;
            }
            
            
return base.OnBubbleEvent(source, args);
        }
   
    
    
</script>
通知主题:
<SharePoint:FormField  ID="FormField1" runat="server" FieldName="Title" />
通知内容:                    
<SharePoint:FormField ID="FormField2" runat="server" FieldName="Body" />
<hr />
<div>              
 
<asp:Button runat="server" ID="saveButton" CommandName="SaveItem" Text=" 保存 "></asp:Button> 
  
<input type="button" value=" 返回 " onclick="history.back()" />                 
</div>


用用户控件来定制列表表单,你可以做任意操作,做什么只受限于你的思维~

备注:
SmartForm实现的两种方式的模板,用户控件模板优先级大于RenderingTemplate,即,如果同时指定了"呈现模板ID"和"模板控件路径",则"模板控件路径"起作用.

下载试用 : http://files.cnblogs.com/jianyi0115/SmartFormWebPart.zip

 

压缩包中包括dll和两个示例模板文件,可以单击里面的deploy.cmd文件实现自动注册GAC和copy模板文件,但是SafeControl仍然需要手工修改。

后记:

SmartFormWebPart当前不支持在非列表页面(DispForm.aspx,EditForm.aspx,NewForm.aspx)使用控件模板,在首页这种地方只能使用RenderingTemplate。

posted on 2008-03-15 23:58 jianyi 阅读(1777) 评论(86)  编辑 收藏 所属分类: Sharepoint

FeedBack:
#1楼  2008-03-16 23:59 RenYong [未注册用户]
很棒的东西,下下来明天研究一下
谢谢分享
  回复  引用    
#2楼  2008-03-17 17:33 geng [未注册用户]
楼主的东西都是精华,谢谢
  回复  引用    
#3楼  2008-03-19 15:11 songcan      
老大就是老大,老大我用SmartQueryWebPart的时候,用覆载QueryExpression的方式查询时,当输入框的字串为时间格式的字符串的时候(列表字段类型为DATETIME)如"2008-3-19",或"2008/3/19"的时候查询结果为<!-- #渲染失败 --> 请问老大,问题出现在哪里?
  回复  引用  查看    
#4楼 [楼主] 2008-03-19 18:14 jianyi0115      
@songcan
有些字段是不能用于查询的,如链接,带菜单的标题字段等,时间格式字段我试过是可以的啊。估计是格式的问题。你用
TypedQueryField<DateTime> dt= new QueryField<DateTime>("时间", false);
return dt<= DateTime.Now ;

试试。

  回复  引用  查看    
#5楼  2008-03-20 08:50 songcan      
老大TypedQueryField<DateTime> dt= new QueryField<DateTime>("时间", false);这个我试过也是不行的"2008-3-19",或"2008/3/19"的时候查询结果为<!-- #渲染失败 --> 不知问题出在哪里,请帮忙看看,谢谢!

我的代码
=========================================
public override CamlExpression QueryExpression
{
get
{
CamlExpression expr = null;

TypedQueryField<string> title = new TypedQueryField<string>("标题", false);

TypedQueryField<string> LeaderSugg = new TypedQueryField<string>("领导意见", false);

//QueryField Content= new QueryField("内容", false);
//QueryField Date= new QueryField("日期", false);

TypedQueryField<DateTime> dt = new TypedQueryField<DateTime>("日期", false);

TypedQueryField<string> Author = new TypedQueryField<string>("创建者", false);
if (txtTitle.Text != "")
expr = title.Contains(txtTitle.Text.Trim());

if (txtLeaderSugg.Text != "")
expr = Append(expr, LeaderSugg.Contains(txtLeaderSugg.Text.Trim()));

//if (txtContent.Text != "")
// expr = Append(expr, Content.Contains(txtContent.Text));

if (txtDate.Text != "")
expr = Append(expr, dt.Contains(DateTime.Parse(txtDate.Text.Trim()).Date));

//if (txtAuthor.Text != "")
// expr = Append(expr, Author.Contains(txtAuthor.Text));
//ArrayList list = PeopleEditor1.ResolvedEntities;
//获取id和显示名称
//foreach (Microsoft.SharePoint.WebControls.PickerEntity p in list)
//{
// string userId = p.EntityData["SPUserID"].ToString();
// string DisplayName = p.EntityData["DisplayName"].ToString();
//}
//获取帐号
//ArrayList selectedAccoutList = PeopleEditor1.Accounts;
string selectedAccouts2 = PeopleEditor1.CommaSeparatedAccounts;
if (selectedAccouts2 != "")
expr = Append(expr, Author.Contains(selectedAccouts2));
return expr;
}
}
  回复  引用  查看    
#6楼 [楼主] 2008-03-20 09:31 jianyi0115      
@songcan
时间不能Contain吧:
if (txtDate.Text != "")
expr = Append(expr, dt.Contains(DateTime.Parse(txtDate.Text.Trim()).Date)); ,你用>或<试一下。
另外:
string selectedAccouts2 = PeopleEditor1.CommaSeparatedAccounts;
if (selectedAccouts2 != "")
expr = Append(expr, Author.Contains(selectedAccouts2));
这样不行的,你要把多个帐号分开来Contains。
  回复  引用  查看    
#7楼  2008-03-21 08:48 笨笨丁      
Hi jianyi0115
当我添加这个控件,并单击控件上的"打开工具窗格"链接时总是报: access resource file [mcswp] error,please confirm files in App_GlobalResources. 请赐教!
十分谢谢!
  回复  引用  查看    
#8楼 [楼主] 2008-03-22 00:31 jianyi0115      
@笨笨丁
不会吧~~是SmartForm吗 ?
  回复  引用  查看    
#9楼 [楼主] 2008-03-22 00:34 jianyi0115      
@笨笨丁
旧的代码写过这个异常信息,但是有关的代码都去掉了,又测了一下,没问题啊
  回复  引用  查看    
#10楼  2008-03-24 18:06 笨笨丁      
Hi jianyi0115,
采用第二种方式:通过UserControl,添加smartForm控件,当单击 edit--> modify shared web part后报如下错误:
Failed to get value of the "Attachments" column from the "Attachments" field type control. See details in log. Exception message: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), 我附加进程调试,好似在调用BaseSPWebPart里的OnUnload后出错,你经验丰富,请帮助看看!
  回复  引用  查看    
#11楼  2008-03-24 18:08 笨笨丁      
我看C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS下的日志,但没有找到相应的关键字!希望给与指导!
  回复  引用  查看    
#12楼  2008-03-24 18:43 笨笨丁      
Hi jianyi0115,
我在日历里使用出上面的错误,但在任务列表里使用就没有问题!很迷惑!
  回复  引用  查看    
#13楼 [楼主] 2008-03-24 20:10 jianyi      
@笨笨丁
你还没有设置用户控件路径就出那个错误??
你试一下系统默认的那个表单webpart修改属性时是否也出错。
SmartForm加载UserControl也不是适合所有表单的,如:日历的编辑页面因为某些字段会引起页面回发,就出错了。相对的,用RenderingTemplate就可以。
  回复  引用  查看    
#14楼  2008-03-25 01:45 lsgonglu [未注册用户]
想实现如下目的,应当怎样做?

选择任一列表项,SmartFormWebPart中都显示相对应的编辑模式。
  回复  引用    
#15楼 [楼主] 2008-03-25 09:44 jianyi      
@lsgonglu
认真看一下SmartFormWebPart的属性面板, 有个FormMode属性,设置为Edit即可
  回复  引用  查看    
#16楼  2008-03-25 12:38 lsgonglu [未注册用户]
看到了FormMode属性,也设置了为Edit,但只能手动给列表项ID赋值!不知道不有能改进一下。
  回复  引用    
#17楼 [楼主] 2008-03-25 13:27 jianyi      
@lsgonglu
ID可以不赋值,若ID<=0时会自动从上下文获取,我回家再测试一下。
  回复  引用  查看    
#18楼 [楼主] 2008-03-25 22:36 jianyi      
@笨笨丁
关于出现“Failed to get value of the "Attachments" column from the "Attachments" field type control. See details in log. Exception message: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)”问题的解决方法:
在添加SmartForm之前先关闭掉页面上原有的ListFormWebPart。问题即可解决。此问题应该是在同一个页面上两个webpart产生冲突造成的。
  回复  引用  查看    
#19楼 [楼主] 2008-03-25 22:39 jianyi      
@lsgonglu
列表项ID为0时,SmartForm会自动获取当前项的ID,已经测试过了。代码重新梳理了一下,欢迎试用最新的版本:http://www.cnblogs.com/Files/jianyi0115/SmartForm.zip
  回复  引用  查看    
#20楼  2008-04-02 13:39 eyes [未注册用户]
我在webpart里面加入了一个SPGridView,在某个TemplateField中的HeaderTemplate里面加了一个CheckBox控件,我把这个控件的AutoPostBack设成True,当这个CheckBox的Checked从false变成true的时候可以正常触发CheckedChange事件,但是从true变成false的时候就触发不了了,楼主知道为什么吗?~~~
  回复  引用    
#21楼  2008-04-02 17:32 songcan      
请教老大SHAREPOINT与USB KEY的集成问题,现在SHAREPOINT的认证方式为WINDOWS认证,我需要做的事USB KEY显示为有效用户后再通过用户名/口令的方式登录SHAREPOINT,用户名/口令通过后才能登录,现在没有一点头绪,不知道对WINDOWS认证方式的登录如何拦截,请老大施予援手,我想问一下老大如果采用FORM认证的方式SHAREPOINT与USB KEY的集成问题,是否更容易 一些?谢谢!
  回复  引用  查看    
#22楼 [楼主] 2008-04-02 20:17 jianyi      
@songcan
首先搞清楚你的 USB KEY是否支持跟AD的 集成 ,如果支持那么采用原先认证方式即可。若不支持,则只能采用Form认证,USB KEY应该提供调用组件 ,比如ActiveX,在登录页面用JS首先调用一下再正常认证即可...
  回复  引用  查看    
#23楼  2008-04-02 22:28 songcan      
非常感谢老大的帮助,USB KEY是否支持跟AD的 集成这个我说不清楚,我刚刚才接触这个东东,我们有一个Sharepoint的网站出于客户的要求
必需使用usb key来验证客户的合法性,USB KEY了提供调用组件好像就是activex的,Sharepoint的网站采用WINDOWS认证,现在确定不能修改认证方式,每次登陆
  回复  引用  查看    
#24楼  2008-04-02 22:33 songcan      
每次登陆网站的时候都会弹出WINDOWS对话框要求输入密码,但那个对话框好像是WINDOWS自带的没法控制,我现在的想法是在弹出
WINDOWS对话框前进行验证,但找不到方法,假如采用Form认证,我们很多的地方都用到了AD,很多功能跟AD相关,而且Sharepoint好像有的功能在Form认证也无法使用。所以现在甚是头痛
  回复  引用  查看    
#25楼 [楼主] 2008-04-03 00:01 jianyi      
@eyes
关于SPGridView,我在页面上试了下,没问题啊,注意控件的生命周期,尽量早的创建控件:
<cc1:SPGridView ID="SPGridView1" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox runat="Server" ID="dd" AutoPostBack="true" />
</HeaderTemplate>
<ItemTemplate>
d
</ItemTemplate>
</asp:TemplateField>
</Columns>
</cc1:SPGridView>
  回复  引用  查看    
#26楼 [楼主] 2008-04-03 00:05 jianyi      
@songcan
你的功能只能用Form认证!即使基于AD,也不需要写很多代码的,研究一下MOSS的身份认证机制吧...
  回复  引用  查看    
#27楼  2008-04-03 08:59 eyes [未注册用户]
@jianyi
那个SPGridView我是在后台代码里面写的~~没有aspx页面~~实际上我是想做一个全选和取消全选的功能,即当点一下Header的CheckBox时,让所有Rows的CheckBox都选中,而再点一下,让所有Rows的CheckBox取消选中。。。但是现在只能全选,不能取消全选,我调试看过,Header里的CheckBox由True变为False的时候根本没有走CheckedChange的代码。。。也就是没有触发事件。。。现在唯有用RadioButtonList来代替。。不过看上去比较丑陋。。还是希望能解决CheckBox的问题。。。
  回复  引用    
#28楼  2008-04-03 09:45 songcan      
老大我只想在IE弹出输入密码和对话框之前或之后加入一些自定义的逻辑,如果使用
FORM认证,例如工作流之类的还可以使用吗?
  回复  引用  查看    
#29楼 [楼主] 2008-04-03 10:10 jianyi      
@songcan
认证方式跟具体的功能没有关系。。。
  回复  引用  查看    
#30楼  2008-04-03 10:52 songcan      
老大,那么采用FORM认证,但我的用户来源是来源于AD,工作流的用户也是来源于AD,我不知道使用了FORM认证后工作流的功能是否还能用
  回复  引用  查看    
#31楼 [楼主] 2008-04-03 12:45 jianyi      
@songcan
你可以测试下--用代码将用户名和密码发送到AD认证---你要去了解一下MOSS的身份认真机制,然后将它重新实现,可能有点难度的. 理论上改认真方式不会影响到工作流的.毕竟工作流的功能是用系统帐号运行的啊.
  回复  引用  查看    
#32楼  2008-04-03 13:51 songcan      
多谢老大不厌其烦的帮我解答问题,非常感谢!
你要去了解一下MOSS的身份认真机制,然后将它重新实现,可能有点难度的
这个对我来说难度不小,无论功力还是时间都差远了,我要完成的这个功能很急
,我不是专搞MOSS,MOSS只有很少时间看!我现在的一个想法是启用匿名访问,再HTTPMOUDLE里面判断是否已登录,如未登录转到自定义登录页面,再在登录页模拟WINDOWS认证登录应用,请问这样有可能实现吗?或是还有其他办法
  回复  引用  查看    
#33楼 [楼主] 2008-04-03 15:52 jianyi      
@songcan
可以按照这个方法试一下,但是启用匿名之后会不会对一些功能造成影响是不能确定的.
  回复  引用  查看    
#34楼  2008-04-03 17:31 songcan      
是的老大,但我想不出好办法,假如能够自己实现WINDOWS认证就好了
  回复  引用  查看    
#35楼 [楼主] 2008-04-03 23:56 jianyi      
@songcan
你可以参考这篇文章:
http://www.windwhisper.cn/article.asp?id=14
  回复  引用  查看