Поделиться через


Создание редакторов фильтров для PerformancePoint Services в SharePoint

Узнайте, как создать компонент редактора расширения специальных фильтров для PerformancePoint Services.

Что такое редакторы настраиваемых фильтров для Службы PerformancePoint Services ?

В Службы PerformancePoint Services редакторы настраиваемых фильтров позволяют пользователям задания свойств настраиваемых фильтров. Редакторы фильтров также должны инициализировать свойство BeginPoints фильтра, которое определяет начальную точку фильтра, содержащую значения параметров для системы показателей и потребителей отчетов. Дополнительные сведения о требованиях к редактора и функциональные возможности можно Редакторы нестандартных объектов PerformancePoint Services.

Следующие процедуры и примеры основаны на класс SampleFilterEditor из настраиваемых объектов. Редактор — тонкие веб-приложения, которое позволяет пользователям изменять имя и описание фильтра панели и выберите в источнике данных. Полный код для класса см. в разделе Пример кода: Создание, получение и обновление настраиваемых фильтров PerformancePoint Services в SharePoint.

Мы рекомендуем использовать редактор образец как шаблон. В примере демонстрируется как вызов объектов в Службы PerformancePoint Services API, предоставляет вспомогательные объекты, которые упрощают вызывает для репозитория операций (например, создание и обновление объектов) и демонстрируются советы и рекомендации по разработке Службы PerformancePoint Services.

