惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
博客园 - 三生石上(FineUI控件)
S
Securelist
U
Unit 42
The Cloudflare Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Simon Willison's Weblog
Simon Willison's Weblog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog
T
Tenable Blog
The Hacker News
The Hacker News
The Register - Security
The Register - Security
IT之家
IT之家
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
P
Privacy & Cybersecurity Law Blog
博客园_首页
T
Tailwind CSS Blog
人人都是产品经理
人人都是产品经理
C
Cybersecurity and Infrastructure Security Agency CISA
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
T
Tor Project blog
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
V
Vulnerabilities – Threatpost
A
Arctic Wolf
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
V
Visual Studio Blog
月光博客
月光博客
爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
G
GRAHAM CLULEY
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Heimdal Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

博客园 - 风渐寒pro

mysql的1067错误 Sharepoint门户可以干很多事情的 利用 Lotus Notes API 提高自动化测试效率(转) sharepoint2010,I am coming! - 风渐寒pro sharepoint安全性验证无效的一个问题 REST实现原理浅析(转载) 山人自有妙招-sharepoint正式环境不能调试 Sharepoint ListType Id 使用 SharePoint 2007 进行安全性编程(转) sharepoint2010的控制台程序,找不到位于<url>的应用程序 - 风渐寒pro - 博客园 extJS中AsyncTreeNode使用多个loader Sharepoint文档权限审计控制小尝试 又是未写完的IDI Repository模式(转) Oracle和Tomcat端口冲突 实现domino平台上的本地word编辑 转帖:ESB拓扑方案 某个domino的word公文本地编辑实现方案 转载:LOTUS还能活多久
Customizing the Rendering of a Custom SPField (copy from todd's blog)
风渐寒pro · 2010-05-21 · via 博客园 - 风渐寒pro

http://blogs.msdn.com/toddca/archive/2009/01/23/customizing-the-rendering-of-a-custom-spfield.aspx

I was recently asked by a customer how to use a PropertySchema field value within a RenderPatten's CAML to control how a field is rendered. The idea is to create a new instance of the field and have some method to control how that field will be rendered at the time the column is instantiated. Unfortunately field values from the PropertySchema are not available via a <Property Select='myValue'/> within a ReanderPattern's CAML and nor is it possible to call a custom getter off the SPField derived class of your custom SPField. In most cases when a field is rendered it is done so within native (non-managed) code so the getter on your .net assembly will not get called. The field schema stored in the DB is what gets read to help generate the rendered output. Fortunately this schema can be accessed by SPFIeld.SchemaXml. Adding properties or attributes to the root element of this XML will allow the RenderPattern CAML access.

So let's take a look at a sample. For my scenario I want URL field however I want to control how that field is rendered. By default a URL field just renders the URL without wrapping that URL in an <a> tag. In our example we want to create a true hyperlink so we are going to generate a RenderingPattern which will wrap an <a> tag around the field value. In addition we want the creator of the field to choose what happens when that link is selected by the user. That is, will the navigation happen within the same window or will the browser open the URL in a new window. I call these options "Self" and "New" respectively.

Now that we have our scenario let's take a look at what it will take to wire up the new field. First I need to define our field via fldTypes XML. Code 1 shows what this looks like. As you can see the Parent is "URL" because we want to use the same storage and rendering of the built-in URL however we are going to tweak it a bit. The FieldTypeClass will be outlined in Code 2. The PropertySchema field is used to collect the user's intent on how the URL will behave within the client's browser and finally we have RenderingPattern CAML which will control how the field will be rendered within the browser. Note I have a FieldSwitch on a Property called 'HowOpenUrl', this value will not be chosen from the PropertySchema's HowOpenUrl directly however once you take a look at Code 2 you will see how this is done. The reminder of the RenderPattern uses the FieldSwitch to determine how to render the URL. The default rendering is an <a> tag with the target set to _self so the URL will be navigated to within the same window.

Code 1 – fldtypes_sample.xml

<?xml version="1.0" encoding="utf-8" ?>

<FieldTypes>

    <FieldType>

        <Field Name="TypeName">ConfigurableURL</Field>

        <Field Name="ParentType">URL</Field>

        <Field Name="TypeDisplayName">Configurable URL</Field>

        <Field Name="TypeShortDescription">Configurable URL</Field>

        <Field Name="UserCreatable">TRUE</Field>

        <Field Name="ShowInListCreate">TRUE</Field>

        <Field Name="ShowInSurveyCreate">TRUE</Field>

        <Field Name="ShowInDocumentLibraryCreate">TRUE</Field>

        <Field Name="ShowInColumnTemplateCreate">TRUE</Field>

        <Field Name="FieldTypeClass">SampleConfigurableField.ConfigurableUrlField, SampleConfigurableField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3de2414d286dff3d</Field>

        <PropertySchema>

            <Fields>

                <Field Name="HowOpenUrl" DisplayName="Choose how to open the URL ('Self' = within same window, 'New' = New Window" Type="Text">

                    <Default>Self</Default>

                </Field>

            </Fields>

        </PropertySchema>

        <RenderPattern Name="DisplayPattern">

            <FieldSwitch>

                <Expr>

                    <Property Select='HowOpenUrl'/>

                </Expr>

                <Case Value="Self">

                    <HTML><![CDATA[<a target="_self" href="]]></HTML>

                    <Column HTMLEncode="TRUE" />

                    <HTML><![CDATA[">]]></HTML>

                    <Column HTMLEncode="TRUE" />

                    <HTML><![CDATA[</a>]]></HTML>

                </Case>

                <Case Value="New">

                    <HTML><![CDATA[<a target="_blank" href="]]></HTML>

                    <Column HTMLEncode="TRUE" />

                    <HTML><![CDATA[">]]></HTML>

                    <Column HTMLEncode="TRUE" />

                    <HTML><![CDATA[</a>]]></HTML>

                </Case>

                <Default>

                    <Column HTMLEncode="TRUE" />

                </Default>

            </FieldSwitch>

        </RenderPattern>

    </FieldType>

</FieldTypes>

After creating a Class Library project and adding the proper reference to Microsoft.SharePoint I added the following code to define my ConfigurableUrlField. This field derives from the SPFieldURL class which is important because we defined in Code 1 that our ParentType is "URL". Like all custom fields we need to create the two proper constructors which not only allow our type to be constructed but properly instantiates the base type. Next we need to override the OnAdded() and OnUpdated() methods which each get called whenever this field definition is added to a new site column or when the site column definition is updated, for example when someone wants to change from a rendering of this field from "Self" to "New". The magic all happens in ConfigureSchemaXml(), this is where we access the base.SchemaXml and update it with our custom property's value as configured by the user. This is the only chance we get to manipulate the schema before being stored in the DB and used to render the field. Note the name of the attribute being added/updated needs to match the name being used within the FieldSwitch: <Property Select='HowOpenUrl'/>

Code 2 – ConfigurableUrlField.cs

namespace SampleConfigurableField

{

using System;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

using System.Xml;

public class ConfigurableUrlField : SPFieldUrl

{

bool _updating = false;

public ConfigurableUrlField(SPFieldCollection fields, string fieldName)

: base(fields, fieldName) { }

public ConfigurableUrlField(SPFieldCollection fields, string typeName, string displayName)

: base(fields, typeName, displayName) { }

public override void OnUpdated()

{

//ConfigureSchemaXml() will cause the OnUpdated event to be raised,

//to keep out of a stack overflow condition we bail early when updating

if (_updating)

return;

_updating = true;

{

base.OnUpdated();

ConfigureSchemaXml();

}

_updating = false;

}

public override void OnAdded(SPAddFieldOptions op)

{

base.OnAdded(op);

ConfigureSchemaXml();

}

void ConfigureSchemaXml()

{

string howOpenUrl = (string)base.GetCustomProperty("HowOpenUrl");

howOpenUrl = AreStringsEqual("New", howOpenUrl) ? "New" : "Self";

XmlDocument doc = new XmlDocument();

doc.LoadXml(base.SchemaXml);

if (doc.FirstChild.Attributes["HowOpenUrl"] == null)

{

XmlAttribute attrib = doc.CreateAttribute("HowOpenUrl");

attrib.Value = howOpenUrl;

doc.FirstChild.Attributes.Append(attrib);

}

else

{

doc.FirstChild.Attributes["HowOpenUrl"].Value = howOpenUrl;

}

base.SchemaXml = doc.OuterXml;

}

private bool AreStringsEqual(string s1, string s2)

{

return (String.Compare(s1, s2, true) == 0);

}

public override BaseFieldControl FieldRenderingControl

{

get

{

BaseFieldControl fldControl = new UrlField();

fldControl.FieldName = InternalName;

return fldControl;

}

}

}

}

For completeness I have included the manifest.xml used for deployment of the solution. I will not go over that here since the concept is covered in so many other places.

Code 3 – manifest.xml

<?xml version="1.0" encoding="utf-8" ?>

<Solution xmlns="http://schemas.microsoft.com/sharepoint/"

SolutionId="733641DA-95D9-446E-812E-6070947171B2"

DeploymentServerType="WebFrontEnd"

ResetWebServer="TRUE">

    <Assemblies>

        <Assembly DeploymentTarget="GlobalAssemblyCache" Location="SampleConfigurableField.dll">

            <SafeControls>

                <SafeControl Namespace="SampleConfigurableField" TypeName="*" Safe="True" />

            </SafeControls>

        </Assembly>

    </Assemblies>

    <TemplateFiles>

        <TemplateFile Location="XML\fldtypes_Sample.xml"/>

    </TemplateFiles>

</Solution>

Once we have our solution added and deployed within our farm it is time to use the field. I created a test list and added a new column based on the Configurable URL field I just deployed. Note the open to set how the URL will open within the browser.

 

Now back at my list I create a new list item – note that we did not create a custom field control but rather are using the SPFieldUrl's field control for editing of this field.

Finally we can see the URL in action. Obviously an image does not do it justice but if I look at the HTML source I can find what actually got rendered:

<a target="_self" href="http://www.msn.com" href="http://www.msn.com">http://www.msn.com</a>