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

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 风渐寒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>