Создание и настройка класса редактора для настраиваемых Службы PerformancePoint Services фильтров

  1. Установите PerformancePoint Services или скопируйте библиотеки DLL, которые использует расширение (см. шаг 3) на компьютер. Дополнительные сведения см. в разделе Библиотеки DLL с библиотеками классов.

  2. В Visual Studio создания библиотеки классов C#. Если вы создали библиотека классов для расширения, добавьте новый класс C#.

    DLL-библиотеку необходимо подписать строгим именем. Кроме того, убедитесь, что все сборки, на которые ссылается DLL-библиотека, имеют строгие имена. Сведения о том, как подписать сборку со строгим именем и как создать пару открытого и закрытого ключей, см. в разделе Практическое руководство. Создание пары открытого и закрытого ключей.

  3. Добавьте в проект в качестве ссылок на сборки следующие библиотеки DLL:

    • Microsoft.PerformancePoint.Scorecards.Client.dll
    • Microsoft.PerformancePoint.Scorecards.ServerCommon.dll
    • Microsoft.PerformancePoint.Scorecards.ServerRendering.dll
    • Microsoft.PerformancePoint.Scorecards.Store.dll (используется в вспомогательных классах)
    • Microsoft.SharePoint.dll (используется в вспомогательных классах)

    Образец редактора также содержит ссылки на сборки System.Web.dll и System.Web.Services.dll. В зависимости от функциональности расширения могут потребоваться другие ссылки в проекте.

  4. Добавьте следующие классы из примера в проект. Редактор использует эти вспомогательные классы для взаимодействия с репозитория Службы PerformancePoint Services:

    • DataSourceConsumerHelper.cs
    • ExtensionRepositoryHelper.cs
    • FilterRepositoryHelper.cs
    • IDataSourceConsumer.cs
  5. В классе редактора добавьте using директивы для следующих PerformancePoint Services пространств имен:

    • Microsoft.PerformancePoint.Scorecards
    • Microsoft.PerformancePoint.Scorecards.ServerCommon
    • Microsoft.PerformancePoint.Scorecards.ServerRendering

    В зависимости от функционального диапазона расширения, могут потребоваться другие директивы using.

  6. Унаследуйте класс от базового класса, который поддерживает реализацию редактора. Так как пример редактора фильтров является веб-приложением, он наследуется от класса Page . В других реализациях могут использоваться классы, производные от таких базовых классов, как UserControl или WebPart .

  7. Определите элементы управления для доступа к свойствам, которые пользователи смогут просматривать или изменять. В образце редактора фильтров сначала объявляются переменные для серверных веб-элементов управления, определенных в компоненте пользовательского интерфейса, представляющем собой страницу ASPX. В образце редактора также определяется элемент управления "Кнопка", позволяющий пользователям отправлять изменения. Затем редактор вызывает метод CreateChildControls(), чтобы сделать элементы управления доступными на странице.

    Примечание.

    В редакторе программная логика определяется отдельно от пользовательского интерфейса. Инструкции по созданию компонента пользовательского интерфейса не входят в данную документации.

    Редактор фильтров пример выполняет шаги с 8 по 12 в методе Page_Load. Page_Load также используется для инициализации и проверка переменными и элементами управления, заполнения элементов управления и сохранить сведения о состоянии для настраиваемого фильтра и вспомогательные объекты.

  8. Задайте для свойства AllowUnsafeUpdatesзначение true. Это позволит редактору фильтров записывать данные в репозиторий без помощи операций POST формы.

  9. Получите параметры из строки запроса и присвойте их значения локальным переменным, как показано в примере кода ниже.

    // The URL of the site collection that contains the PerformancePoint Services repository.
    string server = Request.QueryString[ClickOnceLaunchKeys.SiteCollectionUrl];
    
    // The location of the filter in the repository.
    string itemLocation = Request.QueryString[ClickOnceLaunchKeys.ItemLocation];
    
    // The operation to perform: OpenItem or CreateItem.
    string action = Request.QueryString[ClickOnceLaunchKeys.LaunchOperation];
    

    Примечание.

    Сведения о параметрах строки запроса см. в разделе Редакторы для пользовательских объектов PerformancePoint Services.

  10. Извлеките объект FilterRepositoryHelper, который используется для отправки вызовов в репозиторий, как показано в следующем примере кода.

    filterRepositoryHelper = new FilterRepositoryHelper();
    
  11. Задайте расположение фильтра, используя параметр строки запроса, как показано в следующем примере кода.

    RepositoryLocation repositoryFilterLocation = RepositoryLocation.CreateFromUriString(itemLocation);
    
  12. Извлеките из строки запроса выполняемую операцию ( OpenItem или CreateItem) и извлечения или создайте настраиваемый фильтр.

    • Для извлечения настраиваемого фильтра используйте метод FilterRepositoryHelper.Get.
    • Чтобы создать настраиваемый фильтр, используйте конструктор Filter() и определите свойства Name , RendererClassName и SubTypeId фильтра. SubTypeId — уникальный идентификатор для фильтра, а его должен соответствовать атрибуту subType, указанная для фильтра в файле web.config Службы PerformancePoint Services. RendererClassName — это полное имя класса, который определяет веб-сервер визуализации элемента управления. Если он не определен в редакторе, это значение по умолчанию класса визуализации, которая указана в файле web.config.
    if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase))
    {
      // Use the repository-helper object to retrieve the filter.
      filter = filterRepositoryHelper.Get(repositoryFilterLocation);
      if (filter == null)
      {
        displayError("Could not retrieve the filter for editing.");
        return;
      }
    }
    else if (ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase))
    {
      filter = new Filter
      {
        RendererClassName = typeof(MultiSelectTreeViewControl).AssemblyQualifiedName,
        SubTypeId = "SampleFilter"
      };
    }
    

    Примечание.

    [!Примечание] По умолчанию пользователи могут создавать пользовательские объекты из Конструктор панели мониторинга PerformancePoint только. Чтобы разрешить пользователям создавать пользовательский объект за пределами конструктора панели мониторинга, необходимо добавить пункт меню, который отправляет запрос CreateItem в редактор из типа контента в репозитории. Для получения дополнительных сведений см Редакторы нестандартных объектов PerformancePoint Services.

  13. Извлеките из репозитория базовый источник данных фильтра. В данном образце редактора фильтров используется свойство FilterRepositoryHelper.DataSourceHelper для вызова метода DataSourceConsumerHelper.GetDataSource, позволяющего найти источник данных по его расположению в репозитории. Это показано в следующем примере кода.

    if (!string.IsNullOrEmpty(filter.DataSourceLocation.ItemUrl))
    {
      RepositoryLocation repositoryDatasourceLocation = RepositoryLocation.CreateFromUriString(filter.DataSourceLocation.ItemUrl);
      datasource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation);
    }
    
  14. Чтобы разрешить пользователям Выбор источника данных для фильтра, заполнения элемента управления выбора с источниками данных Службы PerformancePoint Services. Метод PopulateDataSourceDropDown в редакторе фильтров пример вызывает метод DataSourceConsumerHelper.GetDataSourcesBySourceNames для получения источников данных. Это показано в следующем примере кода.

    // The parameter contains the default server-relative URL to the PerformancePoint Data Connections Library.
    // Edit this value if you are not using the default path. A leading forward slash may not be needed.
    ICollection dataSourceCollection =
    
    filterRepositoryHelper.DataSourceHelper.GetDataSourcesBySourceNames
        ("/BICenter/Data%20Connections%20for%20PerformancePoint/",
             new[] { "WSTabularDataSource", DataSourceNames.ExcelWorkbook });
    

    Редактор фильтров пример извлекает только два типа источника данных, однако можно изменить этот метод для поддержки других типов данных или запрос пользователю для типа источника данных для извлечения. Чтобы сослаться на собственный источник данных определенного типа, используйте свойство SourceName , которое возвращает поле из класса DataSourceNames . Чтобы ссылаться на пользовательский источник данных, используйте свойство SubTypeId источник данных, который является совпадает со значением атрибута subType, который зарегистрирован в файле web.config Службы PerformancePoint Services для расширения источника данных.

    При изменении этого метода необходимо внести соответствующее изменение в метод GetDisplayDataInternal в поставщике данных фильтра.

  15. Определите начальную точку фильтра, представленную свойством BeginPoints . Она определяет источник значений фильтра и необходима для того, чтобы иметь возможность отправлять данные из фильтра в системы показателей и отчеты.

    1. Создайте объект ParameterDefinition . Свойство BeginPoints возвращает объект ParameterDefinitionCollection , содержащий ровно один объект ParameterDefinition .

    2. Чтобы указать поставщик данных фильтра, задайте для свойства ParameterProviderId уникальный идентификатор поставщика данных. Он должен соответствовать значению, возвращаемому методом GetId() поставщика данных.

    3. Чтобы указать источник идентификаторов ключей для значений фильтра, задайте для свойства KeyColumn столбец в таблице отображаемых данных, содержащей идентификаторы ключей. В данном образце редактора фильтров это свойство определяется как столбец Symbol.

    4. Чтобы указать источник отображаемых значений для элемента управления фильтром, задайте для свойства DisplayColumn столбец в таблице отображаемых данных, содержащей отображаемые значения. В данном образце редактора фильтров это свойство определяется как столбец Symbol.

      Примечание.

      Таблица отображаемых данных возвращается свойством DisplayValues и инициализируется, когда поставщик данных фильтра вызывает метод GetDisplayDataInternal . Если в таблице отображаемых данных содержатся и другие столбцы, можно определить сопоставления других столбцов для обеспечения дополнительных функциональных возможностей.

    if (0 == filter.BeginPoints.Count)
    {
      ParameterDefinition paramDef = new ParameterDefinition();
    
      // Reference the data provider.
      paramDef.ParameterProviderId = "SampleFilterDataProvider";
      paramDef.DefaultPostFormula = string.Empty;
    
      // Specify the column that contains the key identifiers and the column
      // that contains the display values. The sample uses the same column
      // for both purposes.
      // These values must match the structure of the data table that is
      // returned by the ParameterDefinition.DisplayValues property.
    
      paramDef.KeyColumn = "Symbol";
      paramDef.DisplayColumn = "Symbol";
    
      // You can use this property to store custom information for this filter.
      paramDef.CustomDefinition = string.Empty;
    
      filter.BeginPoints.Add(paramDef);
    }
    

    Начальная точка образца редактора определяется в методе VerifyFilter. Метод VerifyFilter также используется для проверки задания обязательных свойств и для определения режима выбора (это необязательное свойство).

  16. Инициализируйте фильтр, выполнив запрос фильтра и получив данные из источника данных. Метод buttonOK_Click в данном образце редактора фильтров вызывает метод FilterRepositoryHelper.GetParameterDisplayData для инициализации фильтра.

    Примечание.

    [!Примечание] Метод FilterRepositoryHelper.GetParameterDisplayData должен быть вызван в редакторе по крайней мере один раз перед обновлением объекта фильтра.

  17. Обновите фильтр, применив изменения, определенные пользователем. Метод buttonOK_Click в образце редактора фильтров вызывает метод FilterRepositoryHelper.Update для обновления свойств Name , Description и DataSourceLocation данного фильтра в репозитории. Кроме того, с помощью метода buttonOK_Click проверяется содержимое элементов управления и извлекается информация о состоянии настраиваемого фильтра и вспомогательного объекта.

    Примечание.

    Пользователи могут задать свойства Name, Description и Owner (Person Responsible) пользовательского объекта, а также удалить пользовательские объекты непосредственно из конструктора панели мониторинга и репозитория PerformancePoint Services.

