среда, 20 июня 2012 г.

SharePoint: Reflection vs. PropertySchema

При разработке настраиваемого типа столбца SharePoint практически всегда возникает необходимость создания его собственных свойств. В разметке CAML их схему представляет элемент PropertySchema - Элемент PropertySchema (Field Types) . Вещь, в принципе, проста в использовании, за исключением одного – что если значение какого-либо свойства нужно задавать не просто в соответствующем его типу элементе управления, а в более сложном; либо возникнет необходимость при операции присваивания значения выполнять какие-либо действия.

Первое, что приходит на ум объявить всё-таки данное свойство (элемент Field) в PropertySchema, присвоив его атрибуту Hidden значение TRUE, чтобы в области редактирования параметров столбца данного типа не отображался элемент управления по умолчанию. Затем, создать пользовательский редактор свойств типа столбца, и прийти к тому, что единственным способом присвоить теперь значение свойству можно только методом SetCustomProperty , но он свою очередь просто … не работает!!! Ровно, как и его собрат GetCustomProperty , точнее он выдает то, что было присвоено SetCustomProperty, т.е. ничего! 

До чего нельзя добраться разрешенным путём – рефлексия в помощь! Процедура присваивания значения свойству сведется к вставке соответствующего атрибута в значение свойства SchemaXml данного столбца, а его чтение - получение значения этого же атрибута.

Процедура присваивания значения собственному свойству будет выглядеть так:
void SetFieldAttribute(string attribute, string value)
{
    Type baseType = typeof([Тип столбца]);
    MethodInfo mi = baseType.GetMethod("SetFieldAttributeValue", BindingFlags.Instance | BindingFlags.NonPublic);
    mi.Invoke(this, new object[] { attribute, value });
}

А код получения значения этого свойства приведен ниже:

string GetFieldAttributeString(string attribute)
{
    Type baseType = typeof([Тип столбца]);
    MethodInfo mi = baseType.GetMethod("GetFieldAttributeValue", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(String) }, null);
    object obj = mi.Invoke(this, new object[] { attribute });
    if (obj == null)
        return "";
    else
        return obj.ToString();
}

Ну и само свойство определить следующим образом:

public string MyCustomProperty
{
    get
    {
        return GetFieldAttributeString("MyCustomProperty");
    }
    set
    {
        SetFieldAttribute("MyCustomProperty", (string)value);
        { Какие либо действия ...}
    }
}

Теперь даже и объявлять свойство в PropertySchema нет необходимости.

P.S.: В «родном» FLDTYPES.XML элемент PropertySchema не используется ни в одном типе! 

Комментариев нет:

Отправить комментарий