Freitag, 30. Juli 2010

Sharepoint Designer workflow does not react on if -> else if

Wenn in dem Schritt, welchen Sie bearbeiten ein Approvalprozess gestartet wird und folgende Abfrage stattfindet:
If Aktuelles Element:Approval Status equals 1;#Rejected,
diese aber im Workflow nie abgehandelt wird, liegt es daran, dass der Statuswert nicht gesetzt wird.
Man muss sich das so vorstellen, dass der Approval Prozess ebenfalls aus einem Workflow besteht und man dort
definieren muss, was passieren soll, bzw. welche Werte wo gesetzt werden müssen, damit es funktioniert.
Ein simpler Workflow von mir sah so aus:

When there is the following if-clause in the apporval process, that you started:
If Current Element:Approval Status equals 1;#Rejected,
but the workflow never reacts on that, then the reason is, that the value is never set.
You have to consider, that the approval-process contains out of a workflow definition itself and you have to define there, what
has to happen, or what values need to be set, to make it work.
A simple workflow of mine looked like that:
WorkflowStep1

Grossansicht anzeigen - Show large image


Dort hatte ich das Problem, dass if und else einfach immer Approved ausgegeben haben. Das ist damit zu erklären, dass
der Prozess an sich immer approved = true ist, ausser der gesamte Workflow wird gelöscht oder beendet.
Was Sie gerne hätten wäre aber, wie der Prozess abgehandelt wurde, ob der Nutzer approved oder rejected hat.
Hierzu den Prozess einmal dort anklicken wie in der Grafik unten, damit man den Workflow des Porzesses bearbeiten kann.

There I had the problem, that if and else always returned approved. The explanation for that is, that the process itself always
returns approved = true, except you delete the workflow or cancel it.
What you want to know is, did the user approve or reject during the process.
Therefore click the process, like the image below shows you, to be able to edit the process itself.
WorkflowStep1

Grossansicht anzeigen - Show large image

Sie gelangen dann in die Eigenschaftenübersicht des Prozesses. Dort befinden sich auf der linken Seite die wichtigsten Einstellungen.
Klicken Sie den 3. Item in der Liste an, dann gelangen Sie in den Prozessworkflow. Der 2. Item könnte auch interessant sein,
wenn Sie Eigenschaften nach dem Prozess definieren wollen.

You will get to the settings overview of this process. On the left hand side you will see the major settings. Click on the 3rd item
in the list, then you will get to the process workflow. The 2nd item might be also very interesting for you,
when you want to set properties after the process happens.
WorkflowStep1

Grossansicht anzeigen - Show large image

WorkflowStep1

Grossansicht anzeigen - Show large image

Wenn Sie den 3. Item geklickt haben, sehen Sie den Workflow und dort gehen Sie bis zum Ende der einzelnen Schritte.
Am Ende befindet sich "When a task completes". Dort müssten Sie die Werte setzen, wie es in der Grafik markiert hervorgehoben
wird.

When you clicked on the 3rd item, you see the workflow and there go to the last step. There you will find the "When a task completes" step.
There you have to set the values, like I highlighted in the image below.
WorkflowStep1

Grossansicht anzeigen - Show large image

Dadurch werden die Werte während des Approvalprozesses gesetzt und man kann diese dann im eigenen Workflow auslesen und verwenden.

This way, the values are set during the approval-process and you can use those in your own workflow.

Donnerstag, 29. Juli 2010

Timer job and workflow - timer job does not execute workflow

Wenn der Timer Job keinen Workflow auslöst, liegt das daran, dass der Timer Job evtl. vom System Account gesteuert wird und dieser (siehe vorheriger Post) den Workflow überspringt. Deshalb am besten einen eigenen User einrichten, mit System Account Rechten und über diesen den Timer Job laufen lassen.

If your timer-job does not execute a workflow, the reason might be, that the timer-job is handled through the system-account (check previous post). Therefore it might be best, to create a new user with the same permissions like the system-account, and let this one execute the timer-job.

