- Hands-On Mobile Development with .NET Core
- Can Bilgin
- 302字
- 2021-06-24 13:55:40
XAML markup extensions
Up until now, when we created XAML views, we resorted to several markup extensions that are supported either by the Xamarin.Forms framework or the XAML namespace itself. Some of these extensions are as follows:
- x:Reference: Used to refer to another view on the same page
- Binding: Used throughout the view model implementations
- StaticResource: Used to refer to styles
These are all markup extensions that are resolved by the associated service implementation within the Xamarin.Forms framework.
For specific needs in your application, custom markup extensions can be implemented to create a more maintainable XAML structure. In order to create a markup extension, the IMarkupExtension<T> class needs to be implemented. This depends on the type that needs to be provided.
For instance, in our previous example, the error label and the field descriptors were hard coded into the XAML view. This would create issues if the application needs to support multiple localizations. This can be resolved by doing the following:
- First, we need to create a markup extension that will translate the associated text values:
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension<string>
{
public string Text { get; set; }
public string ProvideValue(IServiceProvider serviceProvider)
{
// TODO:
}
object IMarkupExtension.ProvideValue(IServiceProvider
serviceProvider)
{
return (this as
IMarkupExtension<string>).ProvideValue(serviceProvider);
}
}
- Note that the Text property is set as ContentProperty, which allows developers to provide a value for this extension simply by adding a value for the extension. Let's incorporate it into the XAML structure:
<Label Text="{behaviors:Translate LblUsername}" />
<Entry x:Name="usernameEntry" Placeholder="username"
Text="{Binding UserName, Mode=OneWayToSource}" >
<Entry.Behaviors>
<behaviors:ValidationBehavior x:Name="UserNameValidation" ValidationRule="{Binding BindingContext.UserNameValidation, Source={x:Reference RootView}}" />
</Entry.Behaviors>
</Entry>
<Label Text="{behaviors:Translate LblRequiredError}"
FontSize="12" TextColor="Gray"
IsVisible="{Binding HasError, Source={x:Reference UserNameValidation}}"/>
- ProvideValue method would therefore need to translate the LblUsername and LblRequiredError keys:
public string ProvideValue(IServiceProvider serviceProvider)
{
switch (Text)
{
case "LblRequiredError":
return "This a required field";
case "LblUsername":
return "Username";
default:
return Text;
}
}
This completes the quadrant II customizations. Now, we will move on to quadrant III and the customize native controls.