Пример кода: создание, получение и обновление настраиваемых фильтров PerformancePoint Services в SharePoint

В следующем примере кода создается, извлекаются и обновление настраиваемых фильтров. Этот код — от класса редактор кода, который содержит логику программирования для элементов управления, определенных на ASPX-странице.

Перед компиляцией этого примера кода необходимо настроить среду разработки, как описано в разделе Создание и настройка класса редактора для редактора фильтров в PerformancePoint Services.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.PerformancePoint.Scorecards;
using Microsoft.PerformancePoint.Scorecards.ServerCommon;
using Microsoft.PerformancePoint.Scorecards.ServerRendering;

namespace Microsoft.PerformancePoint.SDK.Samples.SampleFilter
{

    // Represents the class that defines the sample filter editor.
    public class SampleFilterEditor : Page
    {

        // Declare private variables for the ASP.NET controls defined in the user interface.
        // The sample's user interface is an ASPX page that defines the controls in HTML.
        private TextBox textboxName;
        private TextBox textboxDescription;
        private Label labelErrorMessage;
        private DropDownList dropdownlistDataSource;
        private Button buttonOK;
        private ListBox listboxStocks;

        // Make the controls available to this class.
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            if (null == textboxName)
                textboxName = FindControl("textboxName") as TextBox;
            if (null == textboxDescription)
                textboxDescription = FindControl("textboxDescription") as TextBox;
            if (null == dropdownlistDataSource)
                dropdownlistDataSource = FindControl("dropdownlistDataSource") as DropDownList;
            if (null == labelErrorMessage)
                labelErrorMessage = FindControl("labelErrorMessage") as Label;
            if (null==buttonOK)
                buttonOK = FindControl("buttonOK") as Button;
            if (null==listboxStocks)
                listboxStocks = FindControl("listboxStocks") as ListBox;
        }