Code not running - Code funktioniert nicht

Liebe Leser dieses Blogs (sind mittlerweile erstaunlicherweise 300 pro Monat), sollte es vorkommen, dass ein Code, welchen ich publiziere, nicht funktioniert, wäre ich über eine kurze Nachricht oder einen Kommentar dankbar.

Dear reader of this blog (I was surprised, that there are more than 300 each month), when a code, that I published, is not working, let me know in sending me a message or leave a comment.

Workflow does not start when list item is created or edited

Workflow does not start when list item is created or edited - Workflow automatisch starten wenn ein Element erstellt/geändert wird funktioniert nicht.

In meinem Fall habe ich im Sharepoint Designer angegeben, dass der Workflow automatisch bei Änderung oder neuem Element gestartet werden soll. Das hat er während meiner Tests nicht gemacht. Grund hierfür ist folgender: Workflows werden nicht gestartet, wenn es sich um den System Account handelt, der Elemente ändert oder neu einstellt. Einfach mit einem anderen Account einloggen und nochmals probieren.

In my case I have set in the Sharepoint Designer, that the workflow is supposed to start automatically, when a new item is created or an item changed. This did not work in my testing. Reason therefore was: workflows are not running automatically, when the system-account is doing those changes or creates new items. Login with a different user and try again.

Donnerstag, 22. Juli 2010

Create your custom webpart property - eigene Webpart Eigenschaft erstellen

Wenn man ein eigenes Webpart entwickelt, kommt es vor, dass man zur Darstellung Daten vom Webpartnutzer benötigt um Inhalte vollständig anzuzeigen. Hierzu gibt es beim Bearbeiten des Webparts die Eigenschaften, welche Einstellungen am webpart vornehmen.
Dieser Blogpost soll zeigen, wie man diese Eigenschaften mit eigenen Eigenschaften erweitert.
Man erstellt zuerst ein neues Visual Webpart in Visual Studio 2010. Das Visual Webpart erstellt eine .cs Datei in gleicher Hierarchie, wie die .webpart Datei.

When you develop your own webpart, there might be the need to gather data from the webpart-user to display content correctly.
Therefore the webpart does have the properties you see, when clicking "edit webpart", that set things of the webpart.
This blog-post is supposed to show, how you can extend those properties with custom properties.
First you have to create a new Visual Webpart in Visual Studio 2010. This Visual Webpart creates a .cs file in the same directory level like the .webpart file.

sharepoint project


Öffnen Sie diese Datei und dann können Sie zu der VisualWebPart1 Klasse folgende Eigenschaft hinzufügen:

Open this file and then you can add to the VisualWebPart1 class the following property:

[WebBrowsable(true), Category("Own Category"), Personalizable(PersonalizationScope.Shared), DefaultValue(""), WebDisplayName("Property Title"), WebDescription("Property Description")]
public string MyCustomProperty
{
get { return _mycustomproperty; }
set { _mycustomproperty = value; }
}
public static string _mycustomproperty;

Category definiert die Kategorie, in welche die Eigenschaft angezeigt wird. Man kann hier auch eine eigene Kategorie erstellen.
Einfach hier einen neuen Namen hineinschreiben. Alle anderen Eigenschaften der Eigenschaft sprechen für sich und können mit anderen Inhalten getestet werden.

Category defines the category, where the property will be displayed. You can create also your own category. Just enter a new name. All other properties of this property talk for themselves and can be tested with different content.

Im VisualWebPart1UserControl.ascx.cs kann man einfach wie folgt auf diese Eigenschaft zugreifen:

In the VisualWebPart1UserControl.ascx.cs file you can access this property easily like that:

litOutput.Text = VisualWebPart1._mycustomproperty;


Deployen Sie jetzt das Webpart und dann gehen Sie auf "Webpart bearbeiten". Sie sehen dann einen eigenen Reiter und in diesem die Eigenschaft. Geben Sie etwas ein und wenn Sie den Wert im Webpart Usercontrol ausgeben, werden Sie ihn auf der Webseite sehen.

