Difference between revisions of "EvalExpression"
m (#2161 - Added XAML Category) |
|||
(59 intermediate revisions by 4 users not shown) | |||
Line 2: | Line 2: | ||
| title = {{PAGENAME}} | | title = {{PAGENAME}} | ||
| name = {{PAGENAME}} | | name = {{PAGENAME}} | ||
− | | namespace= UBIK.WinX.Controls | + | | namespace = "using:UBIK.WinX.Controls" in UBIK.UWP<br>"clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL" in UBIK.Xamarin |
| image = [[File:SY_{{PAGENAME}}.png|220px]] | | image = [[File:SY_{{PAGENAME}}.png|220px]] | ||
| imagecaption = imagecaption | | imagecaption = imagecaption | ||
| purpose = Evaluate a C# expression in XAML | | purpose = Evaluate a C# expression in XAML | ||
− | | version = 3.2+ | + | | version = 3.2+ in UBIK.UWP 1.0+ in UBIK.Xamarin |
}} | }} | ||
− | == | + | == Concept == |
− | The EvalExpression control allows to evaluate a C# expression from within XAML markup. The ''Expression'' has to be a single-line, valid C# | + | The EvalExpression control allows to evaluate a C# expression from within XAML markup. The ''Expression'' has to be a single-line, valid C# expression ("Lambda") and has to return a single value; expressions can also reference names of subordinate [[EvalExpression#Parameters|EvalExpressionParameter]] items. |
− | === | + | === Parameters === |
− | + | EvalExpressionParameters can be added as child objects to an EvalExpression control. Each parameter object needs a unique ''Name'' and a ''Value'', where the latter can be either a constant or dynamic value supplied through a binding. | |
+ | |||
+ | === Examples === | ||
+ | |||
+ | {{Hint|When writing expressions in XAML code, you have to avoid (escape) special characters. There are useful [https://www.freeformatter.com/xml-escape.html online tools] for this.}} | ||
+ | {{Hint|When writing expressions, it's always better (even necessary in some cases) to write them in their full forms. For example, while <nowiki>Bool_A || Bool_B</nowiki> is a valid expression, you should still write <nowiki>Bool_A==true || Bool_B==true</nowiki> instead.}} | ||
+ | {{Hint|If you want to use bindings in EvalExpressionParameters, a lot of the times you need to add <nowiki>Context="{Binding}"</nowiki> to the EvalExpression. This is because child UI elements (parameters in this case) do not inherit the binding context of the parent by default. Manually setting the context that way ensures that the same binding expressions that work outside the EvalExpression also work inside. Although this is not necessary if the binding you use explicitly refers to a named UI element.}} | ||
+ | |||
+ | ==== Evaluation without parameters ==== | ||
+ | The following example shows how to evaluate a simple expression without using any parameters and then use the result for visibility binding. | ||
+ | <tabs> | ||
+ | <tab name="UWP"> | ||
<source lang = "xml"> | <source lang = "xml"> | ||
− | <StackPanel | + | <StackPanel xmlns:ctrls="using:UBIK.WinX.Controls"> |
− | + | <ctrls:EvalExpression | |
− | + | x:Name="Evaluator" | |
− | + | Context="{Binding}" | |
− | + | Expression="Context.Values["LK_OFFLINE"]!=null || Context.Values["GUIDREF"]!=null" /> | |
− | + | <TextBlock | |
− | + | Foreground="White" | |
− | + | Text="Some Text" | |
− | + | Visibility="{Binding ElementName=Evaluator, Path=Result, Converter={StaticResource BoolToVisConverter}}" /> | |
− | + | ||
− | + | ||
− | + | ||
</StackPanel> | </StackPanel> | ||
</source> | </source> | ||
+ | The TextBlock should be visible as long as at least one of the context object's two named properties has a value. | ||
+ | </tab> | ||
+ | |||
+ | <tab name="Xamarin"> | ||
+ | <source lang = "xml"> | ||
+ | <StackLayout xmlns:ctrls="clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL"> | ||
+ | <ctrls:EvalExpression | ||
+ | x:Name="Evaluator" | ||
+ | Context="{Binding}" | ||
+ | Expression="Context.Values["LK_EXAMPLE"]!=null || Context.Values["GUIDREF"]!=null" /> | ||
+ | <Label | ||
+ | TextColor="#00000" | ||
+ | IsVisible="{Binding Path=Result, Source={x:Reference Evaluator}, Converter={StaticResource BoolToBool}}" /> | ||
+ | </StackLayout> | ||
+ | </source> | ||
+ | The Label should be visible as long as at least one of the context object's two named properties has a value. | ||
+ | </tab> | ||
+ | </tabs> | ||
+ | |||
+ | ==== Simple calculation ==== | ||
+ | <tabs> | ||
+ | <tab name="UWP"> | ||
+ | The following example shows how to use an expression with two parameters (''Param0'' and ''Param1''). The evaluated ''Result'' is then bound to a TextBlock for output in the UI. | ||
+ | <source lang = "xml"> | ||
+ | <StackPanel xmlns:ctrls="using:UBIK.WinX.Controls"> | ||
+ | <TextBox x:Name="Expression" Width="200" /> | ||
+ | <TextBox x:Name="Param0" Width="200" /> | ||
+ | <TextBox x:Name="Param1" Width="200" /> | ||
+ | <ctrls:EvalExpression x:Name="Evaluator" Expression="{Binding ElementName=Expression, Path=Text}" Context="{Binding}"> | ||
+ | <ctrls:EvalExpressionParameter Name="P0" Value="{Binding ElementName=Param0, Path=Text, Converter={StaticResource ToType}, ConverterParameter='System.Int32'}" /> | ||
+ | <ctrls:EvalExpressionParameter Name="P1" Value="{Binding ElementName=Param1, Path=Text, Converter={StaticResource ToType}, ConverterParameter='System.Int32'}" /> | ||
+ | </ctrls:EvalExpression> | ||
+ | <TextBlock Foreground="White" Text="{Binding ElementName=Evaluator, Path=Result}" /> | ||
+ | </StackPanel> | ||
+ | </source> | ||
+ | Lets assume that the Textbox ''Param0'' contains a text of 42 and ''Param1'' contains a text of 43. If ''Expression'' now contains <code>(P0 + P1) *2</code> then the result would display 170. | ||
+ | </tab> | ||
+ | |||
+ | <tab name="Xamarin"> | ||
+ | The following example shows how to use an expression with two parameters (''Param0'' and ''Param1''). The evaluated ''Result'' is then bound to a Label for output in the UI. | ||
+ | <source lang = "xml"> | ||
+ | <StackLayout xmlns:ctrls="clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL"> | ||
+ | <Editor x:Name="Expression"/> | ||
+ | <Editor x:Name="Param0" WidthRequest="32"/> | ||
+ | <Editor x:Name="Param1" WidthRequest="43"/> | ||
+ | <ctrls:EvalExpression x:Name="Evaluator" Expression="{Binding Path=Text, Source={x:Reference Expression}}" Context="{Binding}"> | ||
+ | <ctrls:EvalExpressionParameter Name="P0" Value="{Binding Path=WidthRequest, Source={x:Reference Param0}}" /> | ||
+ | <ctrls:EvalExpressionParameter Name="P1" Value="{Binding Path=WidthRequest, Source={x:Reference Param1}}" /> | ||
+ | </ctrls:EvalExpression> | ||
+ | <Label Text="{Binding Path=Result, Source={x:Reference Evaluator}}" /> | ||
+ | </StackLayout> | ||
+ | </source> | ||
+ | Since Textbox ''P0'' has a width of 32 and ''P1'' has a width of 43. If ''Expression'' now contains <code>(P0 + P1)</code> then the result would display 75. | ||
+ | </tab> | ||
+ | </tabs> | ||
+ | |||
+ | ==== Setting a calculated property value ==== | ||
+ | The following example shows how to create a button that adds and stores +5 to the value of a a numeric property named ''MP_EXAMPLE'', every time it is pressed: | ||
+ | <tabs> | ||
+ | <tab name="UWP"> | ||
+ | <source lang = "xml"> | ||
+ | <Grid xmlns:ctrls="using:UBIK.WinX.Controls"> | ||
+ | <ctrls:EvalExpression x:Name="Evaluator" Expression=""MP_EXAMPLE|" + (P0 + 5)" Context="{Binding}"> | ||
+ | <ctrls:EvalExpressionParameter Name="P0" Value="{Binding Values[MP_EXAMPLE]}" /> | ||
+ | </ctrls:EvalExpression> | ||
+ | <Button | ||
+ | Content="Tap for 5 more" | ||
+ | Command="{Binding SetPropertyValueAndValidateCommand}" | ||
+ | CommandParameter="{Binding ElementName=Evaluator, Path=Result}"/> | ||
+ | </Grid> | ||
+ | </source> | ||
+ | </tab> | ||
+ | |||
+ | <tab name="Xamarin"> | ||
+ | <source lang = "xml"> | ||
+ | <Grid xmlns:ctrls="clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL"> | ||
+ | <ctrls:EvalExpression x:Name="Evaluator" Expression=""MP_EXAMPLE|" + (P0 + 5)" Context="{Binding}"> | ||
+ | <ctrls:EvalExpressionParameter Name="P0" Value="{Binding Values[MP_EXAMPLE]}" /> | ||
+ | </ctrls:EvalExpression> | ||
+ | <Button | ||
+ | Text="Tap to add 5 more" | ||
+ | Command="{Binding SetPropertyValueAndValidateCommand}" | ||
+ | CommandParameter="{Binding Path=Result, Source={x:Reference Evaluator}}"/> | ||
+ | </Grid> | ||
+ | </source> | ||
+ | </tab> | ||
+ | </tabs> | ||
+ | |||
+ | ==== Conditional statement ==== | ||
+ | |||
+ | If / Or statements can also be evaluated using C# syntax. | ||
+ | In this case, if the result of the "Condi" parameter is true, namely if the context object's MP_STATUS property value equals to 0, P0's value will be displayed in the Label, otherwise P1's value will be displayed. | ||
+ | |||
+ | <tabs> | ||
+ | <tab name="UWP"> | ||
+ | <source lang = "xml"> | ||
+ | <Grid xmlns:ctrls="using:UBIK.WinX.Controls"> | ||
+ | <ctrls:EvalExpression x:Name="Evaluator" Expression="Condi == true ? P0 : P1" Context="{Binding}"> | ||
+ | <ctrls:EvalExpressionParameter Name="Condi" Value="{Binding Values[MP_STATUS], Converter={StaticResource EqualToTrueConverter}, ConverterParameter=0}" /> | ||
+ | <ctrls:EvalExpressionParameter Name="P0" Value="State1" /> | ||
+ | <ctrls:EvalExpressionParameter Name="P1" Value="State2" /> | ||
+ | </ctrls:EvalExpression> | ||
+ | <TextBlock Text="{Binding ElementName=Evaluator, Path=Result}" /> | ||
+ | </Grid> | ||
+ | </source> | ||
+ | </tab> | ||
+ | |||
+ | <tab name="Xamarin"> | ||
+ | <source lang = "xml"> | ||
+ | <Grid xmlns:ctrls="clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL"> | ||
+ | <ctrls:EvalExpression x:Name="Evaluator" Expression="Condi == true ? P0 : P1" Context="{Binding}"> | ||
+ | <ctrls:EvalExpressionParameter Name="Condi" Value="{Binding Values[MP_STATUS], Converter={StaticResource EqualityToBool}, ConverterParameter=0}" /> | ||
+ | <ctrls:EvalExpressionParameter Name="P0" Value="State1" /> | ||
+ | <ctrls:EvalExpressionParameter Name="P1" Value="State2" /> | ||
+ | </ctrls:EvalExpression> | ||
+ | <Label Text="{Binding Path=Result, Source={x:Reference Evaluator}}" /> | ||
+ | </Grid> | ||
+ | </source> | ||
+ | </tab> | ||
+ | </tabs> | ||
+ | |||
+ | |||
− | |||
− | |||
− | |||
==See also== | ==See also== | ||
* [[XAML]] | * [[XAML]] | ||
+ | [[Category:Client|EvalExpression]] | ||
[[Category:Pages with broken file links|EvalExpression]] | [[Category:Pages with broken file links|EvalExpression]] | ||
+ | [[Category:WinX|EvalExpression]] | ||
+ | [[Category:Xamarin|EvalExpression]] | ||
+ | [[Category:XAML|EvalExpression]] |
Latest revision as of 12:39, 4 April 2024
EvalExpression | |
---|---|
220px | |
imagecaption | |
Name | EvalExpression |
Namespace | "using:UBIK.WinX.Controls" in UBIK.UWP "clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL" in UBIK.Xamarin |
Purpose | Evaluate a C# expression in XAML |
Version | 3.2+ in UBIK.UWP 1.0+ in UBIK.Xamarin |
Contents
Concept
The EvalExpression control allows to evaluate a C# expression from within XAML markup. The Expression has to be a single-line, valid C# expression ("Lambda") and has to return a single value; expressions can also reference names of subordinate EvalExpressionParameter items.
Parameters
EvalExpressionParameters can be added as child objects to an EvalExpression control. Each parameter object needs a unique Name and a Value, where the latter can be either a constant or dynamic value supplied through a binding.
Examples
When writing expressions in XAML code, you have to avoid (escape) special characters. There are useful online tools for this. |
Evaluation without parameters
The following example shows how to evaluate a simple expression without using any parameters and then use the result for visibility binding.
UWP
<ctrls:EvalExpression
x:Name="Evaluator"
Context="{Binding}"
Expression="Context.Values["LK_OFFLINE"]!=null || Context.Values["GUIDREF"]!=null" />
<TextBlock
Foreground="White"
Text="Some Text"
Visibility="{Binding ElementName=Evaluator, Path=Result, Converter={StaticResource BoolToVisConverter}}" />
</StackPanel>
The TextBlock should be visible as long as at least one of the context object's two named properties has a value.
Xamarin
<ctrls:EvalExpression
x:Name="Evaluator"
Context="{Binding}"
Expression="Context.Values["LK_EXAMPLE"]!=null || Context.Values["GUIDREF"]!=null" />
<Label
TextColor="#00000"
IsVisible="{Binding Path=Result, Source={x:Reference Evaluator}, Converter={StaticResource BoolToBool}}" />
</StackLayout>
The Label should be visible as long as at least one of the context object's two named properties has a value.
Simple calculation
UWP
The following example shows how to use an expression with two parameters (Param0 and Param1). The evaluated Result is then bound to a TextBlock for output in the UI.
<TextBox x:Name="Expression" Width="200" />
<TextBox x:Name="Param0" Width="200" />
<TextBox x:Name="Param1" Width="200" />
<ctrls:EvalExpression x:Name="Evaluator" Expression="{Binding ElementName=Expression, Path=Text}" Context="{Binding}">
<ctrls:EvalExpressionParameter Name="P0" Value="{Binding ElementName=Param0, Path=Text, Converter={StaticResource ToType}, ConverterParameter='System.Int32'}" />
<ctrls:EvalExpressionParameter Name="P1" Value="{Binding ElementName=Param1, Path=Text, Converter={StaticResource ToType}, ConverterParameter='System.Int32'}" />
</ctrls:EvalExpression>
<TextBlock Foreground="White" Text="{Binding ElementName=Evaluator, Path=Result}" />
</StackPanel>
Lets assume that the Textbox Param0 contains a text of 42 and Param1 contains a text of 43. If Expression now contains (P0 + P1) *2
then the result would display 170.
Xamarin
The following example shows how to use an expression with two parameters (Param0 and Param1). The evaluated Result is then bound to a Label for output in the UI.
<Editor x:Name="Expression"/>
<Editor x:Name="Param0" WidthRequest="32"/>
<Editor x:Name="Param1" WidthRequest="43"/>
<ctrls:EvalExpression x:Name="Evaluator" Expression="{Binding Path=Text, Source={x:Reference Expression}}" Context="{Binding}">
<ctrls:EvalExpressionParameter Name="P0" Value="{Binding Path=WidthRequest, Source={x:Reference Param0}}" />
<ctrls:EvalExpressionParameter Name="P1" Value="{Binding Path=WidthRequest, Source={x:Reference Param1}}" />
</ctrls:EvalExpression>
<Label Text="{Binding Path=Result, Source={x:Reference Evaluator}}" />
</StackLayout>
Since Textbox P0 has a width of 32 and P1 has a width of 43. If Expression now contains (P0 + P1)
then the result would display 75.
Setting a calculated property value
The following example shows how to create a button that adds and stores +5 to the value of a a numeric property named MP_EXAMPLE, every time it is pressed:
UWP
<ctrls:EvalExpression x:Name="Evaluator" Expression=""MP_EXAMPLE|" + (P0 + 5)" Context="{Binding}">
<ctrls:EvalExpressionParameter Name="P0" Value="{Binding Values[MP_EXAMPLE]}" />
</ctrls:EvalExpression>
<Button
Content="Tap for 5 more"
Command="{Binding SetPropertyValueAndValidateCommand}"
CommandParameter="{Binding ElementName=Evaluator, Path=Result}"/>
</Grid>
Xamarin
<ctrls:EvalExpression x:Name="Evaluator" Expression=""MP_EXAMPLE|" + (P0 + 5)" Context="{Binding}">
<ctrls:EvalExpressionParameter Name="P0" Value="{Binding Values[MP_EXAMPLE]}" />
</ctrls:EvalExpression>
<Button
Text="Tap to add 5 more"
Command="{Binding SetPropertyValueAndValidateCommand}"
CommandParameter="{Binding Path=Result, Source={x:Reference Evaluator}}"/>
</Grid>
Conditional statement
If / Or statements can also be evaluated using C# syntax. In this case, if the result of the "Condi" parameter is true, namely if the context object's MP_STATUS property value equals to 0, P0's value will be displayed in the Label, otherwise P1's value will be displayed.
UWP
<ctrls:EvalExpression x:Name="Evaluator" Expression="Condi == true ? P0 : P1" Context="{Binding}">
<ctrls:EvalExpressionParameter Name="Condi" Value="{Binding Values[MP_STATUS], Converter={StaticResource EqualToTrueConverter}, ConverterParameter=0}" />
<ctrls:EvalExpressionParameter Name="P0" Value="State1" />
<ctrls:EvalExpressionParameter Name="P1" Value="State2" />
</ctrls:EvalExpression>
<TextBlock Text="{Binding ElementName=Evaluator, Path=Result}" />
</Grid>
Xamarin
<ctrls:EvalExpression x:Name="Evaluator" Expression="Condi == true ? P0 : P1" Context="{Binding}">
<ctrls:EvalExpressionParameter Name="Condi" Value="{Binding Values[MP_STATUS], Converter={StaticResource EqualityToBool}, ConverterParameter=0}" />
<ctrls:EvalExpressionParameter Name="P0" Value="State1" />
<ctrls:EvalExpressionParameter Name="P1" Value="State2" />
</ctrls:EvalExpression>
<Label Text="{Binding Path=Result, Source={x:Reference Evaluator}}" />
</Grid>