        // Handles the Load event of the Page control.
        // Methods that use a control variable should call the Control.EnsureChildControls
        // method before accessing the variable for the first time.
        protected void Page_Load(object sender, EventArgs e)
        {

            // Required to enable custom report and filter editors to
            // write data to the repository.
            ServerUtils.AllowUnsafeUpdates = true;

            // Initialize controls the first time the page loads only.
            if (!IsPostBack)
            {
                EnsureChildControls();
                FilterRepositoryHelper filterRepositoryHelper = null;
                try
                {

                    // Get information from the query string parameters.
                    string server = Request.QueryString[ClickOnceLaunchKeys.SiteCollectionUrl];
                    string itemLocation = Request.QueryString[ClickOnceLaunchKeys.ItemLocation];
                    string action = Request.QueryString[ClickOnceLaunchKeys.LaunchOperation];

                    // Validate the query string parameters.
                    if (string.IsNullOrEmpty(server) ||
                        string.IsNullOrEmpty(itemLocation) ||
                        string.IsNullOrEmpty(action))
                    {
                        displayError("Invalid URL.");
                        return;
                    }

                    // Retrieve the repository-helper object.
                    filterRepositoryHelper =
                        new FilterRepositoryHelper();

                    // Set the filter location.
                    RepositoryLocation repositoryFilterLocation = RepositoryLocation.CreateFromUriString(itemLocation);

                    Filter filter;
                    DataSource datasource = null;

                    // Retrieve or create the filter object, depending on the operation
                    // passed in the query string (OpenItem or CreateItem).
                    if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase))
                    {

                        // Retrieve the filter object by using the repository-helper object.
                        filter = filterRepositoryHelper.Get(repositoryFilterLocation);
                        if (filter == null)
                        {
                            displayError("Could not retrieve the filter for editing.");
                            return;
                        }

                    }
                    else if (ClickOnceLaunchValues.CreateItem.Equals(action, StringComparison.OrdinalIgnoreCase))
                    {

                        // Create a filter.
                        // CreateItem requests can be sent from a SharePoint list, but
                        // you must create a custom menu item to send the request.
                        // Dashboard Designer can send edit requests only.
                        filter = new Filter
                            {

                                // Specify the class that defines the renderer
                                // web server control. The sample filter uses a native
                                // PerformancePoint Services renderer.
                                // Defaults to the value specified in the web.config file
                                RendererClassName = typeof(MultiSelectTreeViewControl).AssemblyQualifiedName,

                                // Specify the unique identifier for the filter.
                                // The SubTypeId property must match the
                                // subType attribute in the web.config file.
                                SubTypeId = "SampleFilter"
                            };
                    }
                    else
                    {
                        displayError("Invalid Action.");
                        return;
                    }

                    VerifyFilter(filter);

                    // Retrieve filter's underlying data source.
                    if (!string.IsNullOrEmpty(filter.DataSourceLocation.ItemUrl))
                    {
                        RepositoryLocation repositoryDatasourceLocation =
                            RepositoryLocation.CreateFromUriString(filter.DataSourceLocation.ItemUrl);
                        datasource =

                            // Gets a PerformancePoint Services data source by using the
                            // DataSourceHelper property to call the
                            // DataSourceConsumerHelper.GetDataSource method.
                            filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation);
                    }

