none
[Moss2007] Dev. SDK, librairies, views et columns RRS feed

  • Question

  • Bonjour à tous,

    pour personnaliser un MySite, j'ai besoin de modifier, dans une composant web, la vue d'une librairie en lui ajoutant des colonnes et en modifiant leur ordre d'affichage.

    Voici déjà le code qui me permet de créer ma liste et qui est 100% fonctionnel jusque là :

    Code Snippet

    Guid documentsListGuid = curWeb.Lists.Add("Assignment Documents", "Assignment Documents",
        SPListTemplateType.DocumentLibrary);
    curWeb.Update();
    SPDocumentLibrary documentsList = (SPDocumentLibrary)curWeb.
         GetListsOfType(SPBaseType.DocumentLibrary)[documentsListGuid];



    C'est ensuite que viens le problème.

    En regardant les classes qui permettent de modifier les fields d'une view, je me suis aperçu, contrairement à tout ce que j'ai l'habitude de voir depuis des mois de dévelloppement sur SP, que l'objet

    Code Snippet

    documentsList.Views["All Documents"].ViewFields



    ViewFields, de type SPViewFieldCollection, s'indexant sur uniquement un index (première surprise), ne renvoyait pas comme je le pensais un SPField, mais un String !!!!!!

    Qui plus est, je ne sais absolument pas quoi faire de ce string (je pense que ce string renvoit le nom de la colonne en question).

    D'où mon incompréhension totale sur l'utilisation des fields dans une view... Comment ca marche????

    2ème problème rédibitoire, sur la Library "Assignment Documents" utilisée plus haut, je désire mettre à vide sa propriété DocumentTemplateUrl, comme je l'ai fait déjà via l'interface web de SP. Mais quand je la met à vide, j'ai une erreur
    Citation:
    Value does not fall within the expected range.
    J'ai déjà eu cette erreur pour d'autres propriétés de type String, comme des url par exemple, où il ne veut absolument aucune valeur, ni null, ni String.Empty, ni "", rien ne marche et tout me donne la même erreur. Si je remplis avec une valeur concrete, cela fonctionne. Comment faire pour vider une propriété de type String comme DocumentTemplateUrl en code?

    Merci d'avance à ceux qui pourront me répondre.
    mercredi 23 janvier 2008 22:26