Deploy the webpart and then go to "Edit webpart". You will see your own tab and in there your property. Enter something and if you output the value in the webpart usercontrol, you will see something in the webpage.

Grundsätzlich werden bei folgenden Eigenschaften folgende Controls erstellt:

Basically the following properties generate the following controls:
bool -> Check box
DateTime -> Text box
enum -> Dropdown
int -> Text box
string -> Text box

Aber was macht man, wenn man z.B. Radiobuttons oder andere Controls verwenden will? Dann kann man diese auch selbst erstellen.
In der VisualWebpart1.cs Datei muss die VisualWebpart1 Klasse von folgender Klasse erben: Microsoft.SharePoint.WebPartPages.WebPart.
Anschliessend die GetToolParts() Methode überschreiben.

But what if you want to use controls like radio-buttons or other controls? You can create them on your own.
In the VisualWebpart1.cs file the VisualWebpart1 class needs to inherit from this class: Microsoft.SharePoint.WebPartPages.WebPart.
Then you need to override the GetToolParts() method.

public override ToolPart[] GetToolParts()
{
ToolPart1 mytoolpart = new ToolPart1();
mytoolpart.Title = "My Tab";

List lstToolParts = new List(base.GetToolParts());
lstToolParts.Insert(0, mytoolpart);
return lstToolParts.ToArray();
}


Dieser Code wird die ToolPart1 Klasse dem bestehenden Array hinzufügen, der aus den Default Toolparts besteht.
Dann müssen wir nur noch die ToolPart1 Klasse erstellen.

This code will add the ToolPart1 class to the existing array, that already contains the default toolparts.
Then we need to create the ToolPart1 class.


public class ToolPart1 : Microsoft.SharePoint.WebPartPages.ToolPart
{
public ToolPart1()
{
}

private RadioButtonList myRadioButtons = new RadioButtonList();

//Override the method to create the existing controls and then add your control
protected override void CreateChildControls()
{
base.CreateChildControls();
myRadioButtons.ID = "myRadioButtons";
myRadioButtons.Items.Add("Item 1");
myRadioButtons.Items.Add("Item 2");
myRadioButtons.Items.Add("Item 3");
myRadioButtons.Items.Add("Item 4");
this.Controls.Add(myRadioButtons);
}

//This method happens, when someone will click "OK" or "Apply" and the value will be added to the webpart class-property
public override void ApplyChanges()
{
base.ApplyChanges();
VisualWebPart1 parentWebPart = (VisualWebPart1)this.ParentToolPane.SelectedWebPart;
if (!string.IsNullOrEmpty(myRadioButtons.SelectedItem.Value))
parentWebPart.MyCustomProperty = myRadioButtons.SelectedItem.Value;
}
}


Das war alles. Man kann den Code anpassen und abändern und so ziemlich jedes Control selbst einfügen. Auch Telerikcontrols können hier verwendet werden.

This is it. You can edit or extend this code and insert almost any control. You can also add Telerik controls.

Mittwoch, 21. Juli 2010

Create custom timer-job - einen benutzerdefinierten Time-Job in Sharepoint 2010 erstellen

Um einen benutzerdefinierten TimerJob zu erstellen, einfach ein neues Visual Webpart Projekt im Visual Studio 2010 erstellen.
Dort braucht es dann nur eine Klassendatei, welche den Job definiert, so dass die Struktur wie folgt aussieht:

To create a custom timer-job, you just create a new Visual Webpart project in Visual Studio 2010.
There you just need one class-file, that defines the job, so the structure will look like this:
sharepoint project

Grossansicht anzeigen - Show large image


Was man noch benötigt ist den Feature.EventReceiver. Diesen erstellt man, in dem man auf die .feature Datei rechts klickt und
dort, wie in der Grafik unten, Add EventReceiver anklickt. Diese Datei enthält Code, welcher den Job initialisieren wird und
in diversen state-levels Code ausführen kann.

