XAML Expressions
Grial XAML expressions are markup extensions that extend XAML by allowing element attributes to be set from sources other than literal text strings. For more information, see Markup Extensions
Writing XAML expressions is far way faster than creating a Converter
or defining a calculated property in a View-Model
. In grial we provide a bunch of xaml expressions, such as:
- grial:Eval
- grial:IfEval
- grial:If
- grial:And
- grial:Or
- grial:Not
info
If you need to use a variable with unknown type inside the expression, you should use: EvalExtension.AddKnownType<T>()
or EvalExtension.AddKnownType(Type)
, where T is the type. C#, .NET MAUI and UXDivers.Grial types are already known.
Examples
The grial:Eval
markup extension evaluates the condition specified inside it and returns the result as a boolean.
<Label
Text="Label"
IsVisible="{
grial:Eval 'A > 10',
A={ Binding Products.Count }
}" />
So, above the label will be visible if Products.Count is greater than 10.
grial:IfEval
evaluates the expression specified inside it and in case it's true it returns what the Then
clause specifies, else, it returns what the Else
clause specifies.
grial:If
evaluates the condition specified inside it and in case it's true it returns what the Then
clause specifies, else, it returns what the Else
clause specifies. The ResultType
helps to identify the type of the xaml expression result.
<Switch x:Name="switch">
<Label
Text="{ grial:If Condition={ Binding IsToggled, Source={x:Reference switch } }, Then='on', Else='off', ResultType={ x:Type x:String } }"
TextColor="{ DynamicResource BodyFontColor }"
VerticalTextAlignment="Center"
FontSize="16" />
grial:And
evaluates the expressions specified in Left and Right, and returns the result of the conjunction of both expressions.
<BoxView
IsVisible="{ grial:And
Left={ Binding IsToggled, Source={x:Reference switch } },
Right={ Binding IsFollowing } }"
Color="{ DynamicResource AccentColor }"
HeightRequest="100"
WidthRequest="100" />
grial:Or
evaluates the expressions specified in Left and Right, and returns the result of the disjunction of both expressions.
grial:Not
evaluates the expression specified in Condition, and returns the result of negating the expression.
<Label
Text="{ grial:Format Expression={grial:Translate StringWithParameterKey}, A={Binding ParameterValue} }">
grial:Format
evaluates the expression and replaces the key in StringWithParameterKey with the value provided in A, in this case, ParameterValue.
iOS Devices - Eval and IfEval
caution
When running in full Ahead of Time (AOT) compiled environments such as iOS devices in RELEASE mode, Eval
and IfEval
expressions with more than 2 parameters won't work unless MtouchInterpreter
is enabled.
Eval Expressions use Linq Expressions behind the scenes, and Linq Expressions with more than 2 parameters don't work in iOS runtime as pointed out here: https://github.com/dotnet/runtime/issues/94063
When trying to dynamically compile such expressions, an exception with this message is thrown: Attempting to JIT compile method ... while running in aot-only mode.
The workaround is enabling the Mono Interpreter, letting it take care of dynamic evaluations. This is the best way to do that:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<MtouchInterpreter>-all</MtouchInterpreter>
</PropertyGroup>
The -all
value forces every DLL to be AOT compiled so it doesn't have a performance hit, only enabling the interpreter to be available for these kind of dynamic scenarios. You can read more here:
https://github.com/dotnet/maui/issues/13019
Just bare in mind that the IL code will probably be part of the deployed application, and that might have security implications. You can read about this in the same Github issue.