Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Custom field properties

Îåêßíçóå áðü ôï ìÝëïò dgg. Τελευταία δημοσίευση από το μέλος dgg στις 11-05-2009, 17:35. Υπάρχουν 7 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  07-05-2009, 11:51 50519

    Custom field properties

    Καλημέρα σας,

    Έχω φτιάξει ένα custom field το οποίο αποτελείται απο ένα textbox και ένα HyperLink, το οποίο (HyperLink) ανοίγει  μία custom aspx σελίδα (popup). O χρήστης κάνει κάποιες επιλογές σε αυτό το popup και αυτές επιστρέφουν και γεμίζουν το textbox. Αυτό το τέσταρα και παίζει.

    Τι θέλω να κάνω τώρα: Όταν σε ένα document library κάνω Create Column και διαλέγω το field αυτό, στα Additional Column Settings απο κάτω να έχω μια δική μου custom property την οποία να μπορώ να διαβάσω στο κώδικα του custom field.

    Καμμία ιδέα για το πως γίνεται αυτό;

     

  •  07-05-2009, 12:22 50520 σε απάντηση της 50519

    Απ: Custom field properties

    (Υποψιάζομαι ότι είτε έγραψες όλο τον κώδικα μόνος σου από το μηδέν, ή χρησιμοποιείς κάποιο από τα Visual Studio Extensions for Sharepoint ή το STSDEV. Τo custom field template του VSeWSS είναι εντελώς άδειο ενώ το STSDev έχει μείνει πίσω σε features. Σου προτείνω να χρησιμοποιήσεις το WSPBuilder Addin για το Visual Studio, καθώς τα templates του περιέχουν και sample properties αλλά και κώδικα για στοιχειώδες error handling και για αντιμετώπιση κάποιων bug στα ... properties.
    )

     

    Ξεκινώντας λοιπόν από το sample κώδικα του template ....

    Στην ουσία, τα properties που βλέπεις όταν προσθέτεις ένα custom field είναι απλά properties τα οποία όμως αποθηκεύονται με ειδικό τρόπο μέσω του API του Sharepoint. Αν π.χ. έχεις ένα property που λέγεται MyCustomProperty, ο κώδικας του είναι ο εξής:

            
    public class MyField : SPFieldText
    {


    ...
    public string MyCustomProperty { get { return this.GetCustomProperty("MyCustomProperty") + ""; } set { this.SetCustomProperty("MyCustomProperty", value); } }

    Μετά, πρέπει να φτιάξεις μία ξεχωριστή κλάση field editor η οποία θα εμφανίσει τα απαραίτητα controls για κάθε property και αποθηκεύσει τις τιμές πίσω στο πεδίο. Ευτυχώς το WSPBuilder Addin φτιάχνει αυτόματα όλες αυτές τις κλάσεις. H υλοποίηση του Field Editor είναι :

    public class MyFieldFieldEditor : UserControl, IFieldEditor
        {
            // Fields
            protected DropDownList DdlLookupFieldTargetList;
            private MyField fldMyField;
            protected Label LabelLookupFieldTargetListTitle;
    
            public void InitializeWithField(SPField field)
            {
                this.fldMyField = field as MyField;
    
                if (this.Page.IsPostBack)
                {
                    return;
                }
    
                DdlLookupFieldTargetList.Items.Clear();
    
                DdlLookupFieldTargetList.Items.Add("One");
                DdlLookupFieldTargetList.Items.Add("Two");
                DdlLookupFieldTargetList.Items.Add("Default Value");
                DdlLookupFieldTargetList.Items.Add("Four");
    
    
                if (field != null)
                {
                    DdlLookupFieldTargetList.SelectedValue = fldMyField.MyCustomProperty;
                    this.DdlLookupFieldTargetList.Visible = true;
                }
                else
                {
                    DdlLookupFieldTargetList.SelectedValue = "Default Value";
                    this.DdlLookupFieldTargetList.Visible = true;
                }
            }
    
            public void OnSaveChange(SPField field, bool bNewField)
            {
                MyField lookup = (MyField)field;
    
                lookup.IsNew = bNewField;
                lookup.MyCustomProperty = this.DdlLookupFieldTargetList.SelectedValue;
    
            }
    
    
            // Properties
            public bool DisplayAsNewSection
            {
                get
                {
                    return false;
                }
            }
    
    
    
        }

    Η υλοποίηση όμως του GetCustomProperty, SetCustomProperty στο SPField έχει bugs, γι αυτό ο κώδικας του WSPBuilder τις κάνει override και κάνει κάποιες διορθώσεις:

            private static string[] CustomPropertyNames = new string[] { "MyCustomProperty" };
    
    
    ...
    
            #region Property storage and bug workarounds - do not edit
    
            /// <summary>
            /// Indicates that the field is being created rather than edited. This is necessary to 
            /// work around some bugs in field creation.
            /// </summary>
            public bool IsNew
            {
                get { return _IsNew; }
                set { _IsNew = value; }
            }
            private bool _IsNew = false;
    
            /// <summary>
            /// Backing fields for custom properties. Using a dictionary to make it easier to abstract
            /// details of working around SharePoint bugs.
            /// </summary>
            private Dictionary<string, string> CustomProperties = new Dictionary<string, string>();
    
            /// <summary>
            /// Static store to transfer custom properties between instances. This is needed to allow
            /// correct saving of custom properties when a field is created - the custom property 
            /// implementation is not used by any out of box SharePoint features so is really buggy.
            /// </summary>
            private static Dictionary<string, string> CustomPropertiesForNewFields = new Dictionary<string, string>();
    
            /// <summary>
            /// Initialise backing fields from base property store
            /// </summary>
            private void InitProperties()
            {
                foreach (string propertyName in CustomPropertyNames)
                {
                    CustomProperties[propertyName] = base.GetCustomProperty(propertyName) + "";
                }
            }
    
            /// <summary>
            /// Take properties from either the backing fields or the static store and 
            /// put them in the base property store
            /// </summary>
            private void SaveProperties()
            {
                foreach (string propertyName in CustomPropertyNames)
                {
                    base.SetCustomProperty(propertyName, GetCustomProperty(propertyName));
                }
            }
    
            /// <summary>
            /// Get an identifier for the field being added/edited that will be unique even if
            /// another user is editing a property of the same name.
            /// </summary>
            /// <param name="propertyName"></param>
            /// <returns></returns>
            private string GetCacheKey(string propertyName)
            {
                return SPContext.Current.GetHashCode() + "_" + (ParentList == null ? "SITE" : ParentList.ID.ToString()) + "_" + propertyName;
            }
    
            /// <summary>
            /// Replace the buggy base implementation of SetCustomProperty
            /// </summary>
            /// <param name="propertyName"></param>
            /// <param name="propertyValue"></param>
            new public void SetCustomProperty(string propertyName, object propertyValue)
            {
                if (IsNew)
                {
                    // field is being added - need to put property in cache
                    CustomPropertiesForNewFields[GetCacheKey(propertyName)] = propertyValue + "";
                }
    
                CustomProperties[propertyName] = propertyValue + "";
            }
    
            /// <summary>
            /// Replace the buggy base implementation of GetCustomProperty
            /// </summary>
            /// <param name="propertyName"></param>
            /// <param name="propertyValue"></param>
            new public object GetCustomProperty(string propertyName)
            {
                if (!IsNew && CustomPropertiesForNewFields.ContainsKey(GetCacheKey(propertyName)))
                {
                    string s = CustomPropertiesForNewFields[GetCacheKey(propertyName)];
                    CustomPropertiesForNewFields.Remove(GetCacheKey(propertyName));
                    CustomProperties[propertyName] = s;
                    return s;
                }
                else
                {
                    return CustomProperties[propertyName];
                }
            }
    
            /// <summary>
            /// Called when a field is created. Without this, update is not called and custom properties
            /// are not saved.
            /// </summary>
            /// <param name="op"></param>
            public override void OnAdded(SPAddFieldOptions op)
            {
                base.OnAdded(op);
                Update();
            }
    
            #endregion
    
    ...
    
            public override void Update()
            {
                SaveProperties();
                base.Update();
            }

    Φυσικά, τα πράγματα είναι πολύ απλούστερα αν χρησιμοποιήσεις το ... Addin!

    Τέλος, θα σου προτείνω να διαβάσεις οπωσδήποτε το άρθρο Custom Field Types του Ted Pattison στο MSDN Magazine, για δύο λόγους:

    1. Είναι πολύ καλό άρθρο
    2. Η Microsoft αφαιρεί την CAML από το rendering των custom fields στην επόμενη έκδοση του Sharepoint (καλά ξεκουμπίδια). Ο Pattison δείχνει πως να φτιάξεις το control σου χωρίς τη χρήση CAML και έτσι να αποφύγεις προβλήματα upgrade στο μέλλον, αλλά και τους ανόητους περιορισμούς της CAML στο παρόν.

    Απλά, μην χρησιμοποιήσεις το STSDev που προτείνει. Απ' όλα τα extensions και Addins είναι το φτωχότερο και δυσκολότερο.

     


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  08-05-2009, 10:12 50549 σε απάντηση της 50520

    Απ: Custom field properties

    Me WSPBuilder το έκανα για να μπορέσω να βάλω και Solution Installer, αλλα το ξεκίνησα ως Blank Feature Project. Δοκίμασα και το Field Type template και έφτιαξε την κλάση που μου έδειξες. Έχει φτιάξει όμως και ένα επιπλέον CustomFieldType1FieldEditor.ascx αρχείο. Αυτό για ποιό λόγω χρειάζεται; (έχω ήδη ένα ascx στο οποίο έχω βάλει τα controls του custom field μου.)

  •  08-05-2009, 15:01 50560 σε απάντηση της 50549

    Απ: Custom field properties

    Ο CustomFieldType1FieldEditor εμφανίζει τα settings του πεδίου που όρισες στην κλάση CustomFieldType1 και μεταφέρει τις τιμές μεταξύ του πεδίου και των control του. Ουσιαστικά κάνει ό,τι και το δικό σου control, απλά υλοποιεί και το IFieldEditor interface. Κανονικά θα πρέπει να βάλεις μέσα σε αυτό τα control σου και όχι σε κάποιο άλλο control.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  08-05-2009, 15:41 50561 σε απάντηση της 50560

    Απ: Custom field properties

    Δηλαδή το  CustomFieldType1FieldEditor.ascx ουσιαστικά δεν χρειάζεται;

  •  08-05-2009, 15:58 50563 σε απάντηση της 50561

    Απ: Custom field properties

    Όχι, λέω ότι το ΔΙΚΟ σου ascx δεν χρειάζεται! Αν θέλεις βέβαια να περάσεις τον κώδικα του στο δικό σου, κανένα πρόβλημα, φτάνει να μην μπλέξεις μετά τα ονόματα και ποιό ascx ανήκει σε ποιό control.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  08-05-2009, 17:28 50571 σε απάντηση της 50563

    Απ: Custom field properties

    Ααα, μάλιστα.

    Το rendering, για look and feel, του field μου που πρέπει να το κάνω σε αυτήν την περίπτωση; Μέχρι τώρα το έκανα στο ascx που ανέφερα στο οποίο είχα ένα <SharePoint:RenderingTemplate> item.

  •  11-05-2009, 17:35 50645 σε απάντηση της 50571

    Απ: Custom field properties

    Τελικά το κατάφερα !!

    Όντως το WSPBuilder πολύ καλό toolaki, με έσωσε απο πολύ κόπο.

Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems