Записи с меткой «Silverlight»

PostHeaderIcon Права пользователя на запись

Способ получения прав пользователя на конкретную запись в системе в CRM 2011 (пример на Silverlight с использованием библиотеки SilverCrmSoap).

var userId = new Guid("DF7A9B5D-B0FB-E011-890C-E61F137DE58F");
var entityName = "new_myentity";
var entityId = new Guid("3FA22F05-BA9D-E111-AD62-E61F137DE58F");

bool appendAccess;
bool appendToAccess;
bool assignAccess;
bool createAccess;
bool deleteAccess;
bool readAccess;
bool shareAccess;
bool writeAccess;

var request = new OrganizationRequest { RequestName = "RetrievePrincipalAccess" };
request["Principal"] = new EntityReference { LogicalName = "systemuser", Id = userId };
request["Target"] = new EntityReference { LogicalName = entityName, Id = entityId };
SilverCrmSoap.Helpers.SoapHelper.BeginExecute(request, delegate(IAsyncResult result)
{
    var response = ((IOrganizationService)result.AsyncState).EndExecute(result);
    var rights = (AccessRights)response["AccessRights"];

    appendAccess = rights.HasFlag(AccessRights.AppendAccess);
    appendToAccess = rights.HasFlag(AccessRights.AppendToAccess);
    assignAccess = rights.HasFlag(AccessRights.AssignAccess);
    createAccess = rights.HasFlag(AccessRights.CreateAccess);
    deleteAccess = rights.HasFlag(AccessRights.DeleteAccess);
    readAccess = rights.HasFlag(AccessRights.ReadAccess);
    shareAccess = rights.HasFlag(AccessRights.ShareAccess);
    writeAccess = rights.HasFlag(AccessRights.WriteAccess);
});

PostHeaderIcon Получение списка выбранных записей CRM 2011 в Silverlight-приложении, открытом в не модальном окне

Задача

Есть приложение на Silverlight в котором необходимо получить список ID выделенных в таблице записей. При этом приложение открывается в не модальном диалоговом окне (modeless dialog).

Решение

Для начала нужно создать кнопку на Ribbon, которая будет вызывать JS-функцию, а так же передавать в нее список выбранных в таблице записей. Получить список выбранных записей не представляет труда, достаточно использовать CrmParameter. Можно конечно открыть окно Silverlight-приложения напрямую и передать список ID через строку адреса, но она имеет ограничение по длине, которое легко превысить.

Далее необходимо создать JS-функцию, вызываемую кнопкой. Функция будет подготавливать данные и открывать окно Silverlight-приложения. JS-код может выглядеть следующем образом:

function OpenSLApp(ids) {
    var data = new Object();
    data.ids = ids;
    var page = context.prependOrgName('/WebResources/be_/SLApp/Loader.html');
    window.showModelessDialog(page, data, "dialogWidth:800px;dialogHeight:600px;center:yes;status:false;");
}

Тут есть одна хитрость: для того чтобы иметь возможность получить передаваемый список в Silverlight его необходимо не напрямую передавать как параметр окна, а передавать как значение свойства некого объекта.

И наконец теперь можно получить список ID в Silverlight:

var ids = new List<Guid>();
dynamic dialogArguments = HtmlPage.Window.GetProperty("dialogArguments");
var guids = dialogArguments.ids;
if (guids != null)
{
    for (var i = 0; i < guids.length; ++i)
    {
        dynamic item = guids[i];
        if (!(item is string)) continue;
        var objectValue = (string)item;
        ids.Add(new Guid(objectValue));
    }
}

PostHeaderIcon Выполнение запроса WhoAmI с помощью библиотеки SilverSrmCoap

Выполнение запроса на получение ID текущего пользователя (WhoAmIRequest).

var request = new OrganizationRequest { RequestName = "WhoAmI" };
SilverCrmSoap.Helpers.SoapHelper.BeginExecute(request, delegate(IAsyncResult result)
{
	var response = ((IOrganizationService)result.AsyncState).EndExecute(result);
	var userId = (Guid)response["UserId"];
});

PostHeaderIcon Связывание команд в Silverlight при использовании паттерна MVVM

Если нужно связать команду с событием Click кнопки, то все достаточно просто:

<Button Command="{Binding NewEventCommand}" />

NewEventCommand — команда, унаследованная от ICommand, из класса контекста.

Если же нужно связать команду к другим событием, то нужно предпринять ряд действий.

Первое что нужно сделать — подключить к проекту библиотеку System.Windows.Interactivity.

Второе — указать на странице использование пространства имен:

<UserControl
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">

Дальше можно описывать связывание:

<Button ClickMode="Hover">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseLeftButtonDown">
            <i:InvokeCommandAction Command="{Binding Path=NewEventCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

Обратите внимание на атрибут ClickMode. Если не установить его в Hover событие MouseLeftButtonDown (и ряд других событий) не будет происходит.

В атрибуте EventName необходимо указывать имя события, как оно указано для элемента управления.

Подобным способом можно связывать команды не только для кнопок, но и для других элементов управления (например ListBox, Image и др.).

