Skip to main content

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.