jueves, 6 de mayo de 2010

Extendiendo el control PeoplePicker

Ahora presentaré un pequeño ejemplo de cómo se puede extender el control People Picker, que tanto gusta a los usuarios, pero que en ciertos escenarios (siempre habrá un usuario anormal) no satisface los requerimientos funcionales al cien por ciento, lo que nos llevará irremediablemente a tirar código.

Al final de esta demostración nos daremos cuenta que al extender este control podemos realizar búsquedas sobre diferentes objetos y/o diferentes fuentes de datos, porque este control no está casado con objetos de tipo SPUser como se podría pensar en primera instancia.

Sin más, pasemos al código.Para poder extender la funcionalidad de este control, basicamente tenemos que heredar de tres clases: EntityEditorWithPicker, PickerDialog y SimpleQueryControl.

Dejemos que el código se explique solo :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Collections;
using Microsoft.SharePoint;

namespace Blog.WebControls
{
    public class CustomPeoplePicker : EntityEditorWithPicker
    {
        protected bool m_onInitCalled;
        protected string m_commaSeparatedAccountsDelayedUntilOnInit;

        public CustomPeoplePicker()
        {

        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            //definimos el tipo del PickerDialog
            this.PickerDialogType = typeof(CustomPickerDialog);

            this.m_onInitCalled = true;

            if (!string.IsNullOrEmpty(this.m_commaSeparatedAccountsDelayedUntilOnInit))
            {
                base.UpdateEntities(this.GetAccountsEntities(this.m_commaSeparatedAccountsDelayedUntilOnInit));
                this.m_commaSeparatedAccountsDelayedUntilOnInit = null;
            }
        }

        /// 
        /// Devuleve la lista de usuarios seleccionados en forma de cadena
        /// 
        ///         /// 
        private string GetResolvedEntityAccounts()
        {
            if (this.ResolvedEntities == null)
            {
                return string.Empty;
            }
            if (this.ResolvedEntities.Count == 0)
            {
                return string.Empty;
            }

            List names = new List();
            string list = string.Empty;
            foreach (PickerEntity entity in this.ResolvedEntities.OfType())
            {
                names.Add(entity.Key);
            }
            list = string.Join(this.EntitySeparator.ToString(), names.ToArray());
            return list;
        }

        protected ArrayList GetAccountsEntities(string commaSeparatedAccounts)
        {
            ArrayList list = new ArrayList();
            if (commaSeparatedAccounts != null)
            {
                foreach (string str in commaSeparatedAccounts.Split(new char[] { this.EntitySeparator }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string str2 = str.Trim();
                    if (!string.IsNullOrEmpty(str2))
                    {
                        PickerEntity entity = new PickerEntity();
                        entity.Key = str2;
                        list.Add(entity);
                    }
                }
            }
            return list;
        }

        /// 
        /// Valida las entidades
        /// 
        ///         /// 
        public override PickerEntity ValidateEntity(PickerEntity needsValidation)
        {
            needsValidation.IsResolved = false; ;

            CustomQueryControl c = new CustomQueryControl();
            foreach (CustomUser user in c.GetPeople())
            {
                if (needsValidation.Key.Equals(user.EmployeeNumber, StringComparison.InvariantCultureIgnoreCase))
                {
                    needsValidation.IsResolved = true;
                }
            }
            return needsValidation;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Collections;

namespace Blog.WebControls
{
    public class CustomPickerDialog : PickerDialog
    {
        public CustomPickerDialog()
            : base(new CustomQueryControl(), new TableResultControl(), new CustomPeoplePicker())
        {
            ArrayList columnDisplayNames = ((TableResultControl)base.ResultControl).ColumnDisplayNames;
            columnDisplayNames.Clear();
            columnDisplayNames.Add("Employee Number");
            columnDisplayNames.Add("Email");
            columnDisplayNames.Add("Name");
            
            ArrayList columnNames = ((TableResultControl)base.ResultControl).ColumnNames;
            columnNames.Clear();
            columnNames.Add("EmployeeNumber");
            columnNames.Add("Email");
            columnNames.Add("Name");
            
            ArrayList columnWidths = ((TableResultControl)base.ResultControl).ColumnWidths;
            columnWidths.Clear();
            columnWidths.Add("20%");
            columnWidths.Add("30%");
            columnWidths.Add("50%");
        }
        protected override void OnLoad(EventArgs e)
        {
            CustomQueryControl control = (CustomQueryControl)this.QueryControl;
            base.OnLoad(e);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Data;

namespace Blog.WebControls
{
    public class CustomQueryControl : SimpleQueryControl
    {
        public CustomQueryControl()
        {
            Load += CustomQueryControl_Load;
        }

        void CustomQueryControl_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                EnsureChildControls();
                mColumnList.Items.Add("EmployeeNumber");
                mColumnList.Items.Add("Name");
                mColumnList.Items.Add("Email");
            }
        }

        protected override int IssueQuery(string search, string groupName, int pageIndex, int pageSize)
        {
            CustomUser[] usersAux = this.GetPeople();
            if (usersAux == null)
                return 0;
            List allPeople = new List(usersAux);
            if (allPeople.Count == 0)
                return 0;

            List searchPeople = new List();
            DataTable resultTable = null;

            searchPeople = allPeople;

            if (groupName == "Name" && !string.IsNullOrEmpty(search))
            {
                searchPeople = allPeople.Where(x => SearchString.Match(x.Name, search)).ToList();
            }
            else if (groupName == "Email" && !string.IsNullOrEmpty(search))
            {
                searchPeople = allPeople.Where(x => SearchString.Match(x.Email, search)).ToList();
            }

            resultTable = GetPeopleTable(searchPeople.ToArray());

            PickerDialog.Results = resultTable;
            PickerDialog.ResultControl.PageSize = resultTable.Rows.Count;

            return resultTable.Rows.Count;
        }

        private DataTable GetPeopleTable(CustomUser[] people)
        {
            DataTable dummyTable = new DataTable();
            dummyTable.Columns.Add("EmployeeNumber");
            dummyTable.Columns.Add("Name");
            dummyTable.Columns.Add("Email");

            foreach (CustomUser person in people)
            {
                DataRow row1 = dummyTable.NewRow();
                row1["Name"] = person.Name;
                row1["EmployeeNumber"] = person.EmployeeNumber;
                row1["Email"] = person.Email;
                dummyTable.Rows.Add(row1);
            }
            return dummyTable;
        }

        string _excludedUsers;

        public string ExcludedUsers
        {
            get
            {
                return this._excludedUsers;
            }
            set
            {
                this._excludedUsers = value;
            }
        }

        public virtual CustomUser[] GetPeople()
        {
            List people = new List();

            //agregar toda la logica necesaria para obtener los usuarios
            people.Add(new CustomUser() { EmployeeNumber = "11111", Email = "juan.topo@contoso.com", Name ="Juan G. Topo" });
            people.Add(new CustomUser() { EmployeeNumber = "22222", Email = "max.power@contoso.com", Name = "Max Power" });
            people.Add(new CustomUser() { EmployeeNumber = "33333", Email = "bambi.venado@contoso.com", Name = "Venado Bambi" });
            people.Add(new CustomUser() { EmployeeNumber = "44444", Email = "homero.simpson@contoso.com", Name = "Homero J. Simpson" });

            return people.ToArray();
        }

        public override PickerEntity GetEntity(DataRow dr)
        {
            PickerEntity entity = new PickerEntity();
            entity.DisplayText = dr["Name"].ToString();
            entity.Key = dr["EmployeeNumber"].ToString();
            entity.Description = dr["Email"].ToString();
            entity.IsResolved = true;
            return entity;
        }
    }
}


Happy Coding!

1 comentarios:

Ricardo M M (THX 1138) dijo...

Excelente artículo y lógica impecable, efectivamente, el código habla por sí mismo.

Saludos

Etiquetas

SharePoint 2010 (38) Microsoft (32) Desarrollo SharePoint (31) Gerardo Reyes Ortiz (27) SharePoint (20) SharePoint 2013 (18) Errores SharePoint (12) México (10) PowerShell (9) Silverlight (8) Visio Services (7) Features (6) MVP (6) Silverlight 3 (6) WebCast (6) Workflows (6) Configuracion SharePoint 2010 (5) D.F. (5) API REST (4) Configuracion SharePoint 2010; (4) Troubleshooting (4) Visual Studio 2010 (4) Visual studio (4) WSS (4) Web parts (4) Apps (3) Comunidad SharePoint (3) Configuración SharePoint 2013 (3) ODATA (3) SharePoint Server (3) SharePoint; Instalación SharePoint; Troubleshooting; Search Service (3) Silverlight 3.0 (3) Silverlight Toolkit (3) WebParts (3) javascript (3) jquery (3) Eventos SharePoint (2) Office 2010 (2) PeoplePicker (2) REST (2) SQL Server (2) Scripting (2) Search Service Application (2) SharePoint Designer (2) UPA (2) UPS (2) Workflows SharePoint (2) host header (2) Apps Development (1) Big Bang (1) CAS (1) CSOM (1) Codeplex (1) CompartiMOSS (1) Configuracion SharePoint 2010; Errores SharePoint (1) Configuracion SharePoint 2010; SharePoint 2010 (1) Custom Actions (1) Custom Editor Parts (1) Delegate Controls (1) Deployment (1) DisableLoopbackCheck (1) Document Library (1) Entrevista (1) Examenes de Certificación (1) Extract WSP (1) FBA (1) FS4SP (1) Fakes (1) Fast Search Server 2010 For SharePoint (1) Fiddler (1) HTTP.SYS (1) HTTPS (1) JSON (1) Language Pack's (1) Latam (1) MAXDOP (1) MCSM (1) MSExpertos (1) MVC (1) Microsoft México (1) Microsoft; Codeplex; Screencast; (1) My Sites (1) SQL Server 2012 (1) SQL Server Reporting Services (1) Screencast (1) Screencast; (1) Service Applications (1) Service Pack (1) SharePoint 2007 (1) SharePoint 2010 SP 1 (1) SharePoint API (1) SharePoint Conference (1) SharePoint Emulators (1) SharePoint Farm (1) SharePoint Health Analyzer (1) SharePoint Magazine (1) SharePoint Online (1) SharePoint Search (1) SharePoint Test (1) SharePoint; Desarrollo SharePoint (1) Shims (1) Simposio (1) Simposio Latinoamericano (1) SkyDrive Pro (1) Soporte Microsoft (1) Templates (1) Tip (1) VSeWSS (1) Virtual Machine (1) Visual Studio 2012 (1) WCF (1) WSS; IIS 7 (1) Web API (1) Web Content Management (1) Web Services (1) Windows 8 (1) Windows Live ID (1) Xml (1) appcmd (1) iOS (1) jqGrid (1) onload function (1)