using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.SharePoint; // dll that contains SPField classes.
using Microsoft.SharePoint.WebControls; // dll that contains the class of BaseFieldControl.
using System.Web.UI.WebControls;
using System.Threading;
namespace SpCustomFields
{
/*this is the first class we have that represents the SPField and how its rendered
and how its value is shown to users. it should inherit from the same field as you want to represent
for example if you are going to make a text box you should inherit from SPTextField , or if its
a dropdown you should inherit from SPFieldChoice and so on ... */
public class DropDownField : SPFieldChoice
{
/*constructor of the class DropDownField , represents the constructor of
the custom field it self , it will be called when you create a new custom field
in sharepoint , and the parameters passed to this constructor
are ( the control it self , and the title of it ). the both constructors must inherit
from the base which means that you will invoke the base constructor*/
public DropDownField(SPFieldCollection spFieldCollection, string spName)
: base(spFieldCollection, spName)
{ }
/* another constructor of the DropDownField class which takes 3 parameters , and they are the control it self
and its title and the display name*/
public DropDownField(SPFieldCollection spFieldCollection, string spName, string spDisplay)
: base(spFieldCollection, spName, spDisplay)
{ }
/*this function is called to create an instance from DropDownImplementation class that represents our control code behind
and it returns as the control will be used.*/
public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl dropDown = new DropDownImplementation();
dropDown.FieldName = this.InternalName;
return dropDown;
}
}
/* function that used to get the field value to save it , in the list physically so any validations could be made here
before you return the value to be saved , as here we make a validation on the dropdown , so if its required the
user must choose one of the items rather than the first item which is empty and here to show a label to the
user when the validation fails we throw an exception called SPFieldValidationException that shows this label
and prevents saving */
public override object GetFieldValue(string value)
{
if (this.Required == true && string.IsNullOrEmpty(value))
{
throw new SPFieldValidationException("You must specify a value before saving");
}
return base.GetFieldValue(value);
}
}
/* this is the second class that represents the code behind of our control , and it inherits from BaseFieldControl */
public class DropDownImplementation : BaseFieldControl
{
//our control
DropDownList ServicesDropDown;
// returns the template name. used to load the user control and detect its rendering template.
//must be the same as the id of our RenderingTemplate used in our .ascx file.
protected override string DefaultTemplateName
{
get
{
return "DropDownRenderingTemplate";
}
}
//function used to focus on our control.
//the function EnsureChildControls() is used to be sure that the controls are rendered and didnt return null.
public override void Focus()
{
EnsureChildControls();
base.Focus();
ServicesDropDown.Focus();
}
//function used to create the controls, here you will need to specify the controls you need to render them in
//each case like when creating new item or editing an existing one.
protected override void CreateChildControls()
{
base.CreateChildControls();
//TemplateContainer represents our loaded .ascx so we can search the ID of our dropdown and use it.
ServicesDropDown = (DropDownList)TemplateContainer.FindControl("ServicesDropDown");
//ControlMode represents our control mode such as adding new item or editing an existing one.
//the modes are stored in enum called SPControlMode.
if (ControlMode == SPControlMode.New || ControlMode==SPControlMode.Edit)
{
//this code gets the list name entered by the user as a description or
//additional data when creating the new column and "ListName" represents the
//the name of the text box that the user will enter the list name in that
//created in the xml file.
string lstName = (string)this.Field.GetCustomProperty("ListName");
ServicesDropDown = FillInDropdown(ServicesDropDown, lstName);
}
}
//our function used to get the items of the dropdown from another list depending on the
//current culture.
private DropDownList FillInDropdown(DropDownList ServicesDropDown,string lstName)
{
SPList drpDownLst = SPContext.Current.Site.RootWeb.Lists[lstName];
if (drpDownLst != null)
{
ServicesDropDown.Items.Add(string.Empty);
foreach (SPListItem itm in drpDownLst.Items)
{
if (Thread.CurrentThread.CurrentCulture.ToString().ToLower().Contains("ar"))
{
ServicesDropDown.Items.Add((string)itm["Title"]);
}
else
{
ServicesDropDown.Items.Add((string)itm["TitleEnglish"]);
}
}
}
return ServicesDropDown;
}
//this property is used to show data in the list after addition or when editing it assigns the
//control to the data entered before.
public override object Value
{
get
{
EnsureChildControls();
return ServicesDropDown.SelectedValue;
}
set
{
EnsureChildControls();
ServicesDropDown.SelectedValue=(string)ItemFieldValue ;
}
}
}
}
now we are going to see the last file we have , and this file is very important , because it combines all the files we have to work together .