SharePoint中ListViewWebPart&SPView-一个硬币的两面
如题,这个比喻背后的意思是,这两个SharePoint对象模型类实际上是同一种数据(实体)的两种表现形式。这意味着当你创建这两种对象模型中任意一种实例,你可以自动获得另外一种对象模型的实例,当您删除其中一个,另一个也被删除,当你改变其中一个对象模型的属性,你可以看到这个变化也会发生在另一个对象模型上。因此,在SharePoint中,列表视图(List View)总是和一对对象――ListViewWebPart(LVWP)和SPView--同时出现,因为在它们后面的是同一个数据(实体),所以你不能把这一对对象中的一个用其它的SPView 或LVWP取代。在SharePoint 2010中,引进的LVWP继承者-XSLTListView Webpart(XLV)-同样有着相同的配对问题,只是XLV在WebPart方面取代了LVWP。
为了澄清上述观点,我现在从SPView和LVWP的不同视角来举几个例子
先从SPView的视角
· 当您创建一个新的SPView(从代码或用户界面一样),你得到一个Web Part页(在list的根目录或者在list下面的Forms子目录),该页面上有一个LVWP用来显示该list的数据。当删除SPView的同时,刚才得到的包含LVWP的Web Part页也被一起删除。到目前为止,这听起来相当平淡。
· 但更有趣的部分是你有一个包含LVWP的Web Part页面,你用SharePoint界面(你也可以用代码)删除在Web Part 页面上的LVWP的,结果是创建的SPView对象也被删除了----这可能是你没有想到会发生的(注意不要用这种方式删除默认的视图)。这种操作的结果是你最终只得到一个空的Web Part页面(SPView被删除)。你可以检查SPList的视图集合属性来确认SPView确实被删除了。
我们再从LVWP的视角
· 当你用代码或者SharePoint界面添加一个LVWP到一个发布页(Publishing)或一个简单的Web Part页面的同时,你将得到一个新的SPView,你可以从SPList的视图集合属性中看到。这个新的SPView的Hidden属性值为真,DisplayName属性为空。并且这个SPView的Guid属性(ID)与页面添加的LVWP的ViewGuid属性值相同。
· 当您更改这个隐藏的SPView对象的Query属性或ViewFields属性的时候,你会发现这些变化立即在LVWP上可见。请注意,如果你的LVWP是在一个发布页(Publishing Page),你做这些修改之前需要先把页面签出(Check-Out),否则当你调用SPView.Update方法的时候,将收到一个错误(我会在下面给出一段如何实现该操作的代码)。
· 另外请注意这里――LVWP的属性的标准编辑界面有一点误导――你看到一个下拉列表框,你可以从当前LVWP的所有可见SPView中选择一个。你可能会这样认为:你将你选中的SPView和当前LVWP建立关联。但是实际上是你创建了选中的SPView的结构(Schema)的副本,并将该副本复制给了和该LVWP配对的隐藏的SPView。你可以很容易验证――修改你认为建立“关联”的视图,你会发现你的修改并没有应用在这个LVWP上。
· 这与你用代码添加一个LVWP到一个页面几乎是相同的:在这种情况下,你需要创建一个ListViewWebPart类的新实例,设置它的ListName 属性并且要设置ViewGuid或 ListViewXml属性中的一个。当您设置时,你需要提供一个现有SPView GUID的编号--不过,当这个LVWP已经添加到页面上时,你会发现该LVWP的ViewGuid属性已经不是原来提供的那个SPView的ID了。 如果你使用ListViewXml属性,你应该提供你自己的视图结构(长话短说,你可以使用SPList.GetUncustomizedViewByBaseViewId的返回值作为SchemaXml属性的例子)并且你可以完全控制该视图的架构包括Query,ViewFields等
现在让我告诉你几个如何利用SharePoint UI或代码更新LVWP的隐藏SPView的例子。
先从SharePoint 2007开始--从用户界面修改LVWP的SPView的结构,你可以在WebPart的编辑模式下,在属性面板里单击“编辑当前视图”,这会打开“修改视图”的页面。另一个方法是修改当前视图为另一种现有的视图。
有一种情况你不需要修改SPView的结构(Query,ViewFields属性),你只需要修改BaseViewID。这个问题只有用代码才可以解决,这里有两种可选方案,要么用代码添加LVWPs(操纵ListViewXml属性),要么在LVWP创建以后再修改隐藏的SPView属性(通过UI或者部署feature)。后者实现起来比较困难,下面是可以实现该功能的一个代码片段:
public void ProcessCommonAction(SPWeb rootWeb, SPWeb web, XElement element)
{
string pageUrl = element.Attribute("PageUrl").Value;
string listUrl = element.Attribute("ListUrl").Value;
SPFile file = web.GetFile(pageUrl);
if (!file.Exists) return;
Guid listID = file.ParentFolder.ParentListId;
SPList library = null;
bool inLibrary = !listID.Equals(Guid.Empty);
if (inLibrary)
{
library = web.Lists[listID];
if (library.ForceCheckout && file.Level != SPFileLevel.Checkout) file.CheckOut();
}
try
{
// it is important that the SPView object is retrieved after the checkout of the file
SPList listViewList = web.GetList(web.ServerRelativeUrl.TrimEnd('/') + "/" + listUrl);
SPView view = listViewList.Views.Cast<SPView>().FirstOrDefault(v => v.Url.EndsWith(pageUrl, StringComparison.OrdinalIgnoreCase));
if (view != null)
{
ViewHelper.AddOrUpdateView(listViewList, view, element.Element(XHelper.WSSNs + "View"));
}
}
finally
{
if (inLibrary)
{
if (library.ForceCheckout) file.CheckIn("");
if (library.EnableMinorVersions) file.Publish("");
if (library.EnableModeration) file.Approve("");
}
}
}
请注意,页面包含的LVWP可能需要先签出之后才能更新SPView实例。还要注意的是SPView对象只有在页面签出后才能获得。
关于SharePoint 2010
这里有几件好消息,首先是XLV Web Part的发布,这是在SharePoint2007中LVWP基础上有数项改进的新Web Part(在MS SharePoint团队博客中有一个系列讲座)。该控件的主要改进之一是,界面展示的设置从SPView类移到WebPart自身――XLV的Xsl属性 和XslLink属性替换了烦琐的CAML保存SPView中的展示属性。SharePoint 2010中XLV的另一个“糖果”是你可以直接接使用标准视图编辑页(_layouts/ ViewEdit.aspx)来修改XLV的隐藏SPView--修改的按钮都放在了“ribbon"上,你不再需要做SharePoint 2007中的繁琐的工作。
请注意,打开的标准视图编辑页面只有文本列和列的选择框。删除按钮消失了,但是你还是可以通过代码删除SPView对象。
原文http://stefan-stanev-sharepoint-blog.blogspot.com/2010/02/listviewwebpart-spview-two-sides-of.html