I am on the most current version of Xamarin Forms. I have a Content Page. The Content Page has a grid that has a StackLayout and ScrollView. StackLayout Visible is false at the start point. When I click my Login Button, which has a Login method (see below) I set the StackLayout visible true. I use System.Timers too which start when login button clicked. If this timer reach 10 sec and the login isn't succesful the timer elapsed method activate. This method you can see below. At this point this work great, but I want to Login again and the StackLayout content doesn't show up. Can Anybody help me?
LoginPage.xml 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="Spirocco.LoginPage"
xmlns:renderer="clr-namespace:Spirocco.Droid.Renderers">
<Grid>
<StackLayout x:Name="stackView" IsVisible="False" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="300" HeightRequest="50" BackgroundColor="LightGray" Orientation="Horizontal">
<ActivityIndicator IsRunning="True" Color="Black" HorizontalOptions="Center" Margin="20" HeightRequest="30" WidthRequest="30"/>
<Label Text="Bejelentkezés..." TextColor="Black" VerticalOptions="Center" FontSize="16"/>
</StackLayout>
<ScrollView Orientation="Both" x:Name="scrollView">
<ScrollView.Content>
<StackLayout BackgroundColor="#302138">
<Image Source="login_logo" Margin="0,0,0,0"></Image>
<StackLayout BackgroundColor="White" Margin="20,0,20,30">
<Label Text="ÜDVÖZÖLJÜK!" FontSize="30" FontFamily="Comic Sans MS" Margin="0,15,0,0" TextColor="#302138" HorizontalTextAlignment="Center"></Label>
<renderer:BaseEntry x:Name="entryEmail" Text="{Binding Email}" Placeholder="E-mail" Margin="40,0,40,0" Keyboard="Email" ReturnType="Next"/>
<renderer:BaseEntry x:Name="entryPassword" Text="{Binding Password}" Placeholder="Jelszó" IsPassword="True" Margin="40,0,40,0" ReturnType="Send"/>
<Button Text="BEJELENTKEZÉS" Clicked="Login" TextColor="White" BackgroundColor="#302138" Margin="40,10,40,0"/>
<Button Text="REGISZTRÁCIÓ" Clicked="Register" TextColor="White" BackgroundColor="#302138" Margin="40,0,40,25"/>
</StackLayout>
<Label BackgroundColor="#302138" HeightRequest="160"/>
</StackLayout>
</ScrollView.Content>
</ScrollView>
</Grid>
My login method:
private async void Login(object sender, EventArgs e)
{
if (entryEmail.Text != null && entryPassword.Text != null)
{
try
{
stackView.IsVisible = true;
scrollView.Opacity = 0.5;
timer = new Timer(10000);
timer.Start();
timer.Elapsed += SetContentViewVisible;
}
catch (Exception)
{
stackView.IsVisible = false;
scrollView.Opacity = 1;
await DisplayAlert("Hiba történt", "Sikertelen bejelentkezés", "Vissza");
}
}
else
{
await DisplayAlert("Bejelentkezés", "Sikertelen bejelentkezés, kérem a sikeres bejelentkezéshez töltse ki az e-mail cím és jelszó mezőt!", "Vissza");
}
}
SetContentViewVisible method:
private void SetContentViewVisible(object sender, ElapsedEventArgs e)
{
timer.Dispose();
scrollView.Opacity = 1;
stackView.IsVisible = false;
timer.Stop();
}
I want to refresh UI from different thread. This was problem.
private void SetContentViewVisible(object sender, ElapsedEventArgs e)
{
Device.BeginInvokeOnMainThread(
() =>
{
timer.Dispose();
scrollView.Opacity = 1;
stackView.IsVisible = false;
timer.Stop();
DisplayAlert(SaySomething);
});
}
Related
The swipeview doesnt work when I open the app and press accept button but it works after when I open and close the detail page.
xaml shows list of events from sql and show swipeitem
<CollectionView x:Name="eventview"
BackgroundColor="Transparent"
ItemSizingStrategy="MeasureAllItems"
SelectionMode="Single"
SelectionChanged="eventview_SelectionChanged"
EmptyView="No Pending events">
<SwipeView.RightItems>
<SwipeItems SwipeBehaviorOnInvoked="Close">
<SwipeItem Text="Decline" BackgroundColor="red"/>
<SwipeItem Text="Accept" BackgroundColor="Green" Invoked="SwipeItem_Invoked"/>
</SwipeItems>
</SwipeView.RightItems>
<Grid Padding="10">
<StackLayout>
<Label Text="{Binding Name}" VerticalOptions="Center" FontSize="Small"/>
<Label Text="{Binding Date}" VerticalOptions="Center" FontSize="Small"/>
<Label Text="{Binding stats}" VerticalOptions="Center" FontSize="Small"/>
</StackLayout>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
cs shows click on the item that will open detail page and when click on the swipeitem
private async void eventview_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
lastSelection = e.CurrentSelection[0] as Event;
var eventss = e.CurrentSelection.FirstOrDefault() as Event;
var eventpage = new Eventdetailpage();
eventpage.BindingContext = eventss;
await Navigation.PushAsync(eventpage);
}
private async void SwipeItem_Invoked(object sender, EventArgs e)
{
if (lastSelection != null)
{
lastSelection.stats = "Accepted";
await App.Database.UpdateventAysnc(lastSelection);
eventview.ItemsSource = await App.Database.querypendingevent();
accpetedevents.ItemsSource = await App.Database.queryacceptevent();
}
}
if lastSelection is null, then your if won't execute and nothing will happen
you should be able to get the current item from the sender's BindingContext
var item = (SwipeItem)sender;
lastSelection = (Event)item.BindingContext;
I am having some issues having my back button properly pop my modal after a user acknowledged that they will lose their changes if they do so. I suppose the issue lies in how to properly await the async method within a method that cannot be async due to how it is coded.
In my code behind I have the following method:
protected override bool OnBackButtonPressed()
{
base.OnBackButtonPressed();
Task<bool> confirm = DisplayAlert("Are you sure?", "All unsaved changes will be lost", "I'm Sure", "Cancel");
confirm.ContinueWith(x =>
{
if(x.Result)
{
var task = Navigation.PopModalAsync();
task.Wait();
}
});
return true;
}
I can see that it does properly hit my breakpoint inside if the user has clicked "I'm Sure". However, after doing that the modal still remains on the page.
I call my modal using the following method (it is wrapped in a NavigationPage as I wanted to be able to leverage Toolbar items, if this is an anti pattern please let me know)
private async void EditSwipeItem_Invoked(object sender, EventArgs e)
{
var unitOfWork = container.Resolve<IUnitOfWork>();
var invoked = sender as SwipeItem;
var element = invoked.BindingContext as InventoryModel;
await Navigation.PushModalAsync(new NavigationPage(new AddEditInventoryList(true, "8dc9e483-1d63-4629-b386-680ad7c9a324", element.InventoryId, unitOfWork)));
}
The code for the backbutton is based off of what I wrote for the CancelToolBar_Clicked, and it works correctly (That is, the modal is popped after the user acknowledges the prompt).
private async void CancelToolBar_Clicked(object sender, EventArgs e)
{
bool confirm = await DisplayAlert("Are you sure?", "All unsaved changes will be lost", "I'm Sure", "Cancel");
if(confirm)
await Navigation.PopModalAsync();
}
Edit:
This is what my XAML looks like:
<?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="Invenutory.Views.Inventory.AddEditInventoryList">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Save"
Order="Primary"
Clicked="SaveToolBarItem_Clicked"
Priority="1"/>
<ToolbarItem Text="Cancel"
Order="Secondary"
Clicked="CancelToolBar_Clicked"
Priority="0"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Padding="20">
<Frame HorizontalOptions="FillAndExpand"
VerticalOptions="Start"
Padding="20"
CornerRadius="8"
BorderColor="AliceBlue">
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"
Orientation="Vertical">
<Label Text="Name: " HorizontalOptions="Start" VerticalOptions="Start" />
<Entry HorizontalOptions="FillAndExpand" VerticalOptions="Start" Text="{Binding Name, Mode=TwoWay}" IsSpellCheckEnabled="True" IsTextPredictionEnabled="True" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"
Orientation="Vertical">
<Label Text="Description: " HorizontalOptions="StartAndExpand" VerticalOptions="Start"/>
<Editor HorizontalOptions="FillAndExpand" VerticalOptions="Start" Text="{Binding Description, Mode=TwoWay}" IsSpellCheckEnabled="True" IsTextPredictionEnabled="True" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"
Orientation="Vertical">
<Label Text="Count: " HorizontalOptions="Start" VerticalOptions="Start"/>
<Entry Keyboard="Numeric" HorizontalOptions="FillAndExpand" VerticalOptions="Start" Text="{Binding Count, Mode=TwoWay}" />
</StackLayout>
</StackLayout>
</Frame>
<Frame HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="20" CornerRadius="8" BorderColor="AliceBlue">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Image HorizontalOptions="FillAndExpand" VerticalOptions="Start" HeightRequest="150" Aspect="AspectFit" BackgroundColor="Gray" Source="{Binding CapturedPhoto}" />
<Button Text="Take Photo" HorizontalOptions="FillAndExpand" VerticalOptions="Start" Command="{Binding TakePhotoCommand, Mode=TwoWay}"/>
</StackLayout>
</Frame>
</StackLayout>
</ContentPage.Content>
</ContentPage>
I was able to solve this by updating my inner .ContinueWith to look as follows:
confirm.ContinueWith(x =>
{
if(x.Result)
{
MainThread.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopModalAsync();
});
}
});
I have a screen that captures digital signature which, when saving or returning, executes a postasync or postmodalasync when the screen returns to me does not reload. How can I make the page reload or refresh?
<Grid BackgroundColor="WhiteSmoke" Padding="0" RowSpacing="0" VerticalOptions="StartAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentView Margin="10,0,10,5" Padding="0" BackgroundColor="LightGray" HeightRequest="500">
<StackLayout Padding="5,0,5,5" BackgroundColor="White" Spacing="1">
<Label
Text="Firma Policia Que Realizo Visita"
HorizontalOptions="Center"
TextColor="Black"
FontSize="Large"
FontAttributes="Bold"
/>
<Frame HasShadow="true"
Padding="8"
VerticalOptions="CenterAndExpand">
<signature:SignaturePadView
x:Name="SignatureView"
BindingContext="{Binding SignatureView}"
WidthRequest="280"
HeightRequest="300"
CaptionText=""
CaptionTextColor="Blue"
ClearText=""
PromptText=""
PromptTextColor="Green"
BackgroundColor="WhiteSmoke"
SignatureLineColor="Black"
StrokeWidth="3"
StrokeColor="Black" />
</Frame>
</StackLayout>
</ContentView>
</Grid>
<StackLayout Orientation="Horizontal" Padding="2" Spacing="2">
<Button
HorizontalOptions="FillAndExpand"
HeightRequest="40"
Text="Guardar"
TextColor="{x:StaticResource WhiteColor}"
FontSize="Small"
VerticalOptions="Center"
BackgroundColor="{x:StaticResource GreenButton}"
Clicked="Button_Clicked">
</Button>
<Button
HorizontalOptions="FillAndExpand"
HeightRequest="40"
Text="Limpiar"
TextColor="{x:StaticResource WhiteColor}"
FontSize="Small"
VerticalOptions="Center"
BackgroundColor="{x:StaticResource SicoqYellowColor}"
Clicked="Button_Clicked_1">
</Button>
</StackLayout>
This is the viewmodel which makes the backbuttoncommand service
public Task RemoveLastModalFromBack(object parameter,bool animated = false)
{
var mainPage = Application.Current.MainPage as NavigationView;
if (mainPage != null)
{
mainPage.Navigation.PopAsync(animated);
}
return Task.FromResult(true);
}
This is the ViewModel which receives the signature data
private async Task BackButton()
{
try
{
IsBusy = true;
await NavigationService.RemoveLastModalFromBack(str3);
o
}
catch (Exception e)
{
IsBusy = false;
// await DialogService.DisplayAlertAsync("Error", e.Message, "Aceptar");
}
finally
{
IsBusy = false;
}
}
The digital signature master page is digital signatures when you save or return the digital signatures page to reload
Do you want to achieve the result like following GIF?
If so, you can use MessagingCenter to achieve that.
We can use send method of MessagingCenter, Here is my code in the Button click event of SignaturesPage,Use the MessagingCenter to send the data to the MainPage.
private async void Button_Clicked(object sender, EventArgs e)
{
//get stream of Signatures from the pad
Stream image = await SignaturePad.GetImageStreamAsync(SignatureImageFormat.Png);
MessagingCenter.Send<Stream>(image, "Image");
await Navigation.PopAsync();
}
In the MainPage, I layout have Image to wait the stream from the SignaturesPage.
<StackLayout>
<!-- Place new controls here -->
<Frame BorderColor="Orange"
CornerRadius="10"
HasShadow="True">
<Button AutomationId="Mybutton" Text="Save" x:Name="Mybutton" HorizontalOptions="CenterAndExpand" Clicked="Mybutton_Clicked"/>
</Frame>
<Frame BorderColor="Orange"
CornerRadius="10"
HasShadow="True">
<Image x:Name="MyImage" HeightRequest="500" WidthRequest="400"/>
</Frame>
</StackLayout>
Here is my background code in the MainPage.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
MessagingCenter.Subscribe<Stream>(this, "Image", (arg) =>
{
MyImage.Source = ImageSource.FromStream(() => arg);
});
}
protected override void OnAppearing()
{
base.OnAppearing();
}
private void Mybutton_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new SignaturesPage());
}
}
Is there a way to use absolute layout as a customize pop-up? I am trying to create a customize popup. Is this possible?
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Yellow">
//Elements here
</StackLayout>
<AbsoluteLayout StyleClass="dialogbox" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
//Popup here
</AbsoluteLayout>
You can achieve that with AbsoluteLayout and add a fade animation. Here is running GIF.
There is code.
<StackLayout>
<Button
x:Name="btn"
Text="click"
/>
<ContentView x:Name="popupLoginView" BackgroundColor="#C0808080" Padding="10, 0" IsVisible="false" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All">
<AbsoluteLayout VerticalOptions="Center" HorizontalOptions="Center">
<StackLayout Orientation="Vertical" HeightRequest="200" WidthRequest="300" BackgroundColor="White">
<Entry Margin="20,20,20,10" Placeholder="Enter Username"></Entry>
<Entry Margin="20,0,20,0" Placeholder="Enter Password"></Entry>
<Button Margin="20,0,20,0" Text="Login"></Button>
</StackLayout>
</AbsoluteLayout>
</ContentView>
</StackLayout>
In xamarin forms, you can add fade animation to view. There is animation code.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
btn.Clicked += Btn_Clicked;
}
private async void Btn_Clicked(object sender, EventArgs e)
{
if (popupLoginView.IsVisible==true)
{
btn.IsEnabled = false;
await popupLoginView.FadeTo(0,2000);
await Task.Delay(2000);
popupLoginView.Opacity = 0;
popupLoginView.IsVisible = false;
btn.IsEnabled = true;
return;
}
if (popupLoginView.IsVisible == false)
{
if (popupLoginView.Opacity==1)
{
popupLoginView.Opacity = 0;
}
popupLoginView.IsVisible = true;
btn.IsEnabled = false;
await popupLoginView.FadeTo(1, 2000);
await Task.Delay(2000);
btn.IsEnabled = true;
popupLoginView.Opacity = 1;
return;
}
}
}
There is article about fade animation.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/animation/simple#fading
If you want to achieve it with Rg.Plugins.Popup and add the animation, you can refer to this article, it will add some animations.
https://www.c-sharpcorner.com/article/learn-about-xamarin-forms-animation-with-popuppage/
I am using xamarin.forms. having two projects Android and IOS.
I have one ContentView page with following code
<ContentView.Content>
<StackLayout x:Name="slMain" Padding="1" BackgroundColor="#7ABA45">
<StackLayout VerticalOptions="FillAndExpand" Padding="0,0,20,0" HeightRequest="50" HorizontalOptions="FillAndExpand">
<Label x:Name="lblTitle" VerticalOptions="CenterAndExpand" />
</StackLayout>
<StackLayout x:Name="sl" IsVisible="False" BackgroundColor="White">
</StackLayout>
</StackLayout>
</ContentView.Content>
// In Behind code(.cs file)
public ExpandCollapseStackLayout()
{
InitializeComponent();
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) =>
{
sl.IsVisible = !sl.IsVisible;
};
lblTitle.GestureRecognizers.Add(tapGestureRecognizer);
slMain.GestureRecognizers.Add(tapGestureRecognizer);
}
public string Title
{
get
{
return lblTitle.Text;
}
set
{
lblTitle.Text = value;
}
}
I want to add controls in StackLayout named "sl" of contentview in ContentPage at design time.
I dont want to add at runtime
Please suggest me how can I add Control in Contentview stacklayout?
If you want to add controls in design time simply declare them in your XAML, example:
<StackLayout x:Name="sl" IsVisible="False" BackgroundColor="White">
<!-- Add here your controls -->
<Label ... />
<Button .. />
</StackLayout>
If you want to add controls at runtime, you need to do it using your code behind page in C#. Example:
void AddControl()
{
var btn = new Button();
sl.Children.Add(btn);
}
Code for ContentView:
<ContentView.Content>
<StackLayout x:Name="slMain" Padding="1" BackgroundColor="#7ABA45" >
<StackLayout VerticalOptions="FillAndExpand" Padding="0,0,10,0" HeightRequest="50" HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label x:Name="lblTitle" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" Margin="10,0,0,0" TextColor="White" FontAttributes="Bold" />
<Label Text="{ x:Static local:GrialShapesFont.ArrowDown }" HorizontalOptions="End" VerticalOptions="CenterAndExpand" TextColor="White" Style="{ StaticResource FontIconBase }" FontSize="26" />
</StackLayout>
<Frame Padding="10" IsVisible="False" BackgroundColor="White" x:Name="ContentFrame" OutlineColor="Black" HasShadow="False">
</Frame>
</StackLayout>
</ContentView.Content>
CS Code for ContentView:
[ContentProperty("ContainerContent")]
public partial class ExpandCollapseStackLayout : ContentView
{
public ExpandCollapseStackLayout()
{
InitializeComponent();
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) =>
{
ContentFrame.IsVisible = !ContentFrame.IsVisible;
};
lblTitle.GestureRecognizers.Add(tapGestureRecognizer);
slMain.GestureRecognizers.Add(tapGestureRecognizer);
}
public View ContainerContent
{
get { return ContentFrame.Content; }
set { ContentFrame.Content = value; }
}
public string Title
{
get
{
return lblTitle.Text;
}
set
{
lblTitle.Text = value;
}
}
}
Add Control in ContentPage:
<control:ExpandCollapseStackLayout Title="Demo" Padding="0,10,0,0">
<control:ExpandCollapseStackLayout.ContainerContent >
<StackLayout>
<Label Text="Add Content Here"></Label>
</StackLayout>
</control:ExpandCollapseStackLayout.ContainerContent>
</control:ExpandCollapseStackLayout>