                    // Save the original filter and helper objects across page postbacks.
                    ViewState["action"] = action;
                    ViewState["filter"] = filter;
                    ViewState["filterrepositoryhelper"] = filterRepositoryHelper;
                    ViewState["itemlocation"] = itemLocation;

                    // Populate the child controls.
                    textboxName.Text = filter.Name.ToString();
                    textboxDescription.Text = filter.Description.ToString();

                    // Populate the dropdownlistDataSource control with data sources of specific
                    // types from the PerformancePoint Services repository.
                    // This method looks up the passed data source in the data sources
                    // that are registered in the web.config file.
                    // Although the sample retrieves data sources of two specific types,
                    // you can modify it to prompt the user for a data source type.
                    PopulateDataSourceDropDown(datasource);

                    // Call the SelectedIndexChanged event directly to populate the
                    // listbox control with preview data.
                    dropdownlistDataSource_SelectedIndexChanged(null, null);
                }
                catch (Exception ex)
                {
                    displayError("An error has occurred. Please contact your administrator for more information.");
                    if (filterRepositoryHelper != null)
                    {
                        // Add the exception detail to the server event log.
                        filterRepositoryHelper.HandleException(ex);
                    }
                }
            }
        }

        // Handles the SelectedIndexChanged event of the dropdownlistDataSource control.
        protected void dropdownlistDataSource_SelectedIndexChanged(object sender, EventArgs e)
        {
            EnsureChildControls();

            // Check if a valid data source is selected.
            if (null != dropdownlistDataSource.SelectedItem &&
                !string.IsNullOrEmpty(dropdownlistDataSource.SelectedItem.Text))
            {
                // Retrieve the data source object.
                FilterRepositoryHelper filterRepositoryHelper =
                    (FilterRepositoryHelper)ViewState["filterrepositoryhelper"];
                string selectedDataSourceItemUrl = dropdownlistDataSource.SelectedItem.Value;

                RepositoryLocation repositoryDatasourceLocation =
                    RepositoryLocation.CreateFromUriString(selectedDataSourceItemUrl);
                DataSource datasource = filterRepositoryHelper.DataSourceHelper.GetDataSource(repositoryDatasourceLocation);
                ViewState["datasource"] = datasource;

                // Populate the listboxStocks control with the preview data for the selected
                // data source.
                PopulateListBoxData(datasource);
            }
            else
            {
                ClearStocksListBox();
            }
        }

        // Clears the listboxStocks control.
        // The sample filter works with a web service that provides stock information.
        private void ClearStocksListBox()
        {
            listboxStocks.DataSource = null;
            listboxStocks.DataBind();
            listboxStocks.Items.Clear();
        }

        // Handles the Click event of the buttonOK control.
        protected void buttonOK_Click(object sender, EventArgs e)
        {
            EnsureChildControls();

            // Verify that the controls contain values.
            if (string.IsNullOrEmpty(textboxName.Text))
            {
                labelErrorMessage.Text = "A filter name is required.";
                return;
            }
            if (dropdownlistDataSource.SelectedIndex == 0)
            {
                labelErrorMessage.Text = "A data source is required.";
                return;
            }

            // Clear any pre-existing error message.
            labelErrorMessage.Text = string.Empty;

            // Retrieve the filter, data source, and helper objects from view state.
            string action = (string)ViewState["action"];
            string itemLocation = (string) ViewState["itemlocation"];
            Filter filter = (Filter)ViewState["filter"];
            DataSource datasource = (DataSource)ViewState["datasource"];
            FilterRepositoryHelper filterRepositoryHelper = (FilterRepositoryHelper)ViewState["filterrepositoryhelper"];

            // Update the filter object with form changes.
            filter.Name.Text = textboxName.Text;
            filter.Description.Text = textboxDescription.Text;
            filter.DataSourceLocation = datasource.Location;
            foreach (ParameterDefinition parameterDefinition in filter.BeginPoints)
            {
                parameterDefinition.DisplayName = filter.Name.Text;
            }

            // Initialize the filter. This method runs the filter's query and retrieves preview data.
            filterRepositoryHelper.GetParameterDisplayData(ref filter);

            // Save the filter object to the PerformancePoint Services repository.
            try
            {
                filter.Validate();

                if (ClickOnceLaunchValues.CreateItem.Equals(action,StringComparison.OrdinalIgnoreCase))
                {
                    Filter newFilter = filterRepositoryHelper.Create(
                        string.IsNullOrEmpty(filter.Location.ItemUrl) ? itemLocation : filter.Location.ItemUrl, filter);
                    ViewState["filter"] = newFilter;
                    ViewState["action"] = ClickOnceLaunchValues.OpenItem;
                }
                else
                {
                    filterRepositoryHelper.Update(filter);
                }
            }
            catch (Exception ex)
            {
                displayError("An error has occurred. Please contact your administrator for more information.");
                if (filterRepositoryHelper != null)
                {

                    // Add the exception detail to the server event log.
                    filterRepositoryHelper.HandleException(ex);
                }
            }
        }

        // Displays the error string in the labelErrorMessage label.
        void displayError(string msg)
        {
            EnsureChildControls();

            labelErrorMessage.Text = msg;

            // Disable the OK button because the page is in an error state.
            buttonOK.Enabled = false;
            return;
        }

        // Verifies that the properties for the filter object are set.
        static void VerifyFilter(Filter filter)
        {

            if (null != filter)
            {

                // Verify that all required properties are set.
                if (string.IsNullOrEmpty(filter.SubTypeId))
                {

                    // This value must match the subType attribute specified
                    // in the web.config file.
                    filter.SubTypeId = "SampleFilter";
                }

                if (string.IsNullOrEmpty(filter.RendererClassName))
                {
                    filter.RendererClassName = typeof (MultiSelectTreeViewControl).AssemblyQualifiedName;
                }

                // Define the BeginPoints property so the filter can send a parameter value to
                // scorecards and reports.
                // The value must be from the KeyColumn of the display
                // DataTable object, which is defined in the data provider. The data table is
                // returned by the FilterRepositoryHelper.GetParameterDisplayData method.
                // A filter has one beginpoint only, and it is represented by a
                // ParameterDefinition object. The ParameterDefinition object defines how
                // the filter accesses the data.
                if (0 == filter.BeginPoints.Count)
                {
                    ParameterDefinition paramDef = new ParameterDefinition
                                                       {
                                                           // This value must match the value returned
                                                           // by the data provider's GetId method.
                                                           ParameterProviderId = "SampleFilterDataProvider",

                                                           // Reference the data provider.
                                                           DefaultPostFormula = string.Empty,

                                                           // Specify the column that contains
                                                           // the key identifiers and the column
                                                           // that contains the display values.
                                                           // The sample uses the same column
                                                           // for both purposes.
                                                           // These values must match the structure
                                                           // of the data table that is returned
                                                           // by the ParameterDefinition.DisplayValues property.
                                                           KeyColumn = "Symbol",
                                                           DisplayColumn = "Symbol",

                                                           // You can use this property to store
                                                           // extra information for this filter.
                                                           CustomDefinition = string.Empty
                                                       };
                    filter.BeginPoints.Add(paramDef);
                }

                // Set optional properties. The renderer can return multiple values.
                filter.SelectionMode = FilterSelectionMode.MultiSelect;
            }
        }

        // Populates the dropdownlistDataSource control.
        void PopulateDataSourceDropDown(DataSource filterDataSource)
        {
            EnsureChildControls();

            FilterRepositoryHelper filterRepositoryHelper =
                (FilterRepositoryHelper)ViewState["filterrepositoryhelper"];

            // Retrieve data sources from the repository by using the DataSourceHelper
            // property to call the DataSourceConsumerHelper object.
            // If you modify the types of data source to retrieve, you must make the corresponding
            // change in the filter's data provider.
            // The parameter contains the default server-relative URL to the PerformancePoint Data Connections Library.
            // Edit this value if you are not using the default path. A leading forward slash may not be needed.
            ICollection dataSourceCollection = filterRepositoryHelper.DataSourceHelper.GetDataSourcesBySourceNames("/BICenter/Data%20Connections%20for%20PerformancePoint/",
                new[] { "WSTabularDataSource", DataSourceNames.ExcelWorkbook });
            if (null == dataSourceCollection)
            {
                displayError("No available data sources were found.");
                return;
            }

            // Create a list of name/value pairs for the dropdownlistDataSource control.
            var dataSources = new List<KeyValuePair<string, string>>();
            int selectedIndex = 0;
            int i = 1;
            dataSources.Add(new KeyValuePair<string, string>(string.Empty, string.Empty));

            foreach (DataSource ds in dataSourceCollection)
            {
                dataSources.Add(new KeyValuePair<string, string>(ds.Name.Text, ds.Location.ItemUrl));

                // Check if the entry is the originally selected data source.
                if ((filterDataSource != null) &amp;&amp;
                    (string.Compare(ds.Name.Text, filterDataSource.Name.Text) == 0))
                {
                    selectedIndex = i;
                }
                ++i;
            }

            dropdownlistDataSource.DataSource = dataSources;
            dropdownlistDataSource.DataTextField = "Key";
            dropdownlistDataSource.DataValueField = "Value";
            dropdownlistDataSource.DataBind();
            dropdownlistDataSource.SelectedIndex = selectedIndex;
        }


        // Populate the list box data.
        void PopulateListBoxData(DataSource datasource)
        {
            EnsureChildControls();

            ClearStocksListBox();

            FilterRepositoryHelper filterRepositoryHelper =
                (FilterRepositoryHelper)ViewState["filterrepositoryhelper"];

            // Retrieve the first 100 rows of the preview data from the data source
            DataSet dataSet = filterRepositoryHelper.DataSourceHelper.GetDataSet(100, datasource);

            if (null != dataSet &amp;&amp; null != dataSet.Tables[0])
            {
                listboxStocks.DataTextField = "Symbol";
                listboxStocks.DataValueField = "Value";
                listboxStocks.DataSource = dataSet.Tables[0];
                listboxStocks.DataBind();
            }
        }
    }
}

Дальнейшие действия

После создания редактора фильтров (включая его пользовательский интерфейс, если он необходим) и поставщика данных разверните расширение, как описано в статье How to: Manually Register PerformancePoint Services Extensions.

См. также