PostHeaderIcon Доступ к родительскому контексту из элементов, расположенных в GridView в Silverlight

Есть страница типа UserControl, которой передается некий класс в качестве контекста. На странице расположен GridView (Telerik RadGridView в данном случае), в ячейках которого расположены, например, кнопки и эти кнопки должны брать данные (например, иметь доступ к команде) из контекста страницы.

Для решения задачи необходимо создать статический ресурс, связав его с контекстом страницы, после чего этот ресурс указывать в кнопках в качестве источника.

<UserControl.Resources>
    <ContentControl x:Key="CurrentDataContext" Content="{Binding}" />
</UserControl.Resources>
<telerik:RadGridView>
    <telerik:RadGridView.Columns>
        <telerik:GridViewColumn>
            <telerik:GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Button ClickMode="Hover">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseLeftButtonDown">
                                <i:InvokeCommandAction Command="{Binding Source={StaticResource CurrentDataContext}, Path=Content.NewEventCommand}" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Button>
                </DataTemplate>
            </telerik:GridViewColumn.CellTemplate>
        </telerik:GridViewColumn>
    </telerik:RadGridView.Columns>
</telerik:RadGridView>

PostHeaderIcon Выполнение процесса (Workflow) из Silverlight при использовании библиотеки SilverCrmSoap

private void ExecuteWorkflow(Guid entityId, Guid workflowId)
{
    var request = new OrganizationRequest
    {
        RequestName = "ExecuteWorkflow",
        Parameters = new ParameterCollection
        {
            new SilverCrmSoap.CrmSdk.KeyValuePair<string, object> { Key = "EntityId", Value = entityId },
            new SilverCrmSoap.CrmSdk.KeyValuePair<string, object> { Key = "WorkflowId", Value = workflowId }
        }
    };
    SilverCrmSoap.Helpers.SoapHelper.BeginExecute(request, delegate(IAsyncResult result)
    {
        try
        {
            ((IOrganizationService)result.AsyncState).EndExecute(result);
        }
        catch (Exception ex)
        {
            HtmlPage.Window.Alert("Ошибка выполнения Workflow!");
        }
    });
}

PostHeaderIcon Получение метаданных сущности в Silverlight

SilverCrmSoap.Helpers.SoapHelper.BeginExecuteRetrieveEntity("new_agreement", delegate(IAsyncResult result)
{
	try
	{
		var response = ((IOrganizationService)result.AsyncState).EndExecute(result);
		var entityMetadata = ((EntityMetadata)response["EntityMetadata"]);
		...
	}
	catch (Exception ex)
	{
		...
	}
});

Для доступа к данным используется библиотека SilverCrmSoap.

PostHeaderIcon Ошибка 2103 “Недопустимое или неправильно сформированное приложение: проверьте манифест”

Ошибка Silverlight-приложения:

(по-русски)

SCRIPT5022: Unhandled Error in Silverlight Application
Code: 2103
Category: InitializeError
Message: Недопустимое или неправильно сформированное приложение: проверьте манифест

(по-английски)

SCRIPT5022: Unhandled Error in Silverlight Application
Code: 2103
Category: InitializeError
Message: Invalid or malformed application: Check manifest

По-поводу данной ошибки в интернете можно найти только информацию о том, что она возникает по причине не указанного или некорректного Startap Object.

Однако, практика показала, что данная ошибка может быть еще по одной причине – некорректный HTML-файла.

В попытке побороть кэширование Silverlight-приложения, HTML-файл был изменен следующим образом:

...
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
    <param name="source" value="App.xap?ver=1.01"/>
    ...
</object>

Т.е. к имени файла приложения добавлен параметр с номером версии. Проблема оказалась в точке в номере версии. Именно она вызывала ошибку. Кроме того ошибку вызывал любой символ кроме цифры. Стоило убрать точку, как приложение заработало.

Причина такого поведения непонятна.

PostHeaderIcon DatePicker Binding и пустое значение

Есть элемент управления DatePicker с которым связано некое свойство BirthDate типа DateTime.

<sdk:DatePicker SelectedDate="{Binding Path=BirthDate, Mode=TwoWay}" />

Данная связь будет работать только пока значение DatePicker не пустое. В случае очистки значения элемента управления это пустое значение не будет передано свойству и свойство будет содержать свое прежнее значение.

Происходит это потому, что при очистке значения DatePicker его свойство SelectedDate получает значение null, а в нашем примере свойство BirthDate не может иметь нулевое значение.

Решение проблемы очевидно — необходимо объявить свойство BirthDate как Nullable, то есть объявление свойства должно выглядеть таким образом:

public DateTime? BirthDate { get; set; }

PostHeaderIcon Конвертер bool<->Visibility

Конвертер для преобразования значения булева типа к типу параметра Visibility элемента управления.

using System;
using System.Windows;
using System.Windows.Data;

namespace BE.Silverlight.UI.Converters
{
    /// <summary>
    /// Конвертер позволяет преобразованть булево значение к значению свойства Visibility элемента управления.
    /// </summary>
    public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (bool)value == true ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (Visibility)value == Visibility.Visible;
        }
    }
}