I am doing an authentication in xamarin forms, using b2c, they asked me to embed the pop-up screen that triggers and in turn hide or eliminate both the cancel and the navigation bar, has someone done that part or otherwise modify it? (thanks in advance)enter image description here
Please check if below references can be worked in your case:
Hide Cancel button :
In custom policy:
Configure the setting.showCancelButton metadata item to false in the custom policy technical profile of the sign in or sign up or page for it is requiredrequired.
Example:
<TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
<DisplayName>Email signup</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="IpAddressClaimReferenceId">IpAddress</Item>
<Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
<Item Key="language.button_continue">Create</Item>
<Item Key=" setting.showCancelButton ">false</Item>
</Metadata>
<InputClaims>….
….
</TechnicalProfile>
See self asserted technical profile reference & Microsoft Q&A Reference
Through Xamarin Form:
For Xamarin forms ,Use Xamarin.Forms renderer to hide the "Cancel" button of a SearchBar on iOS using Control.ShowsCancelButton = false;
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "Text")
{ Control.ShowsCancelButton = false;}
}
References:
Xamarin forms– iOS disable cancel button on SearchBar (weblogs.us)
How to handle/cancel back navigation in Xamarin Forms-Stack Overflow
Disable Navigation bar:
If you use webview in the NavigationPage or NavigationPage wrap the contentpage, Try to add NavigationPage.HasNavigationBar="False" into your contentPage tags like following xaml, to disable navigation bar.
Example:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FormsWebViewTest"
x:Class="FormsWebViewTest.MainPage"
NavigationPage.HasNavigationBar="False">
...........
.......//other part
</ContentPage>
Or
SetHasNavigationBar to false on your navigation page (in content page constructor).
ex:
public MyPage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
}
Related
I'm new to Xamarin/.NET MAUI application development. I started to develop a sample .NET MAUI application for Android device.
I'm trying to understand how/when a page and my custom view are destroyed (disposed of). I read some web pages but I can't really understand how things work in .NET MAUI (or Xamarin).
I have three pages: MainPage, SecondPage, TestMapPage.
SecondPage has a button that navigates to TestMapPage. It instantiates a TestMapPage object and passes it to Navigation.PushAsync().
TestMapPage contains a custom view TestMapView, which is rendered by my custom view renderer TestMapViewRenderer. I create a MapView object (from Naxam.Mapbox.Droid) in the renderer and show the map in TestMapPage. The map appears on the emulator and it works fine.
I thought that SecondPage, TestMapPage and TestMapView (and all the objects in TestMapViewRenderer) will be destroyed when I navigate back to MainPage. However, when I set a break point on Dispose() in the renderer and navigate back to SecondPage or MainPage in , it never gets hit.
My questions:
Are the SecondPage, TestMapPage, TestMapView and all the other objects in the view and view renderer like MapboxMap kept somewhere when I go back to MainPage?
When are pages and views destroyed/disposed of?
If those page objects are kept somewhere until the application shuts down, is it normal behaviour?
If not normal behaviour, how do I fix it?
I'm worried about memory leak...
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
// ...
private async void OnGoToSecondPageClicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new SecondPage());
}
}
SecondPage.xaml.cs
public partial class SecondPage : ContentPage
{
// ...
private async void OnMapShowClicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new TestMapPage());
}
}
TestMapPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MapTest"
x:Class="MapTest.TestMapPage">
<StackLayout Margin="5">
<local:TestMapView
x:Name="map"
VerticalOptions="FillAndExpand"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</ContentPage>
TestMapView.cs
public class TestMapView : View { }
TestMapViewRenderer.cs
public partial class TestMapViewRenderer : ViewRenderer<TestMapView, Android.Views.View>
{
private MapboxMap map;
public TestMapViewRenderer(Context context) : base(context) {}
protected override void OnElementChanged(ElementChangedEventArgs<TestMapView> e)
{
base.OnElementChanged(e);
// ...
if (Control == null)
{
var mapView = new MapView(Context);
SetNativeControl(mapView);
mapView.GetMapAsync(this);
}
}
public void OnMapReady(MapboxMap map)
{
this.map = map;
this.map.SetStyle(Resources.GetString(Resource.String.mapbox_style_satellite), this);
}
protected override void Dispose(bool disposing)
{
// A breakpoint never hits on this line. Why?
base.Dispose(disposing);
}
// ...
}
as far as I know;
No, on each navigation you create new page instances, so, the page is created and kept in memory by .NET itself, once garbage collection hits a certain threshold, the memory will be free. Until then, the pages are in memory, but not meant to use somewhen in the future.
When GC decides, the Xamarin/MAUI doesn't care about views.
Unfortunately, yes.
It's normal, you can overcome by using what #ToolmakerSteve refers.
I am using ContentView inside a ContentPage like this
<ContentView x:Name="MyContent"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<ContentView.GestureRecognizers>
<SwipeGestureRecognizer Swiped="SwipLeft" Direction="Left"/>
<SwipeGestureRecognizer Swiped="SwipRight" Direction="Right"/>
</ContentView.GestureRecognizers>
</ContentView>
in the code behind I set the relavent Content to the ContentView according to the SwipeDirection like below. and same as for SwipRight.
private void SwipLeft(object sender, SwipedEventArgs e)
{
if (e.Direction == SwipeDirection.Left)
{
//set the relavent page content here
}
}
I need to set an animation or transition to appear when I swipe between pages. I need this only for iOS. Can anyone help me for this or any method knows anyone to achieve this?
you can get the idea from this snapshot
click here for image
all the content and everything has done I just need to add transitions between pages.
You could use the TabbedPage . It seems that you want to let the tab display on the top of screen . In your case you could install the plugin TopTabbedPage from nuget .
Usage
<forms:TopTabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Naxam.Demo.TestPage"
xmlns:views="clr-namespace:Naxam.Demo"
xmlns:forms="clr-namespace:Naxam.Controls.Forms;assembly=Naxam.TopTabbedPage.Forms"
BarTextColor="#00b9e1"
BarIndicatorColor="#00b9e1"
BarBackgroundColor="#ffffff"
Title="MyRide">
<views:Page1 /> // here is the content page , you need to put each contentview in independent ContenPage
<views:Page2 />
</forms:TopTabbedPage>
And in iOS project -> AppDelegate.cs
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
TopTabbedRenderer.Init();
Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
For more details about the plugin you could refer the github project site .
I am writing an app with Xamarin.Android and MvvmCross. I am using fragments and have a "content container" design where I show the fragments in my content_frame view:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
</FrameLayout>
Everything works, and I can navigate through my app by showing/closing the fragments in my content_frame, but when I close the last fragment, instead of closing the app, it shows a blank screen instead. I reckon I can fix this in my MvxAppCompatViewPresenter class but I don't know how? I currently don't have anything in my view presenter:
public class ViewPresenter : MvxAppCompatViewPresenter
{
public ViewPresenter(IEnumerable<Assembly> androidViewAssemblies) : base(androidViewAssemblies)
{
}
public override void Show(MvxViewModelRequest request)
{
base.Show(request);
}
public override void Close(IMvxViewModel viewModel)
{
base.Close(viewModel);
}
}
Here is the first fragment:
[MvxFragmentPresentation(typeof(LoginViewModel), Resource.Id.content_frame, true)]
[Register("myapp.droid.fragments.LoginSelectionFragment")]
public class LoginSelectionFragment : BaseFragment<LoginSelectionViewModel>
{
protected override int FragmentId => Resource.Layout.fragment_login_selection;
}
One of the approaches you can use, is to not add the fragments that are starting fragments to the backstack by setting the MvxFragmentPresentation property AddToBackStack to false (false is also the default if no parameter is passed).
The idea there is that for the first fragment you would rely on the activity being added to the backstack. Essentially, the first fragment and the activity could then be considered the same with respect to the backstack, eliminating the blank screen.
However, this would only work if the starting fragments do not need to be added to the backstack, with in the same activity context, later in the navigational flow. In future versions of MvvmCross you would easily be able to overcome this limitation via the updated IMvxOverridePresentationAttribute.
Everything works fine until i add Xamarin.Forms.Maps xaml tag to the view. My Application views work flow is as follows MainPage.Xaml --> LocationView.Xaml. MainPage has a button , i use delegate command to navigate to LocationView with the help of navigationservice.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="TruckGPS.Views.LocationViewPage" xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
<StackLayout VerticalOptions="StartAndExpand" Padding="30">
<maps:Map WidthRequest="320" HeightRequest="200"
x:Name="MyMap"
IsShowingUser="true"
MapType="Hybrid"/>
LocationViewPage has corresponding LocationViewPageViewModel.
When i click the button on MainPage ViewModel i invoke the Delegate command which works fine without the maps. It stops at the breakpoint on delegate method when clicked but never navigates.
MainPage ViewModel Code:
public MainPageViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
ShowMapCommand = new DelegateCommand(ShowMap);
}
private void ShowMap()
{
_navigationService.NavigateAsync("LocationViewPage");
}
I have a list of the following class:
public class Set {
public string IconUrl { get; set; }
}
This list is bound to a ListView:
<ListView ItemsSource="{Binding Sets}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Image Source="{Binding IconUrl}" />
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When the view loads and the user starts scrolling, the cells are reused and the Image briefly shows the previous image before the new image is downloaded and rendered.
Is there a way to prevent this kind of behavior without disabling RecycleElement?
I haven't tried this but on ViewCell you have Disappearing and Appearing events that you can hook into.
You may want to look at releasing the image source on the Disappearing event handler, but sometimes this can occur sometime later I think from recollection, so you may also want to try releasing the image on the Appearing event handler that hopefully will be executed prior to the display on the screen?
We have solved this by manually setting the Image source to null to force the render of the new images. we achieve this by using OnBindingContextChanged Event of the ListView. Hope this helps.
Edited (Added code below):
We have something like this:
public class PeopleCell : ViewCell
{...
Image profileImage;
public PeopleCell()
{
profileImage = new Image
{
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
BackgroundColor = Color.FromHex("f5f5f5"),
Source = ImageSource.FromFile("profile_blankimage"),
};...
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
people = BindingContext as CustomerViewModel;
if(people.Customer.Avatar != null)
profileImage.Source = ImageSource.FromUri(new Uri(people.Customer.Avatar.Url));