how can i set a focus for a Entry nested in a custom control?
PackageCode.xaml
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="this"
x:Class="Views.Controls.PackageCode">
<Entry x:Name="txtPackageCode" Completed="txtPackageCode_Completed"> </Entry>
I have tried with txtPackageCode.Focus();
public PackageCode()
{
InitializeComponent();
txtPackageCode.Focus();
}
Nested in my Main.xaml
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<local:PackageCode ></local:PackageCode>
<Button Text="ClickMe"
Clicked="Button_Clicked" ></Button>
</StackLayout>
</ContentPage.Content>
And How to extract the value of this Entry in my Main.xaml?
add a public method in PackageCode
public void Focus()
{
txtPackageCode.Focus();
}
then call it from Main
public override void OnAppearing()
{
// you will need to assign an x:Name in the XAML
packageCode.Focus();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await Task.Delay(1);
packageCode.SetFocus();
}
This worked.
Setting the Focus to an Entry in Xamarin.Forms
If you swipe several times on an already opening field, then after closing the swiped element will return to the position from which the last swipe was.
For example:
I upload project for replay problem: link
XAML Code:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestSwipeView.MainPage">
<CollectionView x:Name="collectionView"
ItemsSource="{Binding TestSequence}">
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="F"
BackgroundColor="LightGreen"/>
<SwipeItem Text="D"
BackgroundColor="LightPink"/>
</SwipeItems>
</SwipeView.LeftItems>
<Grid BackgroundColor="White"
Padding="10">
<Label Text="{Binding .}"></Label>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Xaml.cs code:
namespace TestSwipeView
{
public partial class MainPage : ContentPage
{
public List<String> TestSequence { get; set; }
public MainPage()
{
TestSequence = new List<string>();
for (int i=0; i<10; i++)
{
TestSequence.Add(String.Format("Test {0}",i));
}
InitializeComponent();
this.BindingContext = this;
}
}
}
I am trying to create a little application using MVVM. I would like to open a second page that scan a QR code and then back the value of the QR code to the main page.
I have this code:
Main view:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="QRScannerXamarinForms.Views.MainPageView"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
xmlns:vm="clr-namespace:QRScannerXamarinForms.ViewModels">
<ContentPage.BindingContext>
<vm:MainPageViewModel/>
</ContentPage.BindingContext>
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Barcode Sample" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
</Frame>
<Button x:Name="ucBtnEscanear" Text="Escanear"
Command="{Binding EscanearCommand}"/>
</StackLayout>
</ContentPage>
Main view model:
private INavigationService _navigationService;
public ICommand EscanearCommand { get; private set; }
private void Escanear()
{
string miCodigoQr = _navigationService.AbrirPaginaEscaner();
}
Second view:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="QRScannerXamarinForms.Views.ScannerView"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
xmlns:vm="clr-namespace:QRScannerXamarinForms.ViewModels">
<ContentPage.BindingContext>
<vm:ScannerViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Barcode Sample" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
</Frame>
<Label x:Name="ucScanResultText" />
<zxing:ZXingScannerView x:Name="ucZXingScannerView" IsScanning="True" IsAnalyzing="True" Result="{Binding CodigoQr}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Second view model:
class ScannerViewModel : BaseViewModel
{
private string _codigoQr;
public string CodigoQr
{
get { return _codigoQr; }
set { _codigoQr = value; }
}
}
Interface to open pages:
namespace QRScannerXamarinForms.Services
{
interface INavigationService
{
string AbrirPaginaEscaner();
}
}
Implementation of the interface that allows navigation.
namespace QRScannerXamarinForms.Services
{
class ViewNavigationService : INavigationService
{
public string AbrirPaginaEscaner()
{
ScannerView miScannerView = new ScannerView();
ScannerViewModel miScannerViewModel = miScannerView.BindingContext as ScannerViewModel;
Application.Current.MainPage.Navigation.PushModalAsync(miScannerView);
return miScannerViewModel.CodigoQr;
}
}
}
But in the implementation of the interface, the second page is not shown. So this line doesn't work:
Application.Current.MainPage.Navigation.PushModalAsync(miScannerView);
How could I open from this class?
Thanks.
I made a ContentView with an Expander. I want to duplicate this Xaml code multiple times in an other Xaml file. But I want for each Expander a different Binding.
I linked this code (ContentView code):
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:expandable="clr-namespace:Expandable;assembly=ExpandableView"
x:Class="Hello.ExpandableView">
<ContentView.Content>
<expandable:ExpandableView Padding="5">
<expandable:ExpandableView.PrimaryView>
<Frame BackgroundColor="White" Padding="5" CornerRadius="10">
<StackLayout Orientation="Horizontal">
<Label x:Name="label" FontSize="16" TextColor="Black" FontAttributes="Bold" Padding="5" HorizontalTextAlignment="Start" HorizontalOptions="StartAndExpand"/>
<Image Source="arrow.png" WidthRequest="25" HeightRequest="25" Margin="5"/>
</StackLayout>
</Frame>
</expandable:ExpandableView.PrimaryView>
<expandable:ExpandableView.SecondaryViewTemplate>
<DataTemplate>
<Frame BackgroundColor="White" Padding="5" CornerRadius="10">
<Label Text="{Binding Tip1Uitleg}" FontSize="15" TextColor="Black" Padding="5"/>
</Frame>
</DataTemplate>
</expandable:ExpandableView.SecondaryViewTemplate>
</expandable:ExpandableView>
</ContentView.Content>
</ContentView>
namespace Hello
{
public partial class ExpandableView : ContentView
{
public static BindableProperty LabelProperty =
BindableProperty.Create(nameof(Label),
typeof(string),
typeof(ExpandableView),
propertyChanged: (b, o, n) => (b as ExpandableView).OnLabelChanged());
private void OnLabelChanged()
{
label.Text = Label; //label is the x:Name of your Label control in ExpandableView.xaml
}
public string Label
{
get => (string)GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
}
}
}
To this code:
This works:
<local:ExpandableView Label="Hello"/>
But I want this. This does not work:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:expandable="clr-namespace:Expandable;assembly=ExpandableView"
xmlns:local="clr-namespace:Hello"
x:Class="Hello.Health.HealthDetail"
Title="{Binding Name}">
<ContentPage.Content>
<ScrollView>
<StackLayout>
<Image Source="{Binding Image}"/>
<Label Text="{Binding Tip1Uitleg}" FontSize="15" TextColor="Black" Padding="10, 5, 10, 5"/>
<local:ExpandableView Label="{Binding Tip1}"/> //This is what it is all about
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
CodeBehind:
namespace Hello.Health
{
public partial class HealthDetail : ContentPage
{
public HealthDetail(HealthStrings healthStrings)
{
if (healthStrings == null)
throw new ArgumentNullException();
BindingContext = healthStrings;
InitializeComponent();
}
}
}
How do I make this work? I have to make this above more dynamic, but I do not know how.
BTW This also works:
<Label Text="{Binding Tip1}" />
I am sorry for the unclear explanation, I hope someone can help me.
Thank you for your time :)
You should not bind to 'this' since you are using a BindableProperty. Instead you should update the Label.Text property when the value of the BindableProperty changes.
public static BindableProperty LabelProperty =
BindableProperty.Create(nameof(Label),
typeof(string),
typeof(ExpandableView),
propertyChanged:(b, o, n) => (b as ExpandableView).OnLabelChanged());
private void OnLabelChanged()
{
label.Text = Label; //label is the x:Name of your Label control in ExpandableView.xaml
}
public string Label
{
get => (string)GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
}
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourProject.ExpandableView">
<Grid>
<Label x:Name="label"/>
</Grid>
</ContentView>
Normally, when you want to binding a value for binableproperty, you could try the code below:
ExpandableView: I make a simple contentview with the same binableproperty for you reference.
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinDemo.Pages.ExpandableView">
<ContentView.Content>
<StackLayout>
<Label Text="Hello"></Label>
<Label x:Name="label"></Label>
</StackLayout>
</ContentView.Content>
</ContentView>
Code behind:
public partial class ExpandableView : ContentView
{
public static BindableProperty LabelProperty =
BindableProperty.Create(nameof(Label),
typeof(string),
typeof(ExpandableView),
propertyChanged: (b, o, n) => (b as
ExpandableView).OnLabelChanged());
private void OnLabelChanged()
{
label.Text = Label; //label is the x:Name of your Label control in ExpandableView.xaml
}
public string Label
{
get => (string)GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
}
public ExpandableView()
{
InitializeComponent();
}
}
Usage:
<ContentPage.Content>
<local:ExpandableView Label="{Binding str}"></local:ExpandableView>
</ContentPage.Content>
Code Behind:
public partial class Page1 : ContentPage
{
public string str { get; set; }
public Page1()
{
InitializeComponent();
str = "okay";
this.BindingContext = this;
}
}
On Login or Navigating to Dashboard Page, fetching data from API, I am using an extra button (Show Communities) to fetch my Fetch my Data. here is my code
<StackLayout BackgroundColor="#30af91" Padding="60" VerticalOptions="Center">
<Entry Text="{Binding Username}" Placeholder="Username"/>
<Entry Text="{Binding Password}" IsPassword="True" Placeholder="Password"/>
<Button Command="{Binding LoginCommand}" Text="Login" Clicked="Button_OnClicked"/>
</StackLayout>
Button_OnClicked only navigate to Dashboard page
private async void Button_OnClicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new Dashboard());
}
LoginCommand in LoginViewModel
public ICommand LoginCommand
{
get
{
return new Command(async() =>
{
var accesstoken = await _apiServices.LoginAsync(Username, Password);
Settings.AccessToken = accesstoken;
});
}
}
Here is my Dashboard Page
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:epolleasy.ViewModels;assembly=epolleasy"
x:Class="epolleasy.Views.Dashboard">
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<ContentPage.BindingContext>
<viewModels:DashboardViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Button x:Name="BtnActiveForm" Text="Active Forms" Clicked="BtnActiveForm_OnClicked"></Button>
<Button x:Name="BtnCommunity" Text="My Communities" Clicked="BtnCommunity_OnClicked"></Button>
<Button x:Name="BtnHistory" Text="Sealed Forms" Clicked="BtnHistory_OnClicked"></Button>
<Button Text="Logout" Command="{Binding LogoutCommand}" Clicked="Logout_OnClicked"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
</MasterDetailPage.Master>
</MasterDetailPage>
Here is my Communities page where i am using an extra button using GetDashboard Command
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:epolleasy.ViewModels;assembly=epolleasy"
x:Class="epolleasy.Views.DpCommunities">
<ContentPage.BindingContext>
<viewModels:DashboardViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add New"
Icon="add.png"
Priority="0"
Clicked="MenuItem_OnClicked"/>
</ContentPage.ToolbarItems>
<StackLayout>
<Button Command="{Binding GetDashboard}" Text="Show Communities"/>
<ListView ItemsSource="{Binding UserDashboard.Com}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding CommunityName}"/>
<Label Text="{Binding CommunityUsers.Count}"/>
<Label Text="{Binding FormsCommunity.Count}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Here is GetDashboard Command in my ViewModel
public ICommand GetDashboard
{
get
{
return new Command(async () =>
{
var accessToken = Settings.AccessToken;
UserDashboard = await _apiServices.GetDashboard(accessToken);
});
}
}
Here is my UserDashboard in the same view model.
public Dashboard UserDashboard
{
get { return _userDashboard; }
set
{
_userDashboard = value;
OnPropertyChanged();
}
}
I want to get rid of that extra button.
every page has an OnAppearing method that fires when the page is display. You can use this to load your data instead of having the user click a button.
public override async void OnAppearing() {
base.OnAppearing();
var accessToken = Settings.AccessToken;
UserDashboard = await _apiServices.GetDashboard(accessToken);
}