官术网_书友最值得收藏!

Xamarin.Forms effects

Xamarin.Forms effects are an elegant bridge between the cross-platform domain and the native domain. Effects are generally used to expose a certain platform behavior or implementation of a given native control through the shared domain so that a completely new custom native control is not needed for the implementation.

Similar to the Xamarin.Forms views/controls, effects exist on both the shared domain and the native domain with their abstraction and implementation, respectively. While the shared domain is used to create a routing effect, the native project is responsible for consuming it.

For instance, let's assume the details that we receive for our product items actually contain some HTML data that we would like to present within the application. In this case, we are aware of the fact that the Label element on Xamarin.Forms is rendered with a UILabel in iOS and TextView in Android. While UILabel provides the AttributedString property (which can be created from HTML), the Android platform offers the intrinsic module for parsing HTML. We can expose these platform-specific features using an effect and enable the Xamarin.Forms abstraction to accept HTML input. Let's get started:

  1. Create the routing effect that will provide the data for the platform effects:
 public class HtmlTextEffect: RoutingEffect
{
public HtmlTextEffect(): base("FirstXamarinFormsApplication.HtmlTextEffect")
{
}

public string HtmlText { get; set; }
}
  1. Now, we can use this effect in our XAML:
 <Label Text="{Binding Description}">
<Label.Effects>
<effects:HtmlTextEffect
HtmlText="<b>Here</b> is some
<u>HTML</u>" />

</Label.Effects>
</Label>

Without the platform implementation of this routing effect, the label will still display the binding data (in this case, encoded HTML text).

  1. Now, we need to implement the iOS effect that will parse the HtmlText property of our effect. Platform effects are mainly composed of two main components: registration and implementation:
 [assembly: ResolutionGroupName("FirstXamarinFormsApplication")]
[assembly: ExportEffect(typeof(HtmlTextEffect), "HtmlTextEffect")]
namespace FirstXamarinFormsApplication.iOS.Effects
{
public class HtmlTextEffect: PlatformEffect
{
protected override void OnAttached()
{
}

protected override void OnDetached()
{
}
}
}

The effect that's registered with ResolutionGroupName of the ExportEffect attributes will be used in the runtime environment to resolve the routing effect that was implemented in the first step. In order to modify the native control, you can use the Control property of PlatformEffect. The Element property refers to the Xamarin.Forms control that requires this effect.

  1. Now, we need to implement the OnAttached method (which will be executed when PlatformEffect is resolved):
 protected override void OnAttached()
{
var htmlTextEffect = Element.Effects
.OfType<Client.Effects.HtmlTextEffect>
()
.FirstOrDefault();


if(htmlTextEffect != null && Control is UILabel label)
{
var documentAttributes = new NSAttributedStringDocumentAttributes();
documentAttributes.DocumentType = NSDocumentType.HTML;
var error = new NSError();

label.AttributedText = new NSAttributedString(htmlTextEffect.HtmlText, documentAttributes, ref error);
}
}
  1. A similar implementation for the Android platform will create the HTML rendering of the controls:
 protected override void OnAttached()
{
var htmlTextEffect = Element.Effects
.OfType<Client.Effects.HtmlTextEffect>
()
.FirstOrDefault();


if (htmlTextEffect != null && Control is TextView label)
{
label.SetText(
Html.FromHtml(htmlTextEffect.HtmlText,
FromHtmlOptions.ModeLegacy),
TextView.BufferType.Spannable);

}
}

While we have managed to display HTML content on our Xamarin.Forms view, the value we have used is still not bindable. With a little restructuring, and by using attached properties (that is, attached behavior), we can use the data binding and effects together.

主站蜘蛛池模板: 铁岭市| 阳高县| 莱西市| 安溪县| 大名县| 文安县| 五家渠市| 云南省| 铁岭县| 天峨县| 兴安盟| 宾阳县| 霸州市| 洛宁县| 江门市| 仪陇县| 宁蒗| 竹山县| 罗江县| 铁力市| 闽清县| 临武县| 莒南县| 汝州市| 青田县| 东山县| 营山县| 云和县| 巴里| 江城| 资兴市| 泊头市| 瑞丽市| 松江区| 历史| 云龙县| 武安市| 武山县| 遂平县| 盐池县| 英山县|