<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_jianyi</title><subtitle type="text">------CodeArt </subtitle><id>http://feed.cnblogs.com/blog/u/25153/rss</id><updated>2012-05-31T09:20:43Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/25153/rss"/><entry><id>http://www.cnblogs.com/jianyi0115/archive/2012/03/25/2416410.html</id><title type="text">QuickFlow之“我审批过的单据”</title><summary type="text">如何实现在工作流列表中只显示当前用户审批/参与过的项目？</summary><published>2012-03-25T03:07:00Z</published><updated>2012-03-25T03:07:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2012/03/25/2416410.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2012/03/25/2416410.html"/><content type="html">&lt;p&gt;&lt;strong&gt;1）需求概述&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在工作流列表中添加一个视图，显示当前用户审批过（参与过）的流程/单据&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）解决方案&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;增加一个多用户类型的栏WorkflowApprovers到列表，在流程的运行过程中，把所有任务的参与人增加到这个栏中，然后创建一个视图，用WorkflowApprovers过滤即可。&lt;/p&gt;&lt;p&gt;显然这是一个通用的功能，及任何流程的任何任务都需要这个处理逻辑， 在QuickFlow中，处理通用的流程逻辑可以通过实现WorkflowEventReceiver实现，&lt;/p&gt;&lt;p&gt;注意：这个WorkflowEventReceiver是QuickFlow的WorkflowEventReceiver，而不是MOSS内部的。&lt;/p&gt;&lt;p&gt;关于WorkflowEventReceiver，可以参考这篇文章：&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2009/09/15/1567324.html"&gt;http://www.cnblogs.com/jianyi0115/archive/2009/09/15/1567324.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）WorkflowEventReceiver的实现&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;创建一个&lt;strong&gt;强签名&lt;/strong&gt;类库，引用QuickFlow.dll，添加一个类，代码如下：&lt;/p&gt; public class ApproversWorkflowEventReceiver : QuickFlow.EventBus.WorkflowEventReceiver&lt;br/&gt;    {&lt;br/&gt;        const string Field_Name = "WorkflowApprovers";&lt;br/&gt;&lt;br/&gt;        const string Field_Xml = @"&amp;lt;Field Type='UserMulti' DisplayName='WorkflowApprovers' List='UserInfo' Required='FALSE'&lt;br/&gt;        ShowField='ImnName' UserSelectionMode='PeopleOnly' UserSelectionScope='0' Mult='TRUE' Sortable='FALSE' &lt;br/&gt;         StaticName='WorkflowApprovers' Name='WorkflowApprovers' /&amp;gt;";&lt;br/&gt;&lt;br/&gt;        public override void OnTaskCompleted(QuickFlow.EventBus.WorkflowEventProperties p)&lt;br/&gt;        {            &lt;br/&gt;            var taskUserAccount = p.TaskProperties.AssignedTo;&lt;br/&gt;            if (String.IsNullOrEmpty(taskUserAccount))&lt;br/&gt;                return;&lt;br/&gt;&lt;br/&gt;            if (p.WorkflowProperties.List.Fields.ContainsField(Field_Name) == false)&lt;br/&gt;            {&lt;br/&gt;                //throw new Exception("workflow list must have a multi-user field named Approvers");&lt;br/&gt;                p.WorkflowProperties.List.Fields.AddFieldAsXml(Field_Xml);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            var approvalUser = p.WorkflowProperties.Web.EnsureUser(taskUserAccount);&lt;br/&gt;            //approvalUser = p.TaskProperties.ExtendedProperties[WorkflowConstants.TaskUserIdentityPropertyName]&lt;br/&gt;&lt;br/&gt;            SPFieldUserValueCollection users = p.WorkflowProperties.Item[Field_Name] as SPFieldUserValueCollection;&lt;br/&gt;            if (users == null)&lt;br/&gt;            {&lt;br/&gt;                users = new SPFieldUserValueCollection();&lt;br/&gt;            }&lt;br/&gt;            else&lt;br/&gt;            {&lt;br/&gt;                foreach (SPFieldUserValue u in users)//用户已经存在，无需增加&lt;br/&gt;                {&lt;br/&gt;                    if (approvalUser.ID == u.LookupId)&lt;br/&gt;                        return;&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            users.Add(new SPFieldUserValue(p.WorkflowProperties.Web, approvalUser.ID, approvalUser.Name));&lt;br/&gt;&lt;br/&gt;            var root = ActivityUtil.GetRootActivity(p.Activity) as FlowchartWorkflow;&lt;br/&gt;            if (root != null)&lt;br/&gt;            {&lt;br/&gt;                root.DataFields[Field_Name] = users;&lt;br/&gt;                root.DataFields.Update();//强制更新&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }完整的示例代码 &lt;a title="下载" href="http://quickflow.codeplex.com/workitem/32483"&gt;下载&lt;/a&gt;&lt;p&gt;&lt;strong&gt;4）配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;step1:&lt;/strong&gt;将类库部署到GAC，修改global.config,增加Event配置：&lt;/p&gt;&amp;lt;GlobalConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br/&gt;  &amp;lt;EventReceivers&amp;gt;   &lt;br/&gt;    &amp;lt;Receiver Enabled="true" Name="ApproversWorkflowEventReceiver"&lt;br/&gt;            Type="ProjectName1.ApproversWorkflowEventReceiver,ProjectName1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628" /&amp;gt;&lt;br/&gt;      &amp;lt;/EventReceivers&amp;gt;&lt;br/&gt;&amp;lt;/GlobalConfiguration&amp;gt;&lt;p&gt;&lt;strong&gt;step2:&lt;/strong&gt;在列表中增加一个多选用户类型字段WorkflowApprovers。添加字段后，可以按照需要把WorkflowApprovers改为其他显示名&lt;/p&gt;&lt;p&gt;&lt;strong&gt;step3：&lt;/strong&gt;创建一个视图-我审批过的单据，设置过滤条件为 WorkflowApprovers = [本人]&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5)后记&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;最新版本QuickFlow(Build120325之后版本)已经集成了ApproversWorkflowEventReceiver，无需自己开发WorkflowEventReceiver，直接修改global.config即可：&lt;/p&gt;&amp;lt;EventReceivers&amp;gt;&lt;br/&gt;    &amp;lt;Receiver Enabled="true" Name="ApproversWorkflowEventReceiver"&lt;br/&gt;            Type="QuickFlow.EventBus.ApproversWorkflowEventReceiver,QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628" /&amp;gt;&lt;br/&gt;&amp;lt;/EventReceivers&amp;gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2416410.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2012/03/25/2416410.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/12/09/2282287.html</id><title type="text">SmartQuery WebPart 2.0 发布。</title><summary type="text">新版本提供了wsp安装包，不再需要以前的手工部署了.ListQueryWebpart功能增强</summary><published>2011-12-09T07:24:00Z</published><updated>2011-12-09T07:24:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/12/09/2282287.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/12/09/2282287.html"/><content type="html">&lt;p&gt;&lt;strong&gt;1）概述：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;SmartQuery 是一个列表查询组件，包含以下3部分：&lt;/p&gt;&lt;p&gt;1）查询类库，提供了查询SharePoint数据的友好的方式。详见：&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2008/02/04/1064636.html"&gt;http://www.cnblogs.com/jianyi0115/archive/2008/02/04/1064636.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;2）SmartQueryWebPart-可以添加到列表上方，对列表进行查询，通过一个外部的布局用户控件控制查询查询UI。 详见：&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2008/02/15/1070158.html"&gt;http://www.cnblogs.com/jianyi0115/archive/2008/02/15/1070158.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;2）ListQueryWebPart-同SmartQueryWebPart，只不过可以通过配置控制要查询那些字段。&lt;/p&gt;&lt;p&gt;ListQueryWebPart最早由 [&lt;a title="木头人" href="http://www.cnblogs.com/dreamnan/archive/2010/06/21/listquerywebpart.html" target="_blank"&gt;木头人&lt;/a&gt;] 开发，新版本对其进行了优化。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）新版本增强了什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;新版本提供了wsp安装包，不再需要以前的手工部署了,具体安装方式见安装包中的SmartQuery_Manual.txt&lt;/p&gt;&lt;p&gt;SmartQueryWebPart的功能没有改变。&lt;/p&gt;&lt;p&gt;ListQueryWebPart更好的结合2010的UI，不只是可以查询当前视图的字段，而且可以查询整个列表的字段。UI布局得到优化。&lt;/p&gt;&lt;p&gt;下载地址：&lt;a href="http://camlquery.codeplex.com/"&gt;http://camlquery.codeplex.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）安装新版本注意事项&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;--如果已经用了老版本的ListQueryWebPart，则安装新版本后，在激活CodeArt SmartQuery功能前，需要到webpart库中删除旧的2个SmartQueryWebPart.webpart或ListQueryWebPart.dwp文件，&lt;/p&gt;&lt;p&gt;激活CodeArt SmartQuery后，界面上已经添加的所有ListQueryWebPart必须删除，然后重新添加。&lt;/p&gt;&lt;p&gt;--SmartQueryWebPart功能不受影响。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）ListQueryWebPart使用效果&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;ListQueryWebPart的功能已经得到了很大增强，建议一般的查询直接用ListQueryWebPart配置下即可，不需要用SmartQueryWebPart然后编写布局文件。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;激活Feature：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/21594/2011120919171148.jpg" alt="" width="800" height="318" /&gt;&lt;/p&gt;&lt;p&gt;添加webpart：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/21594/2011120915172040.jpg" alt="" width="800" /&gt;&lt;/p&gt;&lt;p&gt;设置查询字段：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/21594/2011120915174394.jpg" alt="" width="869" height="400" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2282287.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/12/09/2282287.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/12/08/2280791.html</id><title type="text">Switch View when host XmlFormView in aspx</title><summary type="text">当把XmlFormView放到自己的aspx页面的时候，可能需要切换视图的逻辑，比如当流程绑定到表单库的时候，QuickFlow的FormServiceFormTask页面会按照任务活动的TaskFields中的__CurrentView字段来切换视图。XmlFormView本身提供2个方法：XmlViewer.XmlForm.ViewInfos.SwitchView("Approval")XmlViewer.XmlForm.ViewInfos.Initial = XmlViewer.XmlForm.ViewInfos["Approval"]但这两个方法</summary><published>2011-12-08T07:11:00Z</published><updated>2011-12-08T07:11:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/12/08/2280791.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/12/08/2280791.html"/><content type="html">&lt;p&gt;当把XmlFormView放到自己的aspx页面的时候，可能需要切换视图的逻辑，比如当流程绑定到表单库的时候，QuickFlow的FormServiceFormTask页面会按照任务活动的TaskFields中的__CurrentView字段来切换视图。&lt;/p&gt;&lt;p&gt;XmlFormView本身提供2个方法：&lt;/p&gt;&lt;p&gt;XmlViewer.XmlForm.ViewInfos.SwitchView("Approval")&lt;/p&gt;&lt;p&gt;XmlViewer.XmlForm.ViewInfos.Initial = XmlViewer.XmlForm.ViewInfos["Approval"]&lt;/p&gt;&lt;p&gt;但这两个方法或者出错，或者没用。&lt;/p&gt;&lt;p&gt;找到的最合理的方式是采用js切换，参考&amp;nbsp;&lt;a href="http://www.moss2007.be/blogs/vandest/archive/2008/10/10/forms-server-xmlformview-and-setting-the-initialview-on-load.aspx"&gt;http://www.moss2007.be/blogs/vandest/archive/2008/10/10/forms-server-xmlformview-and-setting-the-initialview-on-load.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;但这样会造成页面二次刷新。&lt;/p&gt;&lt;p&gt;没办法用Reflect分析代码，找到这个用反射设置视图的方法：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）for SharePoint2007&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;void SwitchView12(string viewName)&lt;br/&gt;        {&lt;br/&gt;            if (String.IsNullOrEmpty(viewName))&lt;br/&gt;                throw new ArgumentNullException("viewName");&lt;br/&gt;&lt;br/&gt;            //check view exist.&lt;br/&gt;            object viewInfo = null;&lt;br/&gt;&lt;br/&gt;            try&lt;br/&gt;            {&lt;br/&gt;                viewInfo = this.XmlViewer.XmlForm.ViewInfos[viewName];&lt;br/&gt;            }&lt;br/&gt;            catch { }&lt;br/&gt;&lt;br/&gt;            if (viewInfo == null)&lt;br/&gt;            {&lt;br/&gt;                throw new NotSupportedException("view doesn't exist:" + viewName);&lt;br/&gt;                return;&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            //利用反射控制  this.XmlViewer.XmlForm.Document.CurrentViewName&lt;br/&gt;            System.Reflection.PropertyInfo pDocument = this.XmlViewer.XmlForm.GetType().GetProperty("Document", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);&lt;br/&gt;            if (pDocument == null)&lt;br/&gt;            {&lt;br/&gt;                throw new NullReferenceException("can't get property XmlForm.Document");&lt;br/&gt;                return;&lt;br/&gt;            }&lt;br/&gt;            object objDoc = pDocument.GetValue(this.XmlViewer.XmlForm, null);&lt;br/&gt;            if (objDoc == null)&lt;br/&gt;            {&lt;br/&gt;                throw new NullReferenceException("can't get value: XmlForm.Document");&lt;br/&gt;                return;&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            //objDoc.CurrentView = objDoc.Solution.Views[this._xmlFormHost.ViewInfos.Default.Name];&lt;br/&gt;&lt;br/&gt;            System.Reflection.PropertyInfo pCurrentView = objDoc.GetType().GetProperty("CurrentView");&lt;br/&gt;            //Debug("CurrentView: " + pCurrentView);&lt;br/&gt;&lt;br/&gt;            System.Reflection.PropertyInfo pSolution = objDoc.GetType().GetProperty("Solution");&lt;br/&gt;            //Debug("pSolution: " + pSolution);&lt;br/&gt;&lt;br/&gt;            object objSolution = pSolution.GetValue(objDoc, null);&lt;br/&gt;            //Debug("objSolution: " + objSolution); &lt;br/&gt;&lt;br/&gt;            IDictionary views = objSolution.GetType().GetProperty("Views", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(objSolution, null) as IDictionary;&lt;br/&gt;            //Debug("views: " + views); &lt;br/&gt;&lt;br/&gt;            object v = views[viewName];&lt;br/&gt;            //Debug("v: " + v); &lt;br/&gt;&lt;br/&gt;            pCurrentView.SetValue(objDoc, v, null);&lt;br/&gt;        }&lt;br/&gt;&lt;/div&gt;&lt;p&gt;此方法在OnInitlized方法中调用。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）for SharePoint2010&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;以上方法在2010上应该也是可以的，但2010提供了一个更方便的方法：XmlFormView.DefaultView,&lt;/p&gt;&lt;p&gt;bool SwitchView14(string viewName)&lt;br /&gt; {&lt;br /&gt; var pDefaultView = XmlViewer.GetType().GetProperty("DefaultView");//只能在DataBind之前设置&lt;/p&gt;&lt;p&gt;//DefaultView属性可能是公共方法，这样就不必用反射了，但笔者是在2007下实现的这段代码，所以必须用反射&lt;br /&gt; if (pDefaultView == null)&lt;br /&gt; return false;&lt;br /&gt; pDefaultView.SetValue(XmlViewer, viewName, null);&lt;br /&gt; return true;&lt;br /&gt; }&lt;/p&gt;&lt;p&gt;这个方法不同的是：不能在OnInitlized方法中调用，必须在XmlFormView DataBind之前调用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2280791.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/12/08/2280791.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/10/21/2220530.html</id><title type="text">在SharePoint 2010上使用SharePoint Permission Extension</title><summary type="text">SharePoint Permission Extension是一个开源项目，扩展了SharePoint的权限控制体系，提供以下类型的权限控制： 列表字段权限—可以控制一个列表的某个字段的查看和编辑权限 视图权限—控制列表的视图的查看权限 内容类型的创建权限—如果列表由多个内容类型，则可以控制用户只能新建其中的几个（此功能实现的不完善，本文不做详细阐述） 如何部署下载最新版本wsp文件，地址：http://sppex.codeplex.com/解压后运行wsp_install安装解决方案到管理中心安装解决方案到应用程序到网站集功能管理中激活Feature字段权限的使用1）...</summary><published>2011-10-21T09:20:00Z</published><updated>2011-10-21T09:20:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/10/21/2220530.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/10/21/2220530.html"/><content type="html">&lt;p&gt;&lt;span style="color: black; font-size: 10pt;"&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;SharePoint Permission Extension&lt;/span&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;是一个开源项目，扩展了&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;SharePoint&lt;/span&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;的权限控制体系，提供以下类型的权限控制：&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: black; font-size: 10pt;"&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;列表字段权限&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&amp;mdash;&lt;/span&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;可以控制一个列表的某个字段的查看和编辑权限&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: black; font-size: 10pt;"&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;视图权限&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&amp;mdash;&lt;/span&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;控制列表的视图的查看权限&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: black; font-size: 10pt;"&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;内容类型的创建权限&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&amp;mdash;&lt;/span&gt;&lt;span style="font-family: 宋体; background-color: white;"&gt;如果列表由多个内容类型，则可以控制用户只能新建其中的几个（此功能实现的不完善，本文不做详细阐述）&lt;/span&gt;&lt;span style="font-family: Segoe UI; background-color: white;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="background-color: white;"&gt;如何部署&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;下载最新版本wsp文件，地址：&lt;a href="http://sppex.codeplex.com/"&gt;http://sppex.codeplex.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;解压后运行wsp_install安装解决方案&lt;/li&gt;&lt;li&gt;到管理中心安装解决方案到应用程序&lt;/li&gt;&lt;li&gt;&lt;div&gt;到网站集功能管理中激活Feature&lt;/div&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201110/201110211719197061.png" alt="" /&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="background-color: white;"&gt;字段权限的使用&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1）到列表设置中，找到Field Permission菜单，进入设置界面：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201110/201110211719226311.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;2）用非站点管理员账号测试：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201110/201110211719242572.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;3）用字段权限控制时，需要把 列表的数据视图功能禁用掉，要不然，用户通过数据视图还是可以修改任意字段。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="background-color: white;"&gt;视图权限的使用&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;1) 到列表设置中，找到View Permission菜单，进入设置界面：&lt;/div&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201110/201110211719264232.png" alt="" /&gt;&lt;/p&gt;&lt;div&gt;2)用非站点管理员账号测试：&lt;/div&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201110/201110211719294496.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201110/201110211719318282.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;3)在10下，虽然设置了试图权限，但是在视图选择列表中用户还是可以看到视图，点击视图后，出现禁止访问页面。&lt;/p&gt;&lt;p&gt;4)在07下，若无权限，视图选择列表中也是看不到的。&lt;/p&gt;&lt;p&gt;5)用视图权限的时候必须结合列表权限进行，即需要把普通用户修改视图，创建个人试图的权限去掉，要不然，虽然控制了视图的访问，但是用户&lt;/p&gt;&lt;p&gt;创建一个个人视图，还是可以看到数据。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #17365d; font-size: 16pt;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2220530.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/10/21/2220530.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/08/21/2147810.html</id><title type="text">QuickFlow之动态子流程</title><summary type="text">如何实现动态创建多个并行的子流程</summary><published>2011-08-21T06:18:00Z</published><updated>2011-08-21T06:18:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/08/21/2147810.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/08/21/2147810.html"/><content type="html">&lt;p&gt;&lt;strong&gt;1）动态子流程的场景&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;考虑以下工作流场景：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211417544534.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211417555482.png" alt="image" width="490" height="376" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;组长分配工作，指定接收人，每个接收人完成任务后组长立刻可以审批，不必等待其他组员。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）QuickFlow对子流程的支持&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;build110821 版本之后，QuickFlow提供了ChildWorkflow和FlowchartWorkflow活动，用来实现子流程。&lt;/p&gt;&lt;p&gt;ChildWorkflow提供顺序子流程模型，FlowchartChildWorkflow提供Flowchart类型的子流程支持。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3) 使用步骤&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3.1&lt;/strong&gt; 确保安装了build110821或之后的版本的wsp，如果在QFD工具箱中找不到ChildWorkflow，则修改QFD目录下的ToolboxItems.txt，添加如下两行：&lt;/p&gt;&lt;p&gt;QuickFlow.ChildWorkflow, QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628&lt;br /&gt;QuickFlow.FlowchartChildWorkflow, QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3.2&lt;/strong&gt; 将ChildWorkflow活动拖入设计器，将子活动添加到ChildWorkflow中，如果子活动的用户分配在各个子流程是一样的，则直接将User或Users属性绑定到工作流变量，或者设置角色名称。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3.3&lt;/strong&gt;如果子活动用户在各个子流程分支中不一样，则需要配置属性映射：&lt;/p&gt;&lt;p&gt;首先创建一个Names类型的工作流变量，这个变量用来存放各个子流程分支的用户，可以写死或者用过UI代码传递变量值。&lt;/p&gt;&lt;p&gt;然后，设置ChildWorkflow的ChildPropertiesMapping, 将需要动态分配用户的活动的User属性绑定到工作流变量。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）示例&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4.1&lt;/strong&gt; 画出如图所示的流程图&lt;/p&gt;&lt;p&gt;其中，组长分配工作，组员接受工作，组长审批工作都是Task活动&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211418121224.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211418163793.png" alt="image" width="635" height="487" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4.2&lt;/strong&gt;&amp;nbsp; 添加两个工作流变量： groupLeader， string类型，groupMembers, Names类型, 为了方便测试，可以设置groupLeader为一个账号，Names为多个账号，采用换行区分&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211418174533.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211418202284.png" alt="image" width="490" height="356" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4.3&lt;/strong&gt; 将组长分配工作和组长审批工作的User属性绑定到groupLeader&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4.4 &lt;/strong&gt;选中ChildWorkflow活动，将InitalChildData属性绑定到groupMembers，InitalChildData的值只能绑定到Names类型的变量，Names变量中包含几个值则对应会创建几个子流程&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4.5&lt;/strong&gt; 编辑ChildPropertiesMapping属性，添加一个映射，将组员接受工作活动的User属性绑定到 groupMembers变量，如下图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211418219187.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201108/201108211418227626.png" alt="image" width="469" height="341" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4.6&lt;/strong&gt; 发布流程，进行测试。&lt;/p&gt;&lt;p&gt;示例流程下载：&lt;/p&gt;&lt;p&gt;&lt;a href="https://skydrive.live.com/embedicon.aspx/QuickFlow/Examples/%e5%b9%b6%e8%a1%8c%e5%ad%90%e6%b5%81%e7%a8%8b.zip?cid=7f5a25cdf47d03e6&amp;amp;sc=documents" target="_blank"&gt;https://skydrive.live.com/embedicon.aspx/QuickFlow/Examples/%e5%b9%b6%e8%a1%8c%e5%ad%90%e6%b5%81%e7%a8%8b.zip?cid=7f5a25cdf47d03e6&amp;amp;sc=documents&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5）ChildWorkflow属性列表&lt;/strong&gt;&lt;/p&gt;&lt;table style="width: 955px;" border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="125"&gt;属性名&lt;/td&gt;&lt;td valign="top" width="828"&gt;属性说明&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="125"&gt;InitalChildData&lt;/td&gt;&lt;td valign="top" width="828"&gt;用来初始化子流程的&lt;strong&gt;个数&lt;/strong&gt;，InitalChildData一般需要绑定到一个Names类型的变量，Names类型实际是一个NameCollection的字符串集合，&lt;strong&gt;集合的元素个数决定了子流程的个数&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="125"&gt;ChildPropertiesMapping&lt;/td&gt;&lt;td valign="top" width="828"&gt;&lt;p&gt;子流程&lt;strong&gt;活动属性映射&lt;/strong&gt;，设置映射后，ChildWorkflow自动将子流程的属性设置为对应Names集合中的值&lt;/p&gt;&lt;p&gt;即：第一个子流程对应Names集合的第一个元素，第二个子流程对应Names集合的第二个元素&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="125"&gt;ExecutionType&lt;/td&gt;&lt;td valign="top" width="828"&gt;控制子流程是并行一次创建还是串行一个个创建&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="125"&gt;TaskTitleFormat&lt;/td&gt;&lt;td valign="top" width="828"&gt;可以控制子流程任务的标题格式，模式为{num}.{title},&amp;nbsp; {num}表示流程顺序号，{title}表示任务原来的名称， 即TaskTitle属性的值&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="125"&gt;CompeteCondition&lt;/td&gt;&lt;td valign="top" width="828"&gt;控制ChildWorkflow活动何时完成，若指定了CompeteCondition，则每个子流程完成后会计算CompeteCondition的值，如果返回true，无论其他流程分支有无完成，活动都会结束，未完成的任务被取消&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;6）备注&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;6.1 FlowchartChildWorkflow的属性跟ChildWorkflow完全一样&lt;/p&gt;&lt;p&gt;6.2 用FlowchartChildWorkflow时，不必（也不能）拖入Start活动，第一个拖入的活动即为 起始活动。&lt;/p&gt;&lt;p&gt;6.3若要实现子流程结束后统一审批，可以部分打回的效果，则可以在统一审批的时候控制Names变量的值，来控制打回给那些人。&lt;/p&gt;&lt;p&gt;6.4 本文的示例没有涉及到UI的开发，UI开发请看到其他文章进行。&lt;/p&gt;&lt;p&gt;6.5 如果子流程需要会签，则采用MultiTask活动，将其Users属性映射到Names变量，然后控制Names变量值每行多个账号，如下：&lt;/p&gt;&lt;p&gt;dc\user1,dc\user2&lt;/p&gt;&lt;p&gt;dc\user3,dc\user4&lt;/p&gt;&lt;p&gt;6.6 如何在UI代码中给Names变量赋值请参考其他文章。&lt;/p&gt;&lt;p&gt;6.7 不要在ChildWorkflow之外的规则代码中取子流程中活动的属性，比如Taskoutcome，因为动态创建的原因，这些属性可能取不到，或者只能取到最后完成的子流程产生的数据。&amp;nbsp;&lt;/p&gt;&lt;p&gt;6.8 如果在ChildWorkflow之内的规则代码中获取内部子活动的状态，因为QuickFlow内部有活动属性同步的机制，可以取到当前最新的数据，普通的并发条件下作者做过测试，但不能保证大并发条件下没有问题&lt;/p&gt;&lt;p&gt;6.9 当前版本不允许跨容器拖放移动活动，即：不能将一个活动从ChildWorkflow内部拖拽到其他外部活动内部。&lt;/p&gt;&lt;p&gt;6.10 如果需要在ChildWorkflow后面获取到子流程某个任务活动的Outcome做判断如何做？&lt;/p&gt;&lt;p&gt;如果子流程内部是Task，不支持直接获取Task.Outcome,必须通过其他方法，比如用额外的工作流变量+UI代码实现&lt;/p&gt;&lt;p&gt;如果子流程内部是MultiTask等支持多任务的活动，则可以把Outcomes绑定到一个新的变量，比如outcomes1，outcomes1的类型是OutcomeCollection。然后用Decision判断outcomes1即可。如outcomes1.AllMatch("Approved") ， this.TaskOutcomes1.MatchCount("Rejected",1); ：&lt;/p&gt;&lt;p&gt;注意：绑定时，直接点Outcomes旁边那个图标，然后选择绑定到新变量。因为工作流的变量管理中不支持创建OutcomeCollection类型的变量。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;6.11&lt;strong&gt; 注意：子流程活动的属性若需要根据不同的流程有不同的值，则必须设置PropertyMapping，并且，不能&lt;span style="color: #ff0000;"&gt;绑定（bind）&lt;/span&gt;到工作流变量。若设置了绑定，则属性映射会失效。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2147810.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/08/21/2147810.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/07/17/2108825.html</id><title type="text">QuickFlow ListForm之父子表</title><summary type="text">介绍QuickFlow ListForm对父子表的支持。</summary><published>2011-07-17T10:37:00Z</published><updated>2011-07-17T10:37:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/07/17/2108825.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/07/17/2108825.html"/><content type="html">&lt;p&gt;在用QuickFlow的ListForm做表单时，如果涉及到字表的情况，一般实现比较困难，标准的做法是自己实现一个自定义的字段类型，然后添加到列表中。&lt;/p&gt;&lt;p&gt;SharePoint中实现父子表一般用Lookup字段，但是，直接用Lookup字段，在很多情况下缺点很多，比如，必须到两个列表中操作，而这在一个流程审批中用户体验很差。&lt;/p&gt;&lt;p&gt;QF最新版本中(Build110717)增加了对父子表的支持。&lt;/p&gt;&lt;p&gt;安装最新版本后，SharePoint中会增加两个字段类型：ParentItemLookup和ChildItemsLookup，如下图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201107/201107171837151905.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201107/201107171837166200.png" alt="image" width="285" height="277" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;要实现父子关系，首先建立两个列表，父列表和子列表，然后在子列表中添加ParentItemLookup，设置关联到父列表，在父列表中添加ChildItemsLookup,设置关联到子列表。&lt;/p&gt;&lt;p&gt;比如，一个请假审批的流程，申请人可以输入多段不连续的请假时间，如下图&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201107/201107171837175785.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201107/201107171837185129.png" alt="image" width="397" height="318" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在添加ParentItemLookup字段时，可以设置当父项目被删除后自动删除子项目：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/jianyi0115/201107/201107171837197539.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/jianyi0115/201107/201107171837217341.png" alt="image" width="441" height="428" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;备注：&lt;/p&gt;&lt;p&gt;1)父子表目前支持SP10/07.&lt;/p&gt;&lt;p&gt;2)通过控制子表默认视图上显示的字段即可控制父表表单上显示的子表字段.&lt;/p&gt;&lt;p&gt;3）非工作流项目也可以用这两个字段实现关联。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2108825.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/07/17/2108825.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/07/14/2105957.html</id><title type="text">QuickFlow中控制DataField and TaskField(更简单的控制列表项和任务字段值)</title><summary type="text">QuickFlow中控制DataField and TaskField(更简单的控制列表项和任务字段值)</summary><published>2011-07-14T01:34:00Z</published><updated>2011-07-14T01:34:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/07/14/2105957.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/07/14/2105957.html"/><content type="html">&lt;p&gt;QF中控制DataField and TaskField&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）概述&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;DataFields和TaskFields是QF中的两个概念：&lt;br /&gt;DataFields实际上就是工作流关联的列表项。&lt;br /&gt;TaskFields表示一个任务的数据，DataFields和TaskField都都支持用索引(DataFields["name"])来操作字段值。&lt;br /&gt;QF的UI代码API中首先支持这两个对象，如，在Executing事件中，可以通过以下代码操作DataFields和TaskFields：&lt;/p&gt;&lt;p&gt;WorkflowContext.Current.DataFields["Title"] = "some title"; //set list item title in code&lt;br /&gt;string comment s = WorkflowContext.Current.TaskFields["Body"];//get task comments&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2）FlowchartWorkflow.DataFields&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;最新preRelease中，在工作流（WF）API中也支持类似的接口：&lt;br /&gt;首先，FlowchartWorkflow工作流根活动上增加了DataFields属性，在活动的BeforeRule或AfterRule中可以直接通过DataFields&lt;br /&gt;来获取或设置列表项字段值，如：&lt;br /&gt;&lt;br /&gt;BeforeRule:&lt;br /&gt;this.DataFields["Title"] = "some Request title";&lt;br /&gt;string title = ""+this.DataFiels["Title"];&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意：在WF中&lt;/strong&gt;设置DataFields之后，默认只有当活动结束后才会执行更新。如：如果在多任务活动的TaskCompleted事件中修改了DataFields，则只有当最后一个任务完成，同时整个活动完成时才会真正对ListItem执行更新。&lt;/p&gt;&lt;p&gt;如果要立刻更新ListItem，则可以调用this.DataFields.Update()方法。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）Task.TaskFields&lt;/strong&gt;&lt;br /&gt;其次，在Task活动上，增加了TaskFields属性，通过这个属性，在任务创建前，可以控制任务字段属性，在任务创建后，可以获取任务字段值：&lt;/p&gt;&lt;p&gt;task1.BeforeRule&lt;br /&gt;this.task1.TaskFields["Body"] = "input your comment here.";&lt;/p&gt;&lt;p&gt;task1.AfterRule:&lt;br /&gt;this.DataFeilds["AllComments"] = ""+this.DataFeilds["AllComments"]+";" + this.task1.TaskFields["Body"]; //把任务字段的值同步到列表项&lt;/p&gt;&lt;p&gt;TaskFields的另一个功能是使用自定义任务内容类型时：&lt;br /&gt;&lt;br /&gt;QF支持在根站点下创建一个内容类型，继承与QuickFlowTaskContentType,添加扩展字段，然后编辑任务活动的TaskForm属性，设置任务关联到这个&lt;br /&gt;内容类型，这时可以用规则控制任务扩展字段的值：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;task1.AfterRule:&lt;br /&gt;this.task1.TaskFields["RequestDate"] = this.DataFeilds["RequestDate"]; //设置任务上直接显示申请信息&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4）多任务活动的&lt;strong&gt;TaskFields&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;多任务活动（MultiTask,RuleDriven）在Build110714版本后也支持TaskFields。&lt;/p&gt;&lt;p&gt;多任务活动的TaskFields需要注意：&amp;nbsp;&lt;/p&gt;&lt;p&gt;1-给TaskFields赋值时，会影响到所有的任务，并且所有任务的属性只能一样&lt;/p&gt;&lt;p&gt;2-通过TaskFields取值时，只能获取到最后一个有效任务的字段。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5)注意&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;所有字段名都必须用内部名(internalName)&lt;br /&gt;用QF的Rule之前最好了解下WF规则引擎：&lt;a href="http://msdn.microsoft.com/zh-cn/library/aa480193.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/aa480193.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;此功能Build110714后版本支持&lt;/p&gt;&lt;p&gt;多任务活动在Build110724版本后支持TaskFields&lt;/p&gt;&lt;p&gt;this.DataFields.Update()方法在Build120325版本后支持&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2105957.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/07/14/2105957.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/06/20/2085117.html</id><title type="text">CamlQuery and SmartQuery1.3 release</title><summary type="text">CamlQuery and SmartQuery正式支持SharePoint2010了，使用方法跟07完全一样。见：http://www.cnblogs.com/jianyi0115/archive/2008/02/15/1070158.html下载：http://camlquery.codeplex.com/releases</summary><published>2011-06-20T04:03:00Z</published><updated>2011-06-20T04:03:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/06/20/2085117.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/06/20/2085117.html"/><content type="html">&lt;div&gt;CamlQuery and SmartQuery正式支持SharePoint2010了，使用方法跟07完全一样。&lt;/div&gt;&lt;div&gt;见：&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2008/02/15/1070158.html"&gt;http://www.cnblogs.com/jianyi0115/archive/2008/02/15/1070158.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/21594/2011062012013911.jpg" /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;下载：&lt;/div&gt;&lt;div&gt;http://camlquery.codeplex.com/releases&lt;/div&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2085117.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/06/20/2085117.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/06/12/2078774.html</id><title type="text">QuickFlow教程(15)--常见问题释疑</title><summary type="text">本文将针对QuickFlow开发人员经常碰到的问题做一个集中的解释。</summary><published>2011-06-12T03:09:00Z</published><updated>2011-06-12T03:09:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/06/12/2078774.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/06/12/2078774.html"/><content type="html">&lt;p&gt;本文将针对QuickFlow开发人员经常碰到的问题做一个集中的解释。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1）QuickFlow是什么&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;QuickFlow是基于SharePoint（2007,2010）的一个工作流设计工具，它包含一个核心的Flowchart流程模型和一个无代码设计器。基于QuickFlow开发SharePoint工作流和直接在SharePoint上开发工作流很类似，使用Quickflow前最好了解下默认的SharePoint工作流是如何开发和运行的。&lt;/p&gt;&lt;p&gt;更多细节，参见:&lt;a href="http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow2.0%E7%99%BD%E7%9A%AE%E4%B9%A6.docx"&gt;http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow2.0%E7%99%BD%E7%9A%AE%E4%B9%A6.docx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2)QuickFlow如何安装&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;QuickFlow的安装包含两部分：一部分是一个wsp的解决方案，这个解决方案中，包括所有dll文件和页面文件，这个wsp分两个版本：一个用于SharePoint2007，一个用户SharePoint2010。另外一部分是设计器，设计器无需安装，直接解压后即可打开exe文件，需要指出的是，当前版本的设计器只能在SharePoint服务器上运行。&lt;/p&gt;&lt;p&gt;详细见：&lt;a href="http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97.docx"&gt;http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97.docx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3）Quickflow使用中碰到错误如何解决&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有几种类型的错误：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;发布流程时：&lt;/strong&gt;这个时候出错，一般是web.config配置错误，重新激活下QuickFlow feature即可。在SP07下，在网站集功能管理中操作，在SP10下，需要到管理中心激活QuickFlow App Configuration feature，详见&lt;a href="http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow安装指南.docx"&gt;安装文档&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;工作流运行时：&lt;/strong&gt;有很多种可能性，首先要找到日志信息，日志有两个地方可以看，一个是工作流状态页面--在列表页面，点击工作流链接进入。在这个页面可以看到QuickFlow内部输出的日志。不仅仅是碰到错误，如果工作流没错误，但是运行结果跟预期的不一致，也可以到这个页面查看信息。比如设置了发送邮件，但是测试时却没有收到，那么状态页面会记录邮件发现情况。&lt;/p&gt;&lt;p&gt;另一个查看日志的地方是12/Logs or 14/Logs目录，这是SP自带的日志文件。打开最新的日志文件，在里面搜索Workflow Infrastructure&amp;nbsp;,可以搜到跟工作流有关的日志信息。&lt;/p&gt;&lt;p&gt;注：日志目录[C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS]&lt;/p&gt;&lt;p&gt;&lt;strong&gt;在页面提交的时出错:&lt;/strong&gt; 这个时候，如果发现页面上没有详细的错误信息，那么首先要让SP显示出详细错误，这个操作是SP开发第一步就要做的。详细：google SharePoint 详细错误。 需要指出的是：Layouts下的web.config也是需要修改的（set customError mode=&amp;rsquo;off&amp;rsquo;）&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4)关于工作流变量（workflow variable）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;工作流变量是当使用QuickFlow Designer时，允许在流程级别添加一些特定类型的字段，各个活动的属性可以跟工作流变量绑定，UI代码可以直接控制工作流变量的值。&lt;/p&gt;&lt;p&gt;如果您是用VisualStudio+QuickFlow开发，那么是没必要用工作流变量的，工作流变量其实是模拟添加类字段（field）。用vs时，可以很方便的在工作流中添加字段，为什么还要用工作流变量呢？&lt;/p&gt;&lt;p&gt;当然，vs中工作流变量还是可以使用的，那么一般会碰到两个问题：&lt;/p&gt;&lt;p&gt;a）如何在UI代码中控制工作流字段的值：跟控制工作流变量的值是一样的，用QuickFlow.Core.WorkflowContext.Current.UpdateWorkflowVariable("NextApprovors", nextUsers);&lt;/p&gt;&lt;p&gt;b）如何在WF代码中控制工作流变量的值:直接设置字段的值即可，或者，用base.UpdateVariable("NextApprovors", nextUsers);如：&lt;/p&gt;&lt;p&gt;public QuickFlow.NameCollection nextUsers ;&lt;br /&gt;//nexUsers bind to multiTask.Users&lt;br /&gt;private void task_init(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;this.nextUsers = ...;&lt;/p&gt;&lt;p&gt;//or base.UpdateVariable("nextUsers", nextUsers);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;记住：&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;在用VS+QF时，工作流变量跟普通的字段是一样的。&lt;br /&gt;永远不要在VS的WF代码中调用WorkflowContext.Current。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;如果要在UI代码中传递变量值，只能在几个固定的事件方法中才可行：&lt;/p&gt;&lt;p&gt;1-StartWorkflowButton.Executing事件中，&lt;/p&gt;&lt;p&gt;2-ActionsButton.ActionExecuting事件中，&lt;/p&gt;&lt;p&gt;3-TaskReassignButton.Executing事件中，&lt;/p&gt;&lt;p&gt;4-在启动页面或任务页面的Page_Load事件中，Page_Load中给工作流变量赋值后，必须在以下的操作中启动工作流或提交任务才会有效&lt;/p&gt;&lt;p&gt;无论在哪个方法中，都需要使用QuickFlow.Core.WorkflowContext.Current.UpdateWorkflowVariable来更新变量&lt;/p&gt;&lt;p&gt;注意：在ＵＩ代码中，只能设置工作流变量的值而不能获取工作流变量值，如果碰到必须获取工作流变量的情况，那么可以用列表字段传值来实现。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5)关于WorkflowContext.Current&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这个类用于在&lt;strong&gt;工作流页面&lt;/strong&gt;中跟工作流交互。非工作流页面不能使用。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6）如果不用QuickFlow提供的控件来开发工作流页面，如何启动流程，提交任务呢？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有两种方式：&lt;/p&gt;&lt;p&gt;a)直接用SharePoint的对象模型来操作。这样做会有些复杂性。&lt;/p&gt;&lt;p&gt;跟Workflow有关的方法有:SPSite.WorkflowManager.StartWorkflow, SPWorkflow.AlterTask,详细见SharePoint SDK.&lt;/p&gt;&lt;p&gt;b)用QuickFlow提供的API操作: WorkflowContext.Current.&lt;/p&gt;&lt;p&gt;用WorkflowContext必须在特定的上下文下运行，包括列表的新建页面，任务的提交页面。&lt;/p&gt;&lt;p&gt;常用WorkflowContext方法如下：&lt;/p&gt;&lt;table style="width: 893px;" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="397"&gt;WorkflowContext.Current&lt;/td&gt;&lt;td valign="top" width="494"&gt;获取到当前的工作流上下文&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;WorkflowContext.CreateContext(SPList dataList)&lt;/td&gt;&lt;td valign="top" width="494"&gt;基于某个列表创建一个上下文， 这样创建的context，自动工作流的时候，会自动在列表中新建一个列表项&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;.DataFields[]&lt;/td&gt;&lt;td valign="top" width="494"&gt;获取或设置列表字段值。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;.UpdateWorkflowVariable(string name, object value)&lt;/td&gt;&lt;td valign="top" width="494"&gt;工作流启动前或任务提交前更新工作流变量&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;.StartWorkflow(string wfName)&lt;/td&gt;&lt;td valign="top" width="494"&gt;启动工作流&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;&lt;p&gt;.CommitTask( string outcome )&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="494"&gt;完成任务，指定任务的结果（通过，拒绝）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;.ReAssignTask(string to)&lt;/td&gt;&lt;td valign="top" width="494"&gt;转发任务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;WorkflowContext.Current.Task&lt;/td&gt;&lt;td valign="top" width="494"&gt;获取当前的WorkflowTask（只能获取到上次的数据）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="398"&gt;WorkflowContext.Current.TaskFields["field name"]&lt;/td&gt;&lt;td valign="top" width="494"&gt;获取当前的任务字段属性，可以获取到最新数据&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;WorkflowTask一般通过WorkflowContext.Current.Task或者WorkflowContext.FromListItem获取&lt;/p&gt;&lt;p&gt;常用WorkflowTask方法如下：&lt;/p&gt;&lt;table style="width: 902px;" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="360"&gt;WorkflowContext.FromListItem&lt;/td&gt;&lt;td valign="top" width="540"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="361"&gt;.Actions&lt;/td&gt;&lt;td valign="top" width="539"&gt;获取到任务的动作集合（TaskActions）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="362"&gt;bool CanCommit()&lt;/td&gt;&lt;td valign="top" width="539"&gt;当前用户是否可以提交工作流（只有网站集管理员或者任务操作人才能提交任务）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="362"&gt;CommitTask(string outcome)&lt;/td&gt;&lt;td valign="top" width="539"&gt;提交任务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="362"&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign="top" width="539"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;示例：&lt;/p&gt;&lt;p&gt;在列表的Newform页面启动工作流：&lt;/p&gt;&lt;p&gt;WorkflowContext.Current.StartWorkflow(&amp;ldquo;My Workflow&amp;rdquo;)&lt;/p&gt;&lt;p&gt;无论是启动工作流还是提交任务前，都可以传递工作流变量&lt;/p&gt;&lt;p&gt;WorkflowContext.Current.UpdateWorkflowVariable(&amp;ldquo;vabiableName&amp;rdquo;,value)&lt;/p&gt;&lt;p&gt;在一个普通的aspx页面启动流程（非NewForm页面）：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var wflist = SPContext.Current.Web.Lists[&amp;ldquo;List1&amp;rdquo;];&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WorkflowContext wfCtx = WorkflowContext.CreateContext(wflist);&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.DataFields["Title"] = proj.ProjectName; //设置列表项字段&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.DataFields["ReferenceNo"] = proj.ReferenceNo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.DataFields[ProjectID_FieldName] = proj.ID;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.UpdateWorkflowVariable("sendToPCController", true);//设置工作流变量&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.UpdateWorkflowVariable("PCController", new NameCollection(pcController));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.UpdateWorkflowVariable("PM", new NameCollection(proj.ProductManager));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wfCtx.StartWorkflow(Config.WorkflowName);&lt;/p&gt;&lt;p&gt;在任务页面获取任务动作：&lt;/p&gt;&lt;p&gt;TaskActionCollection actons = WorkflowContext.Current.Task.Actions;&lt;/p&gt;&lt;p&gt;在任务页面完成任务：&lt;/p&gt;&lt;p&gt;WorkflowContext.Current.CommitTask(&amp;ldquo;Approved&amp;rdquo;); //Approved is a taskAction&lt;/p&gt;&lt;p&gt;&lt;strong&gt;7)CommentTaskField这个富文本框能否去掉其样式呢，就是不希望用户在审批意见里添加各种样式，只要输入文字意见好了&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在网站内容类型管理中，找到任务内容类型，设置其 描述字段 不使用富文本&lt;/p&gt;&lt;p&gt;&lt;strong&gt;8)在Initialized事件中设置了活动的属性，为什么不起作用？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;因为ＱＦ中的活动可以无限次执行，所以实际执行的活动只是设计器上的活动的副本&lt;/p&gt;&lt;p&gt;如果在活动已经开始执行了，再设置设计器上的活动的属性，可能就无效了。&lt;/p&gt;&lt;p&gt;有两个方法解决这个问题：&lt;/p&gt;&lt;p&gt;&amp;nbsp;1--事件参数sender始终是执行中的活动，直接给sender赋值，如: ((Task)sender).User = "someUserAccount";&lt;/p&gt;&lt;p&gt;&amp;nbsp;2--如果要让一个属性可以在活动执行时可以被修改，那么可以把这个属性绑定到一个全局变量,这样－－就始终可以修改了.&lt;/p&gt;&lt;p&gt;&amp;nbsp;3--在这个活动前面一个活动的Completed事件中给这个活动的字段赋值。&lt;br /&gt;&lt;strong&gt;9)设置了规则引擎(BeforeRule or AfterRule),发现工作流长时间不结束&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;原因：规则的计算，改变了规则的条件，造成规则引擎重新运行规则（造成无限循环）&lt;/p&gt;&lt;p&gt;解决：把&amp;nbsp;重新计算 选项改成 永不(Never) , &amp;nbsp;了解WF规则引擎：&lt;a style="box-sizing: border-box; color: #3468a4;" href="http://msdn.microsoft.com/zh-cn/library/aa480193.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/aa480193.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;10)任务被锁定，即使更正了代码错误，任务依然无法重新提交&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;解决：需要先把任务解锁,然后重新提交即可：&lt;/p&gt;&lt;p&gt;ServerModel code:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;using (SPSite site = new SPSite("http://localhost"))&lt;br/&gt;            {&lt;br/&gt;                using (SPWeb web = site.OpenWeb())&lt;br/&gt;                {&lt;br/&gt;                    SPList taskList = web.Lists["Tasks"];&lt;br/&gt;                    var item = taskList.GetItemById(188); //change 188 to the task id&lt;br/&gt;                    web.AllowUnsafeUpdates = true;&lt;br/&gt;                    item[SPBuiltInFieldId.WorkflowVersion] = 1;&lt;br/&gt;                    try&lt;br/&gt;                    {&lt;br/&gt;                        item.SystemUpdate();&lt;br/&gt;                    }&lt;br/&gt;                    catch (Exception ex)&lt;br/&gt;                    {&lt;br/&gt;                        Console.WriteLine(ex.ToString());&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt; }&lt;br/&gt;&lt;/div&gt;&lt;p&gt;ClientModel code:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; (ClientContext clientContext &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ClientContext(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://localhost&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;))&lt;br /&gt;                {&lt;br /&gt;                    Web site &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; clientContext.Web;&lt;br /&gt;                    var list &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; site.Lists.GetByTitle(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Tasks&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                    ListItem item &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; list.GetItemById(&lt;/span&gt;&lt;span style="color: #800080;"&gt;188&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                    clientContext.Load(item);&lt;br /&gt;                    clientContext.ExecuteQuery();&lt;br /&gt;                    Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WorkflowVersion: &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WorkflowVersion&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;                    item[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WorkflowVersion&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                    item.Update();&lt;br /&gt;                    clientContext.ExecuteQuery();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception e)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(e.ToString());&lt;br /&gt;            }&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;done&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            Console.ReadKey();&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注：最新版本任务被锁定后，默认任务页面上会显示一个解锁的链接，如果是自定义的页面，则在页面上加上UnLockTaskLink控件即可。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;11)不用QuickFlow的API启动流程，而直接用纯MOSS接口启动，如何传递工作流变量呢?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;代码入下：&lt;/p&gt;&lt;p&gt;//using QukckFlow.Core;&lt;/p&gt;&lt;p&gt;WorkflowVariableValues vs = new&amp;nbsp;WorkflowVariableValues();&lt;/p&gt;&lt;p&gt;vs["variableName1"] = "value1";&lt;/p&gt;&lt;p&gt;vs["variableName2"] = "value2";&lt;/p&gt;&lt;p&gt;var&amp;nbsp;eventData = SerializeUtil.Serialize(vs);&lt;/p&gt;&lt;p&gt;SPSite site = SPControl.GetContextSite(HttpContext.Current);&lt;/p&gt;&lt;p&gt;var wfName = "some workflow name";&lt;/p&gt;&lt;p&gt;var wfAss = &amp;nbsp;list.WorkflowAssociations.GetAssociationByName(wfName, System.Globalization.CultureInfo.CurrentCulture);&lt;/p&gt;&lt;p&gt;wf = site.WorkflowManager.StartWorkflow(listItem, wfAss, eventData);&lt;/p&gt;&lt;p&gt;如果要异步启动工作流，可以调用：&lt;/p&gt;&lt;p&gt;site.WorkflowManager.&lt;strong&gt;&lt;a class="bold" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://Microsoft.SharePoint:14.0.0.0:71e9bce111e9429c/Microsoft.SharePoint.Workflow.SPWorkflowManager/StartWorkflow(Object,Microsoft.SharePoint.Workflow.SPWorkflowAssociation,String,Microsoft.SharePoint.Workflow.SPWorkflowRunOptions):Microsoft.SharePoint.Workflow.SPWorkflow"&gt;StartWorkflow&lt;/a&gt;&lt;/strong&gt;(&lt;a title="System.ObjectCTRL+Click to open in new tab." href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Object"&gt;&lt;span style="color: #ff0000;"&gt;object&lt;/span&gt;&lt;/a&gt; context, &lt;a title="Microsoft.SharePoint.Workflow.SPWorkflowAssociationCTRL+Click to open in new tab." href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://Microsoft.SharePoint:14.0.0.0:71e9bce111e9429c/Microsoft.SharePoint.Workflow.SPWorkflowAssociation"&gt;&lt;span style="color: #ff0000;"&gt;SPWorkflowAssociation&lt;/span&gt;&lt;/a&gt; association, &lt;a title="System.StringCTRL+Click to open in new tab." href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String"&gt;&lt;span style="color: #ff0000;"&gt;string&lt;/span&gt;&lt;/a&gt; eventData, &lt;a title="Microsoft.SharePoint.Workflow.SPWorkflowRunOptionsCTRL+Click to open in new tab." href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://Microsoft.SharePoint:14.0.0.0:71e9bce111e9429c/Microsoft.SharePoint.Workflow.SPWorkflowRunOptions"&gt;&lt;span style="color: #ff0000;"&gt;SPWorkflowRunOptions&lt;/span&gt;&lt;/a&gt; runOptions)&lt;/p&gt;&lt;p&gt;此异步方法只有SP2010支持。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;12)如果工作流设置成自动启动（Auto）， 用StartWorkflowButton启动工作流时会报错。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;首先搞清楚MOSS默认的工作流机制：工作流启动分3种模式：&lt;/p&gt;&lt;p&gt;1）手工启动--就是通过下拉菜单进入工作流启动页面启动&lt;/p&gt;&lt;p&gt;2）自动启动--创建一条Item后自动自动&lt;/p&gt;&lt;p&gt;3）当Item的某个字段值改变后启动&lt;/p&gt;&lt;p&gt;用了StartWorkflowButton时，StartWorkflowButton会调用moss api启动工作流，实际上是模拟手工启动&lt;/p&gt;&lt;p&gt;如果配置成自动自动，那么moss会自动启动一个工作流， StartWorkflowButton会再次启动一个工作流&lt;/p&gt;&lt;p&gt;而一个工作里是不能启动2次的，所以，StartWorkflowButton启动工作流的时候就出错了&lt;/p&gt;&lt;p&gt;所以，用了StartWorkflowButton，或用其他方式调用MOSS API启动工作流，工作流必须设置成手工启动（Manual）&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;13)SP10任务表单上的任务历史记录列表会显示一个复选框，如何取消？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;修改任务列表的默认视图设置，取消：Allow individual item checkboxes &amp;nbsp;复选框&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;14)在QFD中新建了一个工作流变量，但是在活动属性绑定窗口或规则编辑窗口无法找到这个变量&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;点下保存按钮，将工作流保存下即可。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;15)重新发布流程后，流程名称后面出现 （1）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;问题原因：是因为老版本的QFD发布流程时流程配置文件的BaseID会变造成的&lt;/p&gt;&lt;p&gt;解决方法：升级到最新版本的QFD，然后用SharePoint Designer打开工作流文件夹，把.xoml.wfconfig.xml的除1.0版本和当前版本外的版本删除，&lt;/p&gt;&lt;p&gt;然后将最新版本.xoml.wfconfig.xml中的BaseID修改成和1.0版本一致），用QFD重新发布流程即可&lt;/p&gt;&lt;p&gt;&lt;strong&gt;16)如何控制WorkflowHistory/TaskList显示的字段&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果是在自定义任务表单中，可以通过WorkflowHistory控件的ViewFields控制,如:&lt;/p&gt;&lt;p&gt;&amp;lt;QFL:WorkflowHistory runat="server" ID="hisList" &amp;nbsp;ShowTaskOfCurrentWorkflow="true"&lt;/p&gt;&lt;p&gt;&amp;nbsp;ViewFields=""Title,AssignedTo, Status, Body, StartDate, WorkflowOutcome, DelegateFrom"/&amp;gt;&lt;/p&gt;&lt;p&gt;如果是想控制QF自带的TaskList页面，则到网站设置-&amp;gt;网站栏管理，将需要显示的字段添加到QuickFlow组中即可。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;strong&gt;17)RuleDriven/TaskWizard设置了超时规则，不起作用&lt;br /&gt;&lt;/strong&gt;&amp;nbsp;1-重启iis，重启SharePoint Timer服务，重启服务器&lt;/p&gt;&lt;p&gt;&amp;nbsp;2-设置定时job扫描间隔：&amp;nbsp;stsadm -o setproperty -propertyname "job-workflow" -propertyvalue "every 2 minutes &amp;nbsp;between 0 and 59" -url &lt;a href="http://d"&gt;http://d&lt;/a&gt;c&lt;/p&gt;&lt;p&gt;&amp;nbsp;3- 参考：&lt;a href="http://www.dev4side.com/community/blog/2010/12/1/bug-using-delay-activity-on-sharepoint-2010-workflow.aspx"&gt;http://www.dev4side.com/community/blog/2010/12/1/bug-using-delay-activity-on-sharepoint-2010-workflow.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;strong&gt;18)采用VS+QF开发工作流时，若已经在生产环境部署，如何更新，才能保证老流程正常运行下去？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;若只是修改了方法内部的代码，则正常更新dll或wsp即可。&lt;/p&gt;&lt;p&gt;若增删了活动或变量，则必须将程序集升版，然后手工备份老程序集，更新新程序集或wsp，然后重新部署老程序集，确保新老程序集在gac中同时存在&lt;/p&gt;&lt;p&gt;see：&amp;nbsp;&lt;strong&gt;&amp;nbsp;&lt;a href="http://spmat.blogspot.com/2010/11/assembly-versioning-for-sharepoint.html"&gt;http://spmat.blogspot.com/2010/11/assembly-versioning-for-sharepoint.html&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2078774.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/06/12/2078774.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jianyi0115/archive/2011/06/08/2074992.html</id><title type="text">MVVM之View和ViewModel的关联</title><summary type="text">概要：将所有的VM在加载到Application的Static Resource中，然后在Ｖｉｅｗ中用标签指定。实现：１）采用特性指定要添加到ＳｔａｔｉｃＲｅｓｏｕｒｃｅ中的对象public class StaticResourceAttribute : Attribute { public string Key { get; set; } public StaticResourceAttribute(string key) { this.Key = key; } }２）从当前的程序集中，把所有标记了StaticResourceAttribute的VM加载到AppResource中public</summary><published>2011-06-08T03:27:00Z</published><updated>2011-06-08T03:27:00Z</updated><author><name>jianyi</name><uri>http://www.cnblogs.com/jianyi0115/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jianyi0115/archive/2011/06/08/2074992.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jianyi0115/archive/2011/06/08/2074992.html"/><content type="html">&lt;p&gt;概要：&lt;/p&gt;&lt;p&gt;将所有的VM在加载到Application的Static Resource中，然后在Ｖｉｅｗ中用标签指定。&lt;/p&gt;&lt;p&gt;实现：&lt;/p&gt;&lt;p&gt;１）采用特性指定要添加到ＳｔａｔｉｃＲｅｓｏｕｒｃｅ中的对象&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;public class StaticResourceAttribute : Attribute&lt;br/&gt;    {&lt;br/&gt;        public string Key { get; set; }&lt;br/&gt;&lt;br/&gt;        public StaticResourceAttribute(string key)&lt;br/&gt;        {&lt;br/&gt;            this.Key = key;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;２）从当前的程序集中，把所有标记了StaticResourceAttribute的VM加载到AppResource中&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;public class ViewModelManager&lt;br/&gt;    {&lt;br/&gt;        private static Application app = Application.Current;&lt;br/&gt;&lt;br/&gt;        public static void InjectViewModelsToResources()&lt;br/&gt;        {&lt;br/&gt;            Assembly executingAssembly = Assembly.GetCallingAssembly();&lt;br/&gt;            foreach (Type type in executingAssembly.GetTypes())&lt;br/&gt;            {&lt;br/&gt;                var attributes = type.GetCustomAttributes(false);&lt;br/&gt;&lt;br/&gt;                foreach (var attribute in attributes)&lt;br/&gt;                {&lt;br/&gt;                    if (attribute is StaticResourceAttribute)&lt;br/&gt;                    {&lt;br/&gt;                        var obj = Activator.CreateInstance(type);&lt;br/&gt;                        if (!app.Resources.Contains(type.Name))&lt;br/&gt;                            app.Resources.Add(type.Name, obj);&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        public static T GetViewModelFromResources&amp;lt;T&amp;gt;()&lt;br/&gt;        {&lt;br/&gt;            var key = typeof(T).Name;&lt;br/&gt;            if (app.Resources.Contains(key))&lt;br/&gt;                return (T)app.Resources[key];&lt;br/&gt;            else&lt;br/&gt;                return default(T);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;在主窗体中调用：&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;public partial class MainPage : UserControl&lt;br/&gt;    {&lt;br/&gt;        public MainPage()&lt;br/&gt;        {&lt;br/&gt;            ViewModelManager.InjectViewModelsToResources();&lt;br/&gt;            &lt;br/&gt;            InitializeComponent();         &lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;3）View写法&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&amp;lt;UserControl x:Class="XXX .LoginView"〉&lt;br/&gt; &amp;lt;UserControl.DataContext&amp;gt;&lt;br/&gt;        &amp;lt;Binding Source="{StaticResource LoginViewModel}"/&amp;gt;&lt;br/&gt;    &amp;lt;/UserControl.DataContext&amp;gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;/UserControl&amp;gt;&lt;br/&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;结论：&lt;/p&gt;&lt;p&gt;这样处理后，实现了VM的"单例",多个View关联同一个VM时可以共享数据。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jianyi0115/aggbug/2074992.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jianyi0115/archive/2011/06/08/2074992.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
