How to Bind Two Controls in Xamarin forms - xamarin

Is it possible to bind a control's value to another, like:
<Stepper x:Name="myValue"
Maximum="1000"
Minimum="0"
Value="{Binding myValue,Mode=TwoWay}" />
<Entry Keyboard="Numeric"
Text="{Binding myValue}"
TextColor="Black" />

use {x:Reference } markup extension
<Stepper x:Name="myValue"
Maximum="1000"
Minimum="0"
Value="{Binding myValue, Mode=TwoWay}" />
<Entry Keyboard="Numeric"
Text="{Binding Value, Source={x:Reference myValue}}"
TextColor="Black" />

Related

How to display string length in winui3 while typing

I would like to display the length of a string in a textbox while typing. The code below works in WPF but does not in WinUI3. How must I adapt the code below?
<TextBox Name="tbInput" Text="{x:Bind Path=ViewModel.Input, Mode=TwoWay}" />
<TextBlock>
<Run Text="{Binding ElementName=tbInput, Path=Text.Lenght, Mode=OneWay}" />
</TextBlock>
Use x:Bind:
<TextBlock>
<Run Text="{x:Bind tbInput.Text.Length, Mode=OneWay}" />
</TextBlock>
Or bind directly to the source property (assuming the view model implements INotifyPropertyChanged):
<TextBox Name="tbInput" Text="{x:Bind Path=ViewModel.Input, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<TextBlock>
<Run Text="{x:Bind Path=ViewModel.Input.Length, Mode=OneWay}" />
</TextBlock>

Multi Data Trigger In Xamarin Forms

I am attempting to allow click on my button ONLY if the two text fields are not null. However, I am getting the compile error of
Type multi-data trigger not found
Below is my syntax, how should I change it so it executes as desired?
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" >
<ContentPage.Content>
<StackLayout Orientation="Vertical" Padding="30" Spacing="40">
<BoxView HeightRequest="10"/>
<Frame BackgroundColor="#BF043055" HasShadow="False">
<StackLayout Orientation="Vertical" Spacing="10">
<Entry x:Name="Email" Text="{Binding Email}" Placeholder="Email"
PlaceholderColor="Red" HeightRequest="50"
Keyboard="Email" TextColor="Black" />
<Entry x:Name="Password" Text="{Binding Password}" Placeholder="Password"
PlaceholderColor="Red" HeightRequest="50"
IsPassword="True" TextColor="Black" />
</StackLayout>
</Frame>
<Button x:Name="loginbutton" Command="{Binding SubmitCommand}" Text="Login" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Email, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=Password, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
EDIT
I edited my syntax to the below but I am getting a compile error of:
No property, bindable property, or event found for 'ElementName', or mismatching type between value and property.
<Button x:Name="loginbutton" Command="{Binding SubmitCommand}" Text="Login" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiTrigger TargetType="{x:Type Button}">
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Email, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=Password, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
MultiDataTrigger is specific to WPF. Xamarin uses MultiTrigger, which essentially does the same thing. Have a look through this blog post to see how to implement Triggers in Xamarin Forms.

Passing button value as command parameter

I have a calculator style grid. How can I pass the text of the button as a Command Parameter in Xamarin Forms:
CONTENT RESOURCE
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="PhoneKeys" TargetType="Button">
<Setter Property="BackgroundColor" Value="White"/>
<Setter Property="FontSize" Value="36"/>
<Setter Property="Command" Value="{Binding Source={x:Reference contactsListView}, Path=BindingContext.TapCommand1}"/>
<Setter Property="CommandParameter" Value="Pass Button Text"/>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
GRID LAYOUT
<Button Style="{StaticResource PhoneKeys}" Text="1" Grid.Row="1" Grid.Column="0" />
<Button Style="{StaticResource PhoneKeys}" Text="1" Grid.Row="1" Grid.Column="0" />
<Button Style="{StaticResource PhoneKeys}" Text="2" Grid.Row="1" Grid.Column="1" />
<Button Style="{StaticResource PhoneKeys}" Text="3" Grid.Row="1" Grid.Column="2" />
<Button Style="{StaticResource PhoneKeys}" Text="4" Grid.Row="2" Grid.Column="0" />
<Button Style="{StaticResource PhoneKeys}" Text="5" Grid.Row="2" Grid.Column="1" />
<Button Style="{StaticResource PhoneKeys}" Text="6" Grid.Row="2" Grid.Column="2" />
<Button Style="{StaticResource PhoneKeys}" Text="7" Grid.Row="3" Grid.Column="0" />
<Button Style="{StaticResource PhoneKeys}" Text="8" Grid.Row="3" Grid.Column="1" />
<Button Style="{StaticResource PhoneKeys}" Text="9" Grid.Row="3" Grid.Column="2" />
<Button Style="{StaticResource PhoneKeys}" Text="*" Grid.Row="4" Grid.Column="0" />
<Button Style="{StaticResource PhoneKeys}" Text="0" Grid.Row="4" Grid.Column="1" />
<Button Style="{StaticResource PhoneKeys}" Text="#" Grid.Row="4" Grid.Column="2" />
Use this syntax to get property of control "{x:Reference myButton}"
You can send self button reference to get complete button object
Style
<Setter Property="CommandParameter" Value="{x:Reference myButton}" />
XAML
<Button x:Name="myButton" Style="{StaticResource PhoneKeys}" Text="#" Grid.Row="4" Grid.Column="2" />
Define button name of each button and get the object reference of that button.
public ICommand TapCommand1 => new Command((obj) =>
{
var button = obj as Button;
var text = button.Text;
});
OR Best way to define command parameter in each button with every button name
<Button x:Name="myButton" Style="{StaticResource PhoneKeys}" CommandParameter="{x:Reference myButton}" Text="#" Grid.Row="4" Grid.Column="2" />

How can I allocate more space to a numeric

Here is the XAML code that I created:
<ViewCell>
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Label HorizontalOptions="StartAndExpand" Text="ABC" />
<Entry Keyboard="Numeric" VerticalOptions="Center" HorizontalOptions="End" />
</Grid>
</ViewCell>
When I run the code the data entry area for the window is only wide enough to show one digit. Is there a way I can expand this so it will allow me to enter three digits?
Set a WidthRequest value, and also try changing the HorizontalOptions
<Entry Keyboard="Numeric" VerticalOptions="Center" WidthRequest="100" HorizontalOptions="FillAndExpand" />

Behaviours and Triggers

I have a simple login form with two fields username and pass. Using behaviours I implemented email validation (not empty, valid email) and pass validation (not empty)
<StackLayout Padding="30" VerticalOptions="CenterAndExpand" Spacing="15">
<Entry Text="{Binding Email}" Keyboard="Email" IsEnabled="{Binding IsNotBusy}" Placeholder="Email address">
<Entry.Behaviors>
<local:EntryValidatorBehavior IsCheckEmail="true" ValidateFromStart="false" IsCheckEmpty="true" x:Name="emailValidator" />
</Entry.Behaviors>
</Entry>
<Label Text="{Binding Source={x:Reference emailValidator}, Path=Message}" />
<Entry Text="{Binding Password}" IsPassword="true" IsEnabled="{Binding IsNotBusy}" Placeholder="Password">
<Entry.Behaviors>
<local:EntryValidatorBehavior ValidateFromStart="false" IsCheckEmpty="true" x:Name="passwordValidator">
</local:EntryValidatorBehavior>
</Entry.Behaviors>
</Entry>
<Label Text="{Binding Source={x:Reference passwordValidator}, Path=Message}" />
<StackLayout Orientation="Horizontal">
<Button Text="Forgot Password?" Command="{Binding ForgotButton}" TextColor="White" HeightRequest="40" VerticalOptions="End">
</Button>
<Button HorizontalOptions="EndAndExpand" Text="Sign In" Command="{Binding LoginButton}" TextColor="White" BackgroundColor="#f50057" HeightRequest="40" WidthRequest="100">
</Button>
</StackLayout>
</StackLayout>
This works perfectly, but at the bottom of the form I have a Login button which should be hidden as long as both email and password are not valid.
How can this be implemented? I was thinking by using Triggers
<Button HorizontalOptions="EndAndExpand" Text="Sign In" Command="{Binding LoginButton}" TextColor="White" BackgroundColor="#f50057" HeightRequest="40" WidthRequest="100" IsVisible="false">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<MultiTrigger TargetType="Button">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference emailValidator}, Path=IsValid}" Value="True" />
<BindingCondition Binding="{Binding Source={x:Reference passwordValidator}, Path=Text.IsValid}" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="IsVisible" Value="True" />
</MultiTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
but this doesn't work.
Thanks in advance!

Resources