Reputation: 211
In my Xamarin Forms application I would like to perform a validation on an Entry
element when the user focus it out. Using Completed
event only works when the user taps "enter" on the keyboard. I tried to use Unfocused
but this event triggers while the user is typing on the Entry element and I really do not understand why.
How could I perform a piece of code only when an Entry element is unfocused?
I've 10 ViewCell
elements like this one:
<ViewCell >
<StackLayout Orientation="Horizontal" Padding="13, 5" >
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" Spacing="1">
<Label Text="Matricola" VerticalOptions="Center" HorizontalOptions="StartAndExpand" ></Label>
<Entry x:Name="matricola" Text="{Binding Paziente.MatricolaPaziente, Mode=TwoWay}" HorizontalOptions="FillAndExpand" Completed="Entry_Completed" Unfocused="Entry_Completed" ></Entry>
<Label Text="{Binding RegistrationValidator.MatricolaError, Mode=OneWay}" HorizontalOptions="FillAndExpand" TextColor="IndianRed"></Label>
</StackLayout>
</StackLayout>
</ViewCell>
Code behind:
private async void Entry_Completed(object sender, EventArgs e){
// Some code here
}
Moreover the event triggers with unexpected random senders (other Entry
elements, always with e.IsFocused == false
)
Upvotes: 2
Views: 4264
Reputation: 2995
The Entry
focus issue inside ListView
seems to occur (on second row of the ListView
and onwards) on Android (8.1 and 9.0) (Xamarin.Forms 4.5.0.356).
See also "Entry focus issue inside ListView".
As a workaround, use CollectionView
(without ViewCell
in ItemTemplate
).
Sample without Entry focus issue:
<CollectionView>
<CollectionView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>First</x:String>
<x:String>Second</x:String>
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Entry Text="collectionview" Focused="Entry_Unfocused" Unfocused="Entry_Unfocused" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Sample with Entry focus issue in ListView
on Android (8.1 and 9.0):
<ListView>
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>First</x:String>
<x:String>Second</x:String>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Entry Text="listview" Focused="Entry_Unfocused" Unfocused="Entry_Unfocused" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Codebehind for observing the focus events:
void Entry_Unfocused(object sender, FocusEventArgs e)
{
Debug.WriteLine($"Entry_Unfocused:{e.IsFocused}:");
}
void Entry_Focused(object sender, FocusEventArgs e)
{
Debug.WriteLine($"Entry_Focused:{e.IsFocused}:");
}
Upvotes: 3
Reputation: 10978
Unfocused event is raised whenever the Entry loses focus. I make a simple code to test and verify.
Xaml:
<ListView ItemsSource="{Binding list}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Entry Text="{Binding Name}" Unfocused="Entry_Unfocused" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Code:
public partial class EntryPage : ContentPage
{
public ObservableCollection<Person> list { get; set; }
public EntryPage()
{
InitializeComponent();
list = new ObservableCollection<Person>()
{
new Person (){ Name="A"},
new Person (){ Name="B"}
};
this.BindingContext = this;
}
private void Entry_Unfocused(object sender, FocusEventArgs e)
{
}
}
public class Person
{
public string Name { get; set; }
}
Upvotes: 0
Reputation: 437
I tried with a sample forms like this
<ContentPage.Content>
<StackLayout Spacing="20" Padding="15">
<Label Text="Text" FontSize="Medium" />
<Entry Text="{Binding Item.Text}" d:Text="Item name" FontSize="Small" Unfocused="Entry_Unfocused" Completed="Entry_Completed" />
<Label Text="Description" FontSize="Medium" />
<Editor Text="{Binding Item.Description}" d:Text="Item description" FontSize="Small" Margin="0" />
</StackLayout>
</ContentPage.Content>
And in the code behind:
private void Entry_Unfocused(object sender, FocusEventArgs e)
{
var txt = ((Entry)sender).Text;
DisplayAlert("Info", $"Value of text after entry lost focus : {txt} ", "OK");
}
private void Entry_Completed(object sender, EventArgs e)
{
var txt = ((Entry)sender).Text;
DisplayAlert("Info", $"Value when Enter Key is tapped : {txt} ", "OK");
}
Everything works fine! While looking into your code again, it seems your are in listview. Maybe the problem might come from there.
Upvotes: 1
Reputation: 63
I believe the Unfocused event gets triggered regardless of focus or unfocus, but the FocusEventArgs
on the event should have a bool called IsFocused
which should show whether or not the Entry is still focused. Have you tried checking that? It looks like you Unfocused Event Handler just uses a generic EventArgs when it could be using the more specific FocusEventArgs
Upvotes: 0