Перейти к содержанию

Использование и реализация UriLinkAPI и событий UriOpening

Пример реализации пользовательского обработчика ссылок IUriLinkHandler для desktop-клиента:

namespace Tessa.Extensions.Client { // Класс TestUriLinkHandler наследуем от StandardUriLinkHandler, чтобы иметь доступ к стандартной функциональности обработки ссылок. public class TestUriLinkHandler : StandardUriLinkHandler { public override async ValueTask OpenAsync(Uri uri, UriLinkHandlerEventType eventType, CancellationToken cancellationToken = default) { switch (eventType) {

case UriLinkHandlerEventType.HtmlPreview: // Действия в случае возникновения события из предпросмотра html. break; case UriLinkHandlerEventType.HyperLinkLabel: // Действия в случае возникновения события из контрола "Метка". break; // В остальных случаях ссылка обработается стандартным обработчиком. case UriLinkHandlerEventType.FormattedText: case UriLinkHandlerEventType.Default: default: await base.OpenAsync(uri, eventType, cancellationToken); break; } } } }

Регистрация пользовательского обработчика в DI:

namespace Tessa.Extensions.Client { [Registrator] public sealed class TestUriLinkHandlerRegistrator : RegistratorBase { public override void FinalizeRegistration() { this.UnityContainer .RegisterType<IUriLinkHandler, TestUriLinkHandler>(new ContainerControlledLifetimeManager()); } } }

Note

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

Пример вью-модели с имплементацией UriLinkAPI:

public class CustomViewModel : ViewModel<EmptyModel> { private readonly IUriLinkDependenciesFactory uriLinkDependenciesFactory;

// Необходимо получить фабрику зависимостей из DI: public CustomViewModel(IUriLinkDependenciesFactory uriLinkDependenciesFactory) { this.uriLinkDependenciesFactory = uriLinkDependenciesFactory; }

// Some code...

// Метод обработки ссылки. public async ValueTask OnUriOpeningAsync(Uri uri, ICardModel cardModel, CancellationToken cancellationToken = default) { // Получаем зависимости для обработки ссылок. // Если UIContextExecutor не задан, действие будет выполняться в неизвестном контексте (т.е. будет использован UIHelper.UnknownContextExecutorAsync). var uriLinkDependencies = this.uriLinkDependenciesFactory.Create(cardModel.UIContextExecutorAsync);

// Запускаем действие через UiContextExecutorAsync из зависимостей, он выполняет заданный метод в контексте IUIContext, // который устанавливается как текущий контекст и передаётся как параметр в заданный метод. await uriLinkDependencies.UiContextExecutorAsync.Invoke (async (context, ct) => { await uriLinkDependencies.UriLinkHandler.OpenAsync(uri, UriLinkHandlerEventType.Default, ct); }, cancellationToken); }

// Some code...

}

Пример desktop-расширения, которое добавляет обработчик события UriOpening в карточках типа “Автомобиль” для всех контролов “Текст с форматированием”.

public sealed class CarUriOpeningUIExtension : CardUIExtension { public override Task Initialized(ICardUIExtensionContext context) { if (context.Card.TypeID != DefaultCardTypes.CarTypeID) // CarTypeID - id типа карточки "Автомобиль" { return Task.CompletedTask; }

this.AddHandlers(context);

return Task.CompletedTask; }

private void AddHandlers(ICardUIExtensionContext context) { // Все контролы "Текст с форматированием". var controls = context.Model.Forms .SelectMany(x => x.Blocks) .SelectMany(x => x.Controls) .Where(x => x is CustomRichTextBoxViewModel).Cast<CustomRichTextBoxViewModel>() .ToList();

foreach (var control in controls) { // Добавление обработчика события. control.RichTextBox.UriOpening += this.LinkHandler; }

return; }

private void LinkHandler(object sender, UriLinkEventArgs e) { if (!e.Cancel) // Если требуется проверить не обработана ли данная ссылка уже в другом событии. { // Do something...

e.Cancel = true; // True, если требуется отменить вызов глобального обработчика после обработчика события UriOpening. e.Handled = true; // Это свойство можно использовать, чтобы обозначить, что событие было обработано. } } }

Back to top