What you need then is an event-receiver. You can create on, in right clicking on the .feature file, like shown in the image,
and click on "Add EventReceiver". This file contains code, that will initialize the job and you can add code to different state-levels
to run code.
sharepoint project

Grossansicht anzeigen - Show large image


When das Projekt deployed wurde, kann man unter Site Settings -> Site collection features den Job aktivieren.

When you deployed the project, you can activate the job under site-settings -> site collection features.
sharepoint project

Grossansicht anzeigen - Show large image


Sobald dieser aktiviert ist, muss er unter Central Administration -> Monitoring -> Check job status -> Job Defenitions sichtbar sein.
(Seite hat meist mehrere Seiten)

As soon as the job is activated, it is supposed to be visible under central administration -> monitoring -> check job-status -> job-defenitions.
(Page usually has more pages)

In der linken Navigation befinden sich Punkte, welche man durchklicken kann und sieht, ob und wann der Job gelaufen ist, oder
laufen wird.

The left-hand side navigation has topics, that you can click through. There you can see if and when a job is run or will be run.
sharepoint project

Grossansicht anzeigen - Show large image


In die EventReceiver Datei kommt in die Methode FeatureActivated folgender Code zum initialisieren des Jobs:
Into the EventReceiver file, into the FeatureActivated method, you can add the following code to initialize the job:

SPSite spSite = (SPSite)properties.Feature.Parent;

SPWebApplication webApp = spSite.WebApplication;
//SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

if (webApp == null)
throw new SPException("Error obtaining reference to Web application.");

// Ensure the job is not already registered.
foreach (SPJobDefinition job in webApp.JobDefinitions)
{
if (job.Name == JOB_NAME)
{
job.Delete();
}
}

// Install job.
MyCustomTimerJob customTimerJob = new MyCustomTimerJob(webApp);
// Schedule the job to run every 5 minute all the time.
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
customTimerJob.Schedule = schedule;
// Save changes.
customTimerJob.Update();


In die FeatureDeactivating Methode kommt dieser Code:
Into the FeatureDeactivating method you can add this code:

SPSite spSite = (SPSite)properties.Feature.Parent;

SPWebApplication webApp = spSite.WebApplication;
foreach (SPJobDefinition job in webApp.JobDefinitions)
if (job.Name == JOB_NAME) job.Delete();


In die MyCustomTimerJob.cs Datei wird folgender Code eingefügt:
Insert the following code into the MyCustomTimerJob.cs file:

public class MyCustomTimerJob : SPJobDefinition
{
private static const string JOB_NAME = "MyCustomTimerJob";
public MyCustomTimerJob() : base() { }
public MyCustomTimerJob(SPWebApplication webApp)
: base(JOB_NAME, webApp, null, SPJobLockType.Job)
{
Title = JOB_NAME;
}

public override void Execute(Guid targetInstanceId)
{
//Code here, what the timer job is supposed to do
}
}


TIP:
Versuchen Sie in der Execute Methode eine Assembly oder ein Objekt aufzurufen, Hier nicht unbedingt den ausführenden Code einfügen.
Try to call just some assemblies and objects from the Execute method. Don't put the execution code directly in there.

Donnerstag, 8. Juli 2010

Custom Timer Job - Access denied when activating

Sie haben einen Custom-Timer-Job erstellt und wollen diesen jetzt aktivieren, bekommen aber eine "Access denied" Fehlermeldung. Dann loggen Sie sich bitte einmal in den Sharepoint bzw. die Site Collection Administration mit dem Account ein, welcher auch die Application Pools verwaltet. So hat es bei mir funktioniert.
FBA kann zu Fehlern führen, man sollte es mit Windows Authentifizierung probieren. Ebenso kann es sein, dass wenn der Application Pool Ping Enable false hat, dass dies ein Fehler sein kann.

