MAUI - Entry - Automaticly Jump to net Entry Field on maxlenght - user-interface

I have 2 maui entry controls that have a maxLenght.
When filling in the first entry control , I would like it to automaticly jump to the next control whenever all values are filled in.
Can not seem to find any info on that.
Any suggestions ?
Thanks,

Xaml:
<Entry
x:Name="Entry1"
MaxLength="5"
TextChanged="Entry1_TextChanged"
/>
<Entry
x:Name="Entry2"
MaxLength="5"
/>
Code behind:
private void Entry1_TextChanged(object sender, TextChangedEventArgs e)
{
if (e.NewTextValue.Length == Entry1.MaxLength)
{
Entry2.Focus();
}
}
Explanation:
You define an event triggered by a change of Text in the first Entry. When the text reach the maximum length you set, the second Entry is focused.

Related

How to disable Syncfusion's Autocomplete from moving to the next entry when completed?

I'm using Syncfusion's Autocomplete entry in Xamarin.Forms in a way not related to a form. Thus, I don't want it to step to the next Entry object in the UI. However, doesn't matter what I try doing, when finishing putting in the input, it jumps to the next Entry.
I have tried setting both Entrys IsTabStop to False, as well as setting the second one's TabIndex to be smaller the other one's. Nothing worked, the only think which I have found to work is disabling the second Entry while the other one is focused.
XAML:
<ScrollView ...>
// ....
<StackLayout>
// ....
<autocomp:SfAutoComplete x:Name="TagsAutoComplete"
WidthRequest="100"
NoResultsFoundText="New Tag..."
DisplayMemberPath="Name"
Keyboard="Chat"
IsTabStop="False"
IsVisible="False"
Completed="AddTagAutoComplete_Completed" />
// ....
</StackLayout>
// ....
<Frame>
<Grid>
// ....
<Entry FontSize="18" TextColor="Black"
WidthRequest="150" VerticalOptions="Center"
Unfocused="EquValueEntry_Unfocused"
TabIndex="-1" IsTabStop="False" />
// ....
</Grid>
</Frame>
// ....
</ScrollView>
My workaround uses the Focused and Unfocused methods of the Autocomplete, which simply set the IsEnabled property of the second Entry to False and True respectively. Does anyone have a better, more elegant solution?
We would like to let know that you can stop the next Entry focus by Return type and IME option.
UWP:
Setting IsTabStop as false it disables the next Entry focus.
Android:
By changing the input method options of EditText in autocomplete (using ImeOptions property)
protected override void OnElementChanged(ElementChangedEventArgs<SfAutoComplete> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.GetAutoEditText().ImeOptions = Android.Views.InputMethods.ImeAction.Done;
Control.GetAutoEditText().SetImeActionLabel("Send", Android.Views.InputMethods.ImeAction.Done);
}
iOS:
By changing the return type property of UITextField in autocomplete (using ReturnKeyType property)
protected override void OnElementChanged(ElementChangedEventArgs<SfAutoComplete> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.TextField.ReturnKeyType = UIReturnKeyType.Done;
}
}
We have prepared a sample for your reference get it from below link.
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/AutoComplete_EntryNotFocus1409818301
For more information refer the link:
https://www.syncfusion.com/kb/10690/how-to-change-return-button-type-in-sfautocomplete

Xamarin Comma to Dot replace ( listview in mvvm ) [duplicate]

I have to create a form in which the user must input his age. I would like to use a numeric keyboard:
<Entry
x:Name="AgeEntry"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Keyboard="Numeric"
/>
but it shows even the decimal point character, I'd like to show only numbers...
To restrict the Entry to only accept numbers you could use a Behavior or a Trigger.
Both of those will react to a user typing into them. So for your use, you could have the trigger or behavior look for any characters that are not numbers and remove them.
Something like this for a behavior (note that I wrote all this on SO and did not try compiling it, let me know if it does not work):
using System.Linq;
using Xamarin.Forms;
namespace MyApp {
public class NumericValidationBehavior : Behavior<Entry> {
protected override void OnAttachedTo(Entry entry) {
entry.TextChanged += OnEntryTextChanged;
base.OnAttachedTo(entry);
}
protected override void OnDetachingFrom(Entry entry) {
entry.TextChanged -= OnEntryTextChanged;
base.OnDetachingFrom(entry);
}
private static void OnEntryTextChanged(object sender, TextChangedEventArgs args)
{
if(!string.IsNullOrWhiteSpace(args.NewTextValue))
{
bool isValid = args.NewTextValue.ToCharArray().All(x=>char.IsDigit(x)); //Make sure all characters are numbers
((Entry)sender).Text = isValid ? args.NewTextValue : args.NewTextValue.Remove(args.NewTextValue.Length - 1);
}
}
}
}
Then in your XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyApp;assembly=MyApp"> <!-- Add the local namespace so it can be used below, change MyApp to your actual namespace -->
<Entry x:Name="AgeEntry"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Keyboard="Numeric">
<Entry.Behaviors>
<local:NumericValidationBehavior />
</Entry.Behaviors>
</Entry>
</ContentPage>
To me the simple solution is just to add a TextChanged handle to the Entry (this is UI specific code so does not break MVVM)
<Entry Text="{Binding BoundValue}" Keyboard="Numeric" TextChanged="OnTextChanged"/>
Then in code behind
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
//lets the Entry be empty
if ( string.IsNullOrEmpty(e.NewTextValue) ) return;
if ( !double.TryParse(e.NewTextValue, out double value) )
{
((Entry) sender).Text = e.OldTextValue;
}
}
Change in int.Parse if need an integer
I was facing this too, but the best way to implement this is through behaviors, here is an article which shows you in detail how to implement this and even more, like limiting the value of the number entered to a given value you set in your XAML.
if (!string.IsNullOrWhiteSpace(args.NewTextValue))
{
bool isValid = args.NewTextValue.ToCharArray().All(char.IsDigit);
((Editor)sender).Text = isValid ? args.NewTextValue : args.OldTextValue;
}
This prevents adding any non digit char into the Editor no matter where you added it.
So if your cursor was in the middle of your number and you got for example 21h3 in #hvaughan3's answer you would just remove the last char giving you 21h with the non digit still being present.
My answer will just use the value you had before adding the non digit char (213).
But keep in mind!
If you put this in a behavior and react to editor.TextChanged Event, this is still gonna change the Text for a brief second to the invalid value since this event triggers when it ALREADY was set. this is no OnTextChanging event.
Same for #hvaughan3's answer.
To prevent any issues you might get because of this, for example because you're also listening to OnTextChanged in Code behind, just add this line before working with the new text value
if (!editor.Text.All(char.IsDigit)) return;

ItemInvoked vs SelectionChanged

In Windows UWP, what is the difference between the ItemInvoked and SelectionChanged events for a NavigationView? The API reference states
ItemInvoked
Occurs when an item in the menu receives an interaction such as a click or tap.
SelectionChanged
Occurs when the currently selected item changes.
It seems to me that SelectionChanged can detect when navigation occurs even by some method other than clicking a NavigationView.MenuItem, so would be the better, more encompassing option to use?
Or are there different use cases for each?
The main difference would be that the SelectionChanged event is executed only once, but if you click the selected item repeatedly, it is not fired. ItemInvoked on the other hand will execute each time an item is clicked even if it is selected already.
Also - SelectionChanged event will execute when you manually set SelectedItem in code.
Another thing that might be useful to note is that ItemInvoked fires before SelectionChanged when you click on a NavigationView item
I was recently struggling with this question and having a problem when using the SelectionChanged Event. Successive clicks on the same Menu Item yielded no result.
Then I found this blog post (https://blogs.msdn.microsoft.com/appconsult/2018/05/06/using-the-navigationview-in-your-uwp-applications/) which suggested using the ItemInvoked Event for the same reason given in answer #1.
This did not work for me as posted in the Blog but after changing the code to use the InvokedItemContainer Tag property the solution worked just fine.
I have included the test code I used to verify the solution.
private void NvTopLevelNav_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
if (args.IsSettingsInvoked)
{
contentFrame.Navigate(typeof(SettingsPage));
}
else
{
string navTo = args.InvokedItemContainer.Tag.ToString();
if ( navTo != null)
{
switch (navTo)
{
case "Nav_Home":
contentFrame.Navigate(typeof(HomePage));
break;
case "Nav_Shop":
contentFrame.Navigate(typeof(ShopPage));
break;
case "Nav_ShopCart":
contentFrame.Navigate(typeof(CartPage));
break;
case "Nav_Message":
contentFrame.Navigate(typeof(MessagePage));
break;
case "Nav_Print":
contentFrame.Navigate(typeof(PrintPage));
break;
}
}
}
}
<Grid>
<NavigationView x:Name="nvTopLevelNav"
Loaded="NvTopLevelNav_Loaded"
Margin="0,12,0,0"
SelectionChanged="NvTopLevelNav_SelectionChanged"
ItemInvoked="NvTopLevelNav_ItemInvoked"
IsTabStop="False"
Header="Lets Go Shopping">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Home" Content="Home" Tag="Nav_Home" />
<NavigationViewItem Icon="Shop" Content="Shop" Tag="Nav_Shop" />
<NavigationViewItem Content="Shopping Cart" Tag="Nav_Cart">
<NavigationViewItem.Icon>
<FontIcon Glyph="[Insert Hex Decimal Value Here. See Segoe MDL2 below for details.]"/>
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Icon="Message" Content="Message" Tag="Nav_Message" />
<NavigationViewItem Icon="Print" Content="Print" Tag="Nav_Print" />
</NavigationView.MenuItems>
<Frame x:Name="contentFrame"></Frame>
</NavigationView>
</Grid>

Why the Completed event occur on Focus()?

I have some problem with Xamarin forms on Completed event which has been triggered when the control have focus (Entry)
Below is the View :
<Entry
x:Name="EntryOrderNumber"
Placeholder="MFGO Number"
Text="{Binding TextOrderEntry}" />
<Entry
x:Name="EntryMachineNumber"
Placeholder="Machine Number"
Text="{Binding TextMachineEntry}" />
And this is where I control the even which is placed at view.cs
public ProductionOrderPage()
{
InitializeComponent();
BindingContext = App.Locator.ProductionOrderPageVM;
EntryOrderNumber.Completed += EntryOrderNumber_Completed;
EntryMachineNumber.Completed += EntryMachineNumber_Completed;
EntryTotalPosition.Completed += EntryTotalPosition_Completed;
}
private void EntryMachineNumber_Completed(object sender, EventArgs e)
{
EntryMachineNumber.Unfocus();
EntryTotalPosition.Focus();
}
private void EntryOrderNumber_Completed(object sender, EventArgs e)
{
EntryOrderNumber.Unfocus();
EntryMachineNumber.Focus();
}
My problem is : While the Entry (Text field) has focused , the Completed event has been triggered which resulting in the focus will go to another field continuously as per set in the Completed event.
the apps being debugged and deployed onto emulator
using MVVMlight
Thanks a lot
using soft keyboard instead of hardware keyboard solve this problems. Weird.
Enabling soft keyboard : Visual Studio Android Emulator Display Keyboard

How to respond to clicks in TableView?

This sounds quite simple, but I haven't found anything like that in the web. How to add click listeners to data rows in TableView?
You could add a TapGestureRecognizer to the root element within your custom ViewCell. That way you can bind the gesture recognizer to a Command with command parameters.
<Grid.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" Command="{Binding CustomCommand}" CommandParameter="{Binding Thing}" />
</Grid.GestureRecognizers>
Okay, what I've found so far, is that while you cannot add any type of input listeners to the TabeView itself, you can add Tapped event listener to the ViewCells inside it. This seems to be working:
var cell = new CustomCell();
cell.Tapped += OnCellTapped;
tableView.Root.LastOrDefault().Add(cell);
....
private void OnWalletTapped(object sender, EventArgs e)
{
Debug.WriteLine(sender.GetHashCode());
}

Resources