How do we embed our custom logic into PeoplePicker control? Implemented exampleshows how to create people picker with user selection limited to a particulardepartment.
1) First we need to create control inherited from Microsoft.SharePoint.WebControls.PeopleEditor class
public classMyPeopleEditor : PeopleEditor
{
public string Department { get; set; }
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
PickerDialogType = typeof(MyPeoplePickerDialog);
}
public override PickerEntity ValidateEntity(PickerEntityentity)
{
entity.IsResolved =string.IsNullOrEmpty(Department) || ((entity.EntityData["Department"]as string) == Department);
return entity;
}
}
In the custom control, we should overrideOnInit and ValidateEntity functions. In OnInit() method, we should setPickerDialogType to our custom dialog class, in ValidateEntity we shouldimplement our custom validation logic. We also check if the user is from theright department.
2) We need to create custom people pickerdialog class inherited from Microsoft.SharePoint.WebControls.PickerDialog
public classMyPeoplePickerDialog : PickerDialog
{
public MyPeoplePickerDialog()
: base(new MyUserQueryControl(), newTableResultControl(), new MyPeopleEditor())
{
ArrayList columnDisplayNames =((TableResultControl)base.ResultControl).ColumnDisplayNames;
columnDisplayNames.Clear();
columnDisplayNames.Add("Name");
columnDisplayNames.Add("Department");
columnDisplayNames.Add("JobTitle");
ArrayList columnNames =((TableResultControl)base.ResultControl).ColumnNames;
columnNames.Clear();
columnNames.Add("Name");
columnNames.Add("Department");
columnNames.Add("JobTitle");
ArrayList columnWidths =((TableResultControl)base.ResultControl).ColumnWidths;
columnWidths.Clear();
columnWidths.Add("40%");
columnWidths.Add("30%");
columnWidths.Add("30%");
}
}
In this class we should implement one constructor,inherited from constructor of base class. Note - that we need to pass severalcontrols in base construction - first is our custom query control, secondis result control, third is our custom people control, that we've createdearlier. Constructor also contains code for TableResultControl initialization.
3) The last step is to create custom querycontrol, inherited from SimpleQueryControl. This control will implement custombusiness logic for people picker dialog populating.
public classMyUserQueryControl : SimpleQueryControl
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
mColumnList.Visible = false;
if (!Page.IsPostBack)
{
IssueQuery(string.Empty, string.Empty, 0, 0);
}
}
DataTableConvertProfilesToDataTable(IEnumerable<userprofile> profiles)
{
DataTable table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("Department");
table.Columns.Add("AccountName");
table.Columns.Add("JobTitle");
table.Columns.Add("Email");
table.Columns.Add("SIPAddress");
table.Columns.Add("WorkPhone");
foreach (UserProfile profile inprofiles)
{
DataRow row= table.NewRow();
row["Name"] = profile.DisplayName;
row["Department"] = profile[PropertyConstants.Department].Value;
row["AccountName"] = profile[PropertyConstants.AccountName].Value;
row["JobTitle"] = profile[PropertyConstants.JobTitle].Value;
row["Email"] = profile[PropertyConstants.WorkEmail].Value;
row["SIPAddress"] = profile[PropertyConstants.SipAddress].Value;
row["WorkPhone"] = profile[PropertyConstants.WorkPhone].Value;
table.Rows.Add(row);
}
return table;
}
protected IEnumerable<userprofile>SearchProfiles(string search, string department)
{
SPServiceContext context =SPServiceContext.GetContext(SPContext.Current.Site);
UserProfileManagerprofileManager = new UserProfileManager(context);
string[] patterns = (from p in(new string[] {search, department})
where !string.IsNullOrEmpty(p)
select p).ToArray();
IEnumerable<userprofile>res = null;
if (patterns.Count()> 0)
{
//execute query
ProfileBase[] searchResult = profileManager.Search(patterns);
res =from p in searchResult
where (p is UserProfile) &&
(string.IsNullOrEmpty(department)||
(((p as UserProfile)[PropertyConstants.Department].Value as string) ==department))
select (p as UserProfile);
}
else
{
//getall profiles
List<userprofile> profiles = new List<userprofile>();
foreach (UserProfile profile in profileManager)
{
profiles.Add(profile);
}
res =profiles;
}
return res;
}
protected override int IssueQuery(string search, stringgroupName, int pageIndex, int pageSize)
{
List<pickerentity>pickerEntities = new List<pickerentity>();
SPWebApplication application =SPContext.Current.Site.WebApplication;
LEPeopleEditor editor =PickerDialog.EditorControl as LEPeopleEditor;
DataTable tablePrinciples =ConvertProfilesToDataTable(SearchProfiles(search, editor.Department));
PickerDialog.Results =tablePrinciples;
PickerDialog.ResultControl.PageSize = tablePrinciples.Rows.Count;
returntablePrinciples.Rows.Count;
}
public override PickerEntity GetEntity(DataRow dr)
{
PickerEntity entity = newPickerEntity();
entity.DisplayText =dr["Name"] as string;
entity.Key =dr["AccountName"] as string;
entity.EntityData["Department"] = dr["Department"] asstring;
entity.EntityData["JobTitle"] = dr["JobTitle"] as string;
entity.EntityData["Email"] = dr["Email"] as string;
entity.EntityData["SIPAddress"]= dr["SIPAddress"] as string;
entity.EntityData["WorkPhone"] = dr["WorkPhone"] as string;
entity.IsResolved = true;
return entity;
}
}
In this class we need tooverride IssueQuery function, which populates PickerDialog.Results andGetEntity which converts DataRow back to entity. In the above example, we seacheduser profiles to get users from specific department.