четверг, 22 августа 2013 г.

ListViewByQuery контрол

Введение

ListViewByQuery контрол умеет рендерит view любого листа на основе запроса.

listviewbyquery
Когда контрол покажет юзеров можно будет их отсортировать или применить к ним фильт, но эти события требуют собственной реализаци.

Синтакс

ListViewByQuery контрол это часть Microsoft.SharePoint.dll и расположен в пространстве Microsoft.SharePoint.WebControls. Обявлять нужно так:

<spuc:ListViewByQuery ID="CustomersListViewByQuery" runat="server" Width="700px" />

Так он работать не будет, свойства List и Query можно установить только из кода.
Не забывайте добавить вверху страницы:

<%@ Register TagPrefix="spuc" Namespace="Microsoft.SharePoint.WebControls"
             Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Можно создать контрол прямо из кода:

private ListViewByQuery CustomersListViewByQuery;
private void EnsureChildControls()
{
     CustomersListViewByQuery = new ListViewByQuery();
     // The rest of the code follows here....
}
Для нормальной работы требуется установить несколько обязательных свойств: List тип которого SPList и Query тип которого SPQuery. В OnLoad или EnsureChildControls можно добавить код:

list = SPContext.Current.Web.Lists["Customers"];
CustomersListViewByQuery.List = list;
string query = null;
if (!Page.IsPostBack)
{
    query = "<OrderBy><FieldRef Name='Title' Ascending='true' /></OrderBy>";
}
else
{
    // apply filtering and/or sorting
}
SPQuery qry = new SPQuery(list.DefaultView);
qry.Query = query;
CustomersListViewByQuery.Query = qry;
Запрос обязательно должен строиться на существующем view листа или контрол не будет работать. Данные в контроле отображаются согласно переданному запросу.
Можно устанавливать ограничение на кол-во возвращаемых записей RowLimit:
qry.RowLimit = 50;

Сортировка

Юзер может сортировать колонку стандартным кликаньем на header колонки и выбрав A on Top or Z on Top.

listviewbyquery-sort2

Это генерирует post back, и данные будут переданы на серверную сторону для обработки сохраненные в Context.Request["SortField"] и Context.Request["SortDir"]. Следующий код показывает как можно работать с ними.

if (!Page.IsPostBack)
{
    query = "<Query><OrderBy><FieldRef Name='Title' Ascending='true' /></OrderBy></Query>";
}
else
{
    // apply filtering and/or sorting
   if (this.Context.Request != null && this.Context.Request["SortField"] != null)
   {
       string sortorder = BuildSortOrder(this.Context.Request["SortField"],
           (this.Context.Request["SortDir"] == "Asc" ? "true" : "false"));
       if (string.IsNullOrEmpty(query))
           query = sortorder;
       else
           query += sortorder;
   }
}
private string BuildSortOrder(string fieldName, string sortOrder)
{
    string query = null;
    if (!string.IsNullOrEmpty(fieldName))
    {
        query = string.Format("<OrderBy><FieldRef Name='{0}' Ascending='{1}' /></OrderBy>", fieldName, sortOrder);
    }           
    return query;
}

Фильтрация
Также юзер может фильтровать данные в ListViewByQuery контроле  listviewbyquery-filter После этого также происходит posting back, выбранное поле хранится в Context.Request["FilterField1"], а выбранное значение в Context.Request["FilterValue1"]. Если фильтров более чем один (например выбран ещё один фильтр в другой колонке) они будут хранится по такому же принципу с именами FilterField2 и FilterValue2. private string BuildFilter() {     string query = "{0}";     bool isFound = true;     int counter = 1;     while (isFound)     {           string filterfield = "FilterField" + counter.ToString();           string filtervalue = "FilterValue" + counter.ToString();           if (this.Context.Request[filterfield] != null && this.Context.Request[filtervalue] != null)           {                // Field type must be treated differently in case of other data type                if (counter > 1)                    query = "<And>" + query + "{0}</And>";                query = string.Format(query, string.Format("<Eq><FieldRef Name='{0}' /><Value Type='Text'>{1}</Value></Eq>",                this.Context.Request[filterfield], this.Context.Request[filtervalue]));                counter++;           }           else           {                isFound = false;           }     }     if (!string.IsNullOrEmpty(query))        query = "<Where>" + query + "</Where>";     return query; } Этот код будет работать только для текстовых полей. Если необходимы другие типы, например number, choice или lookup, необходимо использовать так: SPField field = list.Fields[filterfield]; query = string.Format(query, string.Format("<Eq><FieldRef Name='{0}' /><Value Type='{1}'>{2}</Value></Eq>",                        this.Context.Request[filterfield], field.TypeAsString, this.Context.Request[filtervalue]));

Группировка

ListViewByQuery контрол может также гррупировать элементы, для этого нужно использовать CAML GroupBy элемент: query = "<GroupBy Collapse='FALSE'><FieldRef Name='CountryRegionName' /><FieldRef Name='City' /></GroupBy>"; Этот пример группирует данные по CountryRegionName и по City. listviewbyquery-expanded Если вы решили показать сразу сгруппированый вариант, установите Collapse аттрибут в TRUE и получите: listviewbyquery-collapsed Но здесь есть проблема, если они сгруппированы по умолчанию, то при открытиии вы получити только надпись Loading и никаких данных. listviewbyquery-collapsed-expanding Эта проблема решается так: устанавливаем Collapse аттрибут в FALSE и размещаем наш ListViewByQuery контрол в DIV, затем задаём у дива ID. Ниже дива вставляем скрипт: <div id="ViewDiv" class="ms-authoringcontrols" style="width:700px">      <spuc:ListViewByQuery ID="CustomersListViewByQuery" runat="server" Width="700px" /> </div> <script language="javascript">     ExpLinkFormer = function(divId)     {          this._DivId = divId;          this._init();     }     ExpLinkFormer.prototype = {         _init: function() {          var div = document.getElementById(this._DivId);          var links = div.getElementsByTagName("a");         for (var i = 0; i < links.length; i++) {           if (links[i].href == "javascript:" && links[i].onclick.toString().indexOf("ExpCollGroup") > -1) {               //alert(links[i]);               links[i].click();            }         }      }     }     var expLnk = new ExpLinkFormer('ViewDiv'); </script> ListViewByQuery контрол загружает все данные без группировки, но при рендеринге страницы, клик метод выполняется для всех hyperlinks которые имеют вызов на ExpCollGroup в их href аттрибуте.

Как изменить имя и email адресс существующего пользователя

Можно это сделать через PowerShell

Set-SPUser -Identity 'имямашины\TestUser' -DisplayName TestUser'  -Email 'testuser@yahoo.com' -Web http:// имямашины[порт]