avril
2012
Vous êtes encore confronté à du SharePoint 2007 existant qui doit évoluer ou simplement vous n’avez pas migré vers SharePoint 2010. Si c’est le cas, ce blog peut vous être utile. Attention, la démarche décrite ci-dessous n’est pas portable vers SharePoint 2010.
Il ne s’agit pas ici d’expliquer comment faire une colonne personnalisée mais uniquement de discuter des interactions entres champs dans les écrans de saisie SharePoint..
Le cas le plus typique et le plus souvent demandé est la cascading dropdown. Il existe sur internet une solution gratuite que nous avons-nous même utilisé jusqu’au jour où il m’a été demandé de lui ajouter des caractéristiques plus avancées (parents multiples, choix multiples)
J’avais alors le choix soit de partir de cette classe, soit de partir sur une nouvelle conception. Vous l’aurez compris, c’est cette deuxième solution que j’ai choisi. Pourquoi, d’une part il n’était pas aisé d’inclure les nouvelles caractéristiques dans le concept existant. D’autre part, je n’ai jamais aimé le principe d’avoir une colonne parent également personnalisée. Toutefois, pour partie, les deux solutions sont basées sur le même concept. L’idée de base est d’abonner le contrôle de la colonne personnnalisée à un événement du contrôle de rendu d’une autre colonne, personnalisée ou non. Pour mon cas concret, je suis parti sur l’élément « SelectedIndexChange » mais le principe fonctionne sur n’importe quel événement. Evidemment l’événement choisi va déterminer les types de contrôles qui pourront être connectés.
{
string fieldNames = Field.GetCustomProperty("JoinFieldNames").ToString();
foreach (string fieldName in fieldNames.Split(';'))
{
DropDownList control = getParentControl(fieldName);
if (control != null)
{
control.AutoPostBack = true;
control.SelectedIndexChanged += parentChanged;
}
}
}
Comme vous le voyez dans le code ci-dessus, il est nécessaire d’activer l’AutoPostBack pour permettre une interaction immédiate. L’élément intéressant dans ce code est l’appel à getParentControl. Cette méthode permet de retrouver un parent sur base du nom du champ et de son type de rendu. Dans mon cas, je cherche spécifiquement une dropdown.
Détaillons maintenant ce code:
{
Control parentField = findField(this.Page, fieldName);
DropDownList parentControl = null;
if (parentField != null)
{
parentControl = findControl(parentField);
}
return parentControl;
}
La recherche du control de rendu se fait en deux phases, la recherche du champ, ensuite la recherche du control proprement dit. Cette double recherche est nécessaire car aucun élément objectif ne permet de retrouver directement le contrôle au sein de la page. Par contre SharePoint génère non pas uniquement le contrôle de rendu mais toute une hiérarchie de contrôles pour effectuer le rendu des champs et un des niveaux identifie la colonne. La méthode « findField » recherche ce niveau.
{
Control result = null;
if (root is BaseFieldControl)
{
if (((BaseFieldControl)root).FieldName == fieldName)
{
result = root;
}
}
else
{
foreach (Control ctrl in root.Controls)
{
result = findField(ctrl, fieldName);
if (result != null)
break;
}
}
return result;
}
Il s’agit d’une méthode récursive qui va parcourir l’arborescence à la recherche d’un élément qui hérite de « BaseFieldControl » et dont le nom correspond à la colonne recherchée. Une fois cet élément trouvé, il devient alors possible de rechercher l’élément de rendu souhaité. N’oubliez pas que le rendu peut être assuré par plusieurs contrôles. La recherche ne peut donc se faire que sur le type.
{
DropDownList result = null;
if (root is DropDownList)
{
result = (DropDownList)root;
}
else
{
foreach (Control ctrl in root.Controls)
{
result = findControl(ctrl);
if (result != null)
break;
}
}
return result;
}
« findControl » fonctionne de manière identique à « findField ». La seule différence réside dans le type recherché. Il serait d’ailleurs possible de n’utiliser qu’une seule méthode qui prendrait le type en paramètre.
Maintenant, que vous êtes capable de vous connecter à n’importe quel événement de n’importe quelle colonne, il est possible de réaliser une colonne personnalisée capable de réaliser pratiquement n’importe quelle action dynamique telle que cascading drop down, validation dynamique complexe (la colonne personnalisée devenant un gestionnaire d’erreur), un provider pour lire des données externes en relation avec la valeur d’un champ,…