Toutes les réponses

  • Bonsoir,

     

    1er problème :

     

    Je ne suis pas en mesure de vous donner des explications précisément sur la SPViewFieldCollection. En revanche, je dois pouvoir vous aider pour réorganiser vos champs... quitte à ce que la solution que je vais vous proposer soit approchée mais qu'elle vous permette de comprendre comment fonctionnent les SPViews.

     

    Depuis la collection de SPViews de votre liste, la méthode Add (http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.spviewcollection.add.aspx) prend en paramètre une StringCollection représentant la liste de vos champs, dans l'ordre d'apparition souhaité. Il vous est donc éventuellement possible de dupliquer une vue existante, tout en réorganisant ses champs, puis de supprimer la vue d'origine et enfin de renommer la vue nouvellement créée. Ok, cette solution ne me semble pas idéale non plus...

     

    Si on s'arrête juste après avoir dupliqué la vue (avec champs réorganisés), on doit donc avoir deux objets SPView relativement proches... la différence dans l'ordre des colonnes devrait se voir parmi les propriétés différentes de l'objet SPView ou des objets référencés. Une fois la différence trouvée, vous saurez certainement comment comment ajouter des colonnes et modifier l'ordre d'affichage.

     

    2ème problème :

     

    C'est normal. Une SPDocumentLibrary n'est qu'une liste particulière... et une liste n'a pas de métadonnée décrivant un template de document. :-) Le champ DocumentTemplateUrl n'est en réalité qu'un wrapper vers la véritable propriété qui gère le template utilisé : SPContentType.DocumentTemplateUrl :-) (http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.spcontenttype.documenttemplateurl.aspx)

     

    Vous pouvez d'ailleurs le vérifier par vous même via l'interface graphique : créez un nouveau ContentType et faites le hériter du ContenType "Document". Vous aurez la possibilité de lui associer un fichier modèle. Côté code, il vous suffit de parcourir la collection des ContentTypes associés à votre liste pour modifier leur DocumentTemplateUrl. Au pire, vous pourrez créer un nouveau ContentType à cette collection pour vous assurer que ce DocumentTemplateUrl reste bien vide. Attention, la collection des ContentTypes associés à votre liste n'est pas la même que celle attachée à votre site. Si vous comparez les ID des ContentTypes portant le même nom dans votre liste et dans votre site, vous verrez qu'ils sont différents.

     

    Autre solution pour ajouter un Template de Document : lors de la création de la liste. Certes, par l'interface graphique, celà ne nous apprends pas grand chose, mais s'il est possible de séléctionner un template à la création (ou même en avoir un par défaut), c'est qu'il y a bien un mécanisme en place. En partant de ce constat, il est légitime de penser qu'on trouve la réponse dans les définitions de sites comportant des bibliothèques de document, ou bien dans les features liées aux modèles de listes. Justement, en ce qui concerne la feature relative aux bibliothèque de document, activée dans la plupart des définitions de sites, on trouve un ListTemplate dont l'attribut Type vaut 101 (Document Library). Jusqu'ici tout est normal... mais on trouve également un attribut DocumentTemplate, associé à une valeur. Le MSDN (http://msdn2.microsoft.com/en-us/library/ms462947.aspx) indique pourtant que cette propriété est inutilisée, et valide uniquement pour les document librairies... étrange non ? Si vous faites le test en supprimant la valeur associée à Document Template, votre liste affichera un bouton nouveau proposant un "Nouveau Document", associé à aucun modèle... en réalité, seul le téléchargement sera possible.

     

     

    J'espère que ces réponses vous auront été utiles,

     

    Sébastien.

    mercredi 23 janvier 2008 23:45
    Modérateur
  • Merci beaucoup pour cette réponse rapide.

    J'ai trouvé une page très intéressante qui répond à pas mal de mes problématiques citées plus haut, et que je suis en train de tester : http://www.tonstegeman.com/Blog/Lists/Posts/Post.aspx?List=70640fe5%2D28d9%2D464f%2Db1c9%2D91e07c8f7e47&ID=4

    Je vous tiens bien évidemment au courant.
    jeudi 24 janvier 2008 14:04
  • Concernant mon premier problème, et suite au lien donné précédemment, j'ai réussis enfin à rajouter une colonne.

    Je ne vous cache pas mon énèrvement quand à la complexité et au temps passé pour effectuer une action aussi simple. Dans le code suivant, je suis d'ailleurs obligé de créer un Site Field et un Site Content Type, chose dont je n'ai strictement et absolument aucune utilité, ni maintenant, ni dans le futur.

    Voici donc le code pour créer une malheureuse colonne dans une Library de documents, sans même n'avoir modifié aucun de ses paramètres et ne l'avoir pour l'instant affichée dans aucune vue...

    Code Snippet

    // ------------------------------
    // Create a new Site Field
    SPFieldDateTime validityDateField = null;
    try
    {
        validityDateField = (SPFieldDateTime)curWeb.Fields.GetField("Validity Date");
    }
    catch (Exception ex)
    {
        validityDateField = null;
    }
    if (validityDateField == null)
    {
        // Create a new Validity Date Site Field
        String newValidityNameFieldName = curWeb.Fields.Add("Validity Date", SPFieldType.DateTime, false);
        curWeb.Update();
        validityDateField = (SPFieldDateTime)curWeb.Fields.GetField("Validity Date");
        validityDateField.Update();
    }
    else
    {
        // Validity Date Site Field already existing.
        validityDateField = (SPFieldDateTime)curWeb.Fields.GetField("Validity Date");
    }

    // ------------------------------
    // Create new content type
    SPContentType validityDateContentType = null;
    if (curWeb.ContentTypes["Validity Date"] == null)
    {
        // Create new Validity Date Site Content Type
        SPContentType documentContentType = curWeb.AvailableContentTypes["Document"];
        validityDateContentType = new SPContentType(documentContentType, curWeb.ContentTypes,
            "Validity Date");
        curWeb.ContentTypes.Add(validityDateContentType);
    }
    else
    {
        // Validity Date Site Content Type already existing
        validityDateContentType = curWeb.ContentTypes["Validity Date"];
    }
    validityDateContentType = curWeb.ContentTypes[validityDateContentType.Id];

    // ------------------------------
    // Add FieldLink to content type to add it to documentsList Content types
    SPFieldLink fieldLink = new SPFieldLink(validityDateField);
    validityDateContentType.FieldLinks.Add(fieldLink);
    validityDateContentType.Update(false);

    // ------------------------------
    // Use Content Type
    // Apply Content Type on documents Library
    documentsList.ContentTypesEnabled = true;
    documentsList.ContentTypes.Add(validityDateContentType);



    jeudi 24 janvier 2008 15:31