You have created a custom-timer-job and you want to activate it now, but receive the "access denied" error-message. Then login into Sharepoint, the Site Collection Administration, with the account that you are using to run the application-pools with. This worked for me.
FBA can also create this error, you are supposed to login with Windows authentication. In addition, it can be that ping enable = false in the application-pool settings, executes this error message.

Error occurred in deployment step recycle IIS Application Pool provider load failure

Wenn Sie in Visual Studio 2010 ein Projekt deployen wollen und dies an der oben genannten Fehlermeldung scheitert, dann einfach unter Windows Services -> den Sharepoint 2010 Administration Service neu starten. Ich hatte dieses Problem, nachdem ich in der Domäne mein Passwort ändern musste. Ich vermute einmal, dass evtl. das alte Password hängen blieb und dadurch meine Rechte für den Zugriff auf den Application Pool Recycle nicht gewährleistet waren.

If you want to deploy a project in Visual Studio 2010 and you get the error mentioned above in the headline, then just go to the windows services -> choose the Sharepoint 2010 Administration Service and restart this one. I had this problem after having to change my password in the domain. I asume it could be, that the old password was still stuck somewhere and I had not the permission to recycle the app-pool.

Mittwoch, 7. Juli 2010

Create a custom field-type - ein benutzerdefiniertes Field-type erstellen

Wie man ein benutzerdefinierten FieldType erstellt.
Es kommt vor, dass man beim Erstellen einer Spalte in einer Liste gerne einen FieldType hätte, der benutzerdefiniert ist, weil man vielleicht Daten separat speichern will oder eine Interaktion durchführen. Hierzu kann man einen Feldtyp benutzerdefinieren.
Als erstes ein leeres Sharepointprojekt in Visual Studio 2010 erstellen. Dann die folgenden Punkte durchgehen:

How to create a custom field-type.
Sometimes you might want to use a field-type when creating a new column in a list. This can be useful, when wanting to save data in a different place or interact with the data inserted. Therefore you can create a custom field-type.
First create an empty Sharepoint-project in Visual Studio 2010 and then follow this instruction:

1. Mappen Sie folgende Sharepoint Ordner, indem man das Projekt mit rechter Maustaste -> Hinzufügen -> Sharepointverzeichnis mappen anklickt.
Map the following sharepoint-directories, in clicking the project with the right mouse-key -> Add -> Sharepoint Mapped Folder
map the sharepoint folders

Grossansicht anzeigen - Show large image


2. Bitte folgende Verezichnisse mappen: Template\Controltemplates, Template\XML, Template\Layouts\XSL
Please map the following folders: : Template\Controltemplates, Template\XML, Template\Layouts\XSL

3. Fügen Sie Ihrem Projekt 3 Klassendateien hinzu: [Ihr Name].Field.cs, [Ihr Name].FieldControl.cs, [Ihr Name].ValidationRule.cs
Then add three class-files to your project: [Your name].Field.cs, [Your name].FieldControl.cs, [Your name].ValidationRule.cs

!!Hinweis: [Ihre Name].FieldControl.cs wird die Codebehinddatei Ihres Usercontrols!!
!!Hint: [Your name].FieldControl.cs will be the code-behind file of your user-control!!

4. Fügen Sie den mapped Verzeichnissen folgende Dateien hinzu, so dass zum Schluss Ihr Projekt wie folgt aussieht: [Ihr Name]FieldControl.ascx (CONTROLTEMPLATES), fldtypes_[Ihr Name].xml (XML), fldtypes_[Ihr Name].xsl (XSL)
Add the following files to your mapped folders, so your project will look like this: [Your name]FieldControl.ascx (CONTROLTEMPLATES), fldtypes_[Your name].xml (XML), fldtypes_[Your name].xsl (XSL)
sharepoint project

Grossansicht anzeigen - Show large image


5. Fügen Sie die Referenzen hinzu, welche in der Grafik angezeigt werden.
Add the references shown in the image.
references

Grossansicht anzeigen - Show large image



Verantwortlichkeiten:
Responsibilities:
- Wenn man Neu, Bearbeiten oder Anzeigen eines Listitems anklickt, erscheint ein Fenster. Zuständig für diese Anzeige ist die ascx Datei.
When clicking new, edit or display of a list-item, then a window opens. Responsible for the display style is the ascx file.
- Wie der Item in der Liste angezeigt wird, das regelt die xsl Datei.
How the item will be displayed in the list, that is handled through the xsl file.
- Die Eigenschaften, sowie die Bezeichnung links, neben dem ascx Inhalt, wird in der xml Datei bearbeitet.
The properties, and the name on the left side, next to the ascx content, will be defined in the xml file.
Hier eine Grafik zu der Erklärung:
Here you see an image to the explanation:
Overview diagram

Grossansicht anzeigen - Show large image



5. In der ascx Datei definieren Sie über die Rendering Templates die Darstellung in den verschiedenen Modi.
In the ascx file you define through the rendering-templates the different display variations in the different modes.
Ascx file

Grossansicht anzeigen - Show large image


6. Die folgenden Grafiken zeigen die Formatierung der XML und XSL Datei.
The following images show you the format of the xml and xsl file.
XML and XSL file

Grossansicht anzeigen - Show large image

XML and XSL file

Grossansicht anzeigen - Show large image


Hier ein Beispiel Code für die [Ihr Name].Field.cs.
Here is a sample code for the [Your name].Field.cs.

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;

using System.Windows.Controls;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace [Your namespace]
{
public class MyCustomField : SPField
{
//You have to use those constructors. Leave them like they are or extend with custom code if you need to.
public MyCustomField(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}

public MyCustomField(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
}

//This method will call and start render the control. You can keep it this way.
public override BaseFieldControl FieldRenderingControl
{
[SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
get
{
//In case your control does have a different name, initialize it here
BaseFieldControl fieldControl = new MyCustomFieldControl();
fieldControl.FieldName = this.InternalName;
return fieldControl;
}
}

//This method validates the value. The validation-class will be initialized (MyCustomFieldValidationRule)
//That means you can leave everything, like it is, just be sure your correct validation-class is called
public override string GetValidatedString(object value)
{
if ((this.Required == true)
&&
((value == null)
||
((String)value == "")))
{
throw new SPFieldValidationException(this.Title
+ " must have a value.");
}
else
{
//Your custom validation class is supposed to be called here
MyCustomFieldValidationRule rule = new MyCustomFieldValidationRule();
ValidationResult result = rule.Validate(value, CultureInfo.InvariantCulture);

if (!result.IsValid)
{
throw new SPFieldValidationException((String)result.ErrorContent);
}
else
{
return base.GetValidatedString(value);
}
}
}
}
}



Hier ein Beispiel Code für die [Ihr Name].FieldControl.cs.
Here is a sample code for the [Your name].FieldControl.cs.

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;

using System.Runtime.InteropServices;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace [Your namespace]
{
public class MyCustomFieldControl : BaseFieldControl
{
protected global::System.Web.UI.WebControls.Label AdditionalInfoNew;
protected global::System.Web.UI.WebControls.TextBox TextFieldNew;
protected global::System.Web.UI.WebControls.Label AdditionalInfoEdit;
protected global::System.Web.UI.WebControls.TextBox TextFieldEdit;
protected global::System.Web.UI.WebControls.Label AdditionalInfoDisplay;
protected global::System.Web.UI.WebControls.Label DisplayText;

//This method initializes the correct rendering-template, depending on the mode.
protected override string DefaultTemplateName
{
get
{
if (this.ControlMode == SPControlMode.Display)
{
//This template will be called, if the mode is display
return this.DisplayTemplateName;
}
else if (this.ControlMode == SPControlMode.Edit)
{
//This template will be called, if the mode is edit
return "RenderingTemplateEdit";
}
else
{
//This template will be called, if the mode is new or invalid, you can also set one for each
return "RenderingTemplateNew";
}
}
}

//You need to override this template-name, otherwise there seems to be a default one and your web-controls won't be recognized in the
//CreateChildControls method and it will throw an exception. Tell explicit, which renderingtemplate to use for display.
public override string DisplayTemplateName
{
get
{
return "RenderingTemplateDisplay";
}
set
{
base.DisplayTemplateName = value;
}
}

//This method creates the child-controls and runs some major code.
protected override void CreateChildControls()
{
if (this.Field != null)
{
//Make sure inherited child controls are completely rendered.
base.CreateChildControls();

//Associate child controls in the .ascx file with the
//fields allocated by this control.
this.AdditionalInfoNew = (Label)TemplateContainer.FindControl("AdditionalInfoNew");
this.TextFieldNew = (TextBox)TemplateContainer.FindControl("TextFieldNew");
this.AdditionalInfoEdit = (Label)TemplateContainer.FindControl("AdditionalInfoEdit");
this.TextFieldEdit = (TextBox)TemplateContainer.FindControl("TextFieldEdit");
this.AdditionalInfoDisplay = (Label)TemplateContainer.FindControl("AdditionalInfoDisplay");
this.DisplayText = (Label)TemplateContainer.FindControl("DisplayText");

//This code runs if not display mode
if (this.ControlMode != SPControlMode.Display)
{
if (!this.Page.IsPostBack)
{
if (this.ControlMode == SPControlMode.New)
{
//The method 'GetCustomProperty' gets the value set, that depends on the property-schema field in the xml.
this.TextFieldNew.Text = (String)base.Field.GetCustomProperty("MyPropertyintheXML");
this.AdditionalInfoNew.Text = "You are in 'new' mode: ";
//!!!Take care to use the correct controls, otherwise there won't be anything visible!!!!!!
}

else if (this.ControlMode == SPControlMode.Edit)
{
//The method 'GetCustomProperty' gets the value set, that depends on the property-schema field in the xml.
this.TextFieldEdit.Text = (String)base.Field.GetCustomProperty("MyPropertyintheXML");
this.AdditionalInfoEdit.Text = "You are in 'edit' mode: ";
//!!!Take care to use the correct controls, otherwise there won't be anything visible!!!!!!
}
}

}
else
{
//Assign current value from database to the label control
if (!string.IsNullOrEmpty(this.ItemFieldValue.ToString()))
DisplayText.Text = (String)this.ItemFieldValue;
this.AdditionalInfoDisplay.Text = "You are in 'display' mode: ";
//!!!Take care to use the correct controls, otherwise there won't be anything visible!!!!!!
//!!!Exception? web-controls are not recognized? then check if the property is overriden: DisplayTemplateName !!!!!!
}
}
}

//The value object is the final value that will be stored in the list-column.
public override object Value
{
get
{
EnsureChildControls();
//Here you return the value, that finally will be written into the column value.
//Start custom code ************************************************************************

//End custom code **************************************************************************
return "[This is the column value]";
}
}

//The UpdateFieldValueInItem method stores the value in the database and runs code, that needs to be done before doing the update and finalizing the insert.
public override void UpdateFieldValueInItem()
{
Page.Validate();
if (Page.IsValid)
{
//Code that is supposed to be executed before everything is stored and the update is done.
//Start custom code ************************************************************************

//End custom code **************************************************************************
base.UpdateFieldValueInItem();
}
else
{
//Code that is supposed to be executed in case the page is not valid and the update failed.
}
}
}
}



Hier ein Beispiel Code für die [Ihr Name].ValidationRule.cs.
Here is a sample code for the [Your name].ValidationRule.cs.

namespace [Your namespace]
{
public class MyCustomFieldValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
//The overloaded value is the one you have to validate against.
//Start custom code ************************************************************************

//End custom code **************************************************************************
//Your custom code needs to return a ValidationResult like the one below. Set either true or false and an error-message
//in your code to return, depending on your validation.
return new ValidationResult(true, "Everything is OK.");
}
}
}