How to make from xamarin.forms 4.3 identical to СarouselPage? - xamarin.forms

The documentation says that I should use the page carousel for the place, this is a carousel view. But I do not understand how to do this.
I have three completely different pages. If earlier I could do like this. look how easy it is.
<CarouselPage 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"
xmlns:local="clr-namespace:test.Views"
x:Class="test.Corusel">
<CarouselPage.Children>
<local:Page1></local:Page1>
<local:Page2></local:Page2>
</CarouselPage.Children>
Now, when I try to make a look identical to the CarouselPage, I just have a white screen.
<ContentPage 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"
xmlns:local="clr-namespace:test.Views"
x:Class="test.Corusel">
<CarouselView>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<local:View1></local:View1>
<local:View2></local:View2>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ContentPage>
People tell me that there should be an itemSource. Without itemSource, content will not be displayed. But as I understand it, itemSource does not allow you to make different layouts for data.
I don’t understand how I can make a copy of СarouselPage from СarouselView (or CollectionView) if:
My pages have different layouts!
To load content into different layouts, I use different functions!

In my knowledge what you are looking for is the DataTemplateSelector
Create a subclass of Selector with properties that hold the templates:
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate ValidTemplate { get; set; }
public DataTemplate InvalidTemplate { get; set; }
protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
{
return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;
}
}
Add them to your resources:
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="validPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="invalidPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<local:PersonDataTemplateSelector x:Key="personDataTemplateSelector"
ValidTemplate="{StaticResource validPersonTemplate}"
InvalidTemplate="{StaticResource invalidPersonTemplate}" />
</ResourceDictionary>
</ContentPage.Resources>
Use them:
ItemTemplate="{StaticResource personDataTemplateSelector}"
For more information check the microsoft documents: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/selector

Related

Can I create some small views including created views to use it in mainPage?

Can I create a view including Entry Progress bar or others to make a view which I can use in other places?
for example I want to create a card view which I can use to list the lists.
I can only write in the list not to write the card in every list.
Yes, you can create a custom view and use it in the MainPage or other Pages, Views you want.
To create a custom view, add a new item --> ContentView,let's call it CardView:
In .cs of CardView:
public partial class CardView : ContentView
{
public CardView()
{
InitializeComponent();
}
}
In xaml of CardView, add your labels,progressbar, entry there:
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="App35.CardView">
<ContentView.Content>
<StackLayout>
<Label Text="Hello Xamarin.Forms!" />
<ProgressBar Progress="0.5" />
<Entry Placeholder="I'm entry"/>
</StackLayout>
</ContentView.Content>
</ContentView>
To use it in MainPage, in listView or in the page:
<StackLayout>
<projectName:CardView HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
<ListView x:Name="listView" RowHeight="70">
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>mono</x:String>
<x:String>monodroid</x:String>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<projectName:CardView HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
I upload a sample here and you can check.
Yes you can do that using ContentView, if you want to use it as views
Or you can make ViewCells if you want to use it in ListViews. Its easy and almost every project does that.
You can refer this link :- https://xamarinhelp.com/xamarin-forms-user-control/
Let me know if you have more questions on this. Thanks!

Xamarin.Forms: Tabs with Sharnado.presentation.forms do not respond to tap

I'm trying to use Sharpnado's awesome tab functionality to create what they call "Fixed tabs". But it is not doing what I want it to - and the problem may lay somewhere else... Basically, the tabs are not responding to a tap. I have narrowed it down to just that with this simple exampl.
The context is an app that uses an ordinary tabbed page (with navigation pages for each tab). On one of these tabs I have tried to put the TabHostViewcontrol - even without binding as I originally thought that was the problem. This is a screenshot of the test page:
Nothing happens when I tap the two tabs ("Personlig" and "Udforsk"). The XAML looks like this:
<?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:tabs="clr-namespace:Sharpnado.Presentation.Forms.CustomViews.Tabs;assembly=Sharpnado.Presentation.Forms"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
xmlns:views="clr-namespace:Angler.Views.Partials"
x:Class="Angler.Views.StatisticsPage">
<NavigationPage.TitleView>
<Label Text="{Binding Title}" HorizontalOptions="Center"
VerticalOptions="Center" Style="{StaticResource PageTitle}" />
</NavigationPage.TitleView>
<StackLayout VerticalOptions="FillAndExpand" BackgroundColor="LightYellow">
<Label Text="{Binding ShowSelectedTab}" Margin="20,10" />
<Grid RowSpacing="0" ColumnSpacing="0" Margin="0"
BackgroundColor="LightPink" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<tabs:TabHostView ShadowType="Bottom" Grid.Row="0">
<tabs:TabHostView.Tabs>
<tabs:UnderlinedTabItem Label="Personlig" />
<tabs:UnderlinedTabItem Label="Udforsk" IsSelected="True" />
</tabs:TabHostView.Tabs>
</tabs:TabHostView>
</Grid>
</StackLayout>
</ContentPage>
The viewmodel looks like this (although the above has been narrowed down to not using the property for the tabindex. But I did also investigate if the binding context for the viewmodel was Ok - and it seems to be):
public class StatisticsPageViewModel : ViewModelBase
{
public int SelectedTabIndex { get; set; }
public string ShowSelectedTab { get { return $"Index: {SelectedTabIndex}"; } }
public StatisticsPageViewModel(INavigationService navigationService, IPageDialogService pageDialogService,
IDeviceService deviceService) : base(navigationService, pageDialogService,
deviceService)
{
Title = AppResources.StatisticsPageTitle;
}
public override void OnAppearing()
{
//SelectedTabIndex = 1;
base.OnAppearing();
Analytics.TrackEvent("Navigate to Statistics");
}
}
I'm using VisualStudio for Mac 8.3.4 (build 8), Sharpnado.presentations.forms 1.3.0 and Prism.forms 7.2.0.1367.
I have tried to add InputTransparent="True" to some of the container objects - with no effect.
Any good ideas as to how to solve this is most appreciated!
Ok, this was just stupid (and a waste of two days!)...
In trying to solve other issues I had stepped back in my source repo - and once too far back... So the initialization of Sharpnado in the platforms projects were not there. That kind of made a difference.
So you will see this kind of behavious if you have not remembered to add this line to your platform projects:
SharpnadoInitializer.Initialize()
Just leaving it here in the case that someone else might end up with the same symptom :-)

Xamarin.Forms: How to hide the Navigation Bar Separator on iOS devices?

I have changed the default color of the navigation bar by using these codes in app.xaml as I am unable to make it transparent on iOS devices:
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="#0a82b8" />
<Setter Property="BarTextColor" Value="#ffffff" />
</Style>
Now, there is an unnecessary navigation bar separator on iOS:
On Microsoft's official website, it says these codes can be helpful:
This platform-specific hides the separator line and shadow that is at
the bottom of the navigation bar on a NavigationPage. It's consumed in
XAML by setting the NavigationPage.HideNavigationBarSeparator bindable
property to false:
<NavigationPage ...
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:NavigationPage.HideNavigationBarSeparator="true">
</NavigationPage>
Alternatively, it can be consumed from C# using the fluent API:
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
public class iOSTitleViewNavigationPageCS : Xamarin.Forms.NavigationPage
{
public iOSTitleViewNavigationPageCS()
{
On<iOS>().SetHideNavigationBarSeparator(true);
}
}
Source: Hiding the Navigation Bar Separator on a NavigationPage
The problem is that when I want to paste the ios:NavigationPage.HideNavigationBarSeparator="true" property into the <NavigationPage>tag, it gives this error:
No property, bindable property, or event found for 'HideNavigationBarSeparator', or mismatching type between value and property.
My full codes are:
<?xml version="1.0" encoding="utf-8"?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:My.App" x:Class="My.App.MainPage">
<MasterDetailPage.Master>
<ContentPage Title="Menu" BackgroundColor="#0a82b8" Icon="menu.png">
<StackLayout Orientation="Vertical">
<ListView x:Name="navigationDrawerList" RowHeight="55" SeparatorVisibility="None" BackgroundColor="#ffffff" ItemSelected="OnMenuItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!-- Main design for our menu items -->
<StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal" Padding="20,10,0,10" Spacing="20">
<Label Text="{Binding Title}" FontSize="Large" VerticalOptions="Start" HorizontalOptions="CenterAndExpand" TextColor="#28DDFF" FontAttributes="Bold" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:NavigationPage.HideNavigationBarSeparator="true">
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
Here is the tutorial which I followed for the MasterDetail navigation. The file which has <NavigationPage> tag is named as MainPage.xaml
You can use a custom renderer to hide that shadow:
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationPage))]
namespace CustomNavigationPage.iOS
{
public class CustomNavigationPage : NavigationRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
NavigationBar.SetBackgroundImage(new UIKit.UIImage(), UIKit.UIBarMetrics.Default);
NavigationBar.ShadowImage = new UIKit.UIImage();
}
}
}
While you have accepted the answer, this one is more precise - you haven't followed the instructions that you have pasted from the site as you have ommited this line:
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
Place UINavigationBar.Appearance.ShadowImage = new UIImage(); inside the public override bool FinishedLaunching(UIApplication app, NSDictionary options) method within AppDelegate.cs file. AppDelegate.cs resides within the iOS project of Xamarin.Forms

Xamarin.Forms How do we remove a child from a TabbedPage's children?

I would like to add and remove child pages from a tabbed page in certain conditions.
However, it gives me that collection "Children" is read only .
Has anyone succeeded ?
Here is the code for TabbedPage
<TabbedPage 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"
xmlns:partialViews="clr-namespace:TestTabbed.Views.PartialViews;assembly=TestTabbed"
prism:ViewModelLocator.AutowireViewModel="False"
x:Class="TestTabbed.Views.MainPage"
ItemsSource="{Binding ChannelLists}" Appearing="MainPage_OnAppearing"
Disappearing="MainPage_OnDisappearing">
<TabbedPage.ItemTemplate>
<DataTemplate>
<ContentPage Title="{Binding Name}" x:Name="mainContentPage">
<ContentPage.Content>
<OnIdiom x:TypeArguments="View">
<OnIdiom.Phone>
<partialViews:MainPhoneView />
</OnIdiom.Phone>
<OnIdiom.Tablet>
<partialViews:MainTabletView />
</OnIdiom.Tablet>
</OnIdiom>
</ContentPage.Content>
</ContentPage>
</DataTemplate>
</TabbedPage.ItemTemplate>
</TabbedPage>
Seeing your code might be helpful in case I am missing the actual issue but the following should work for you (note that you cannot directly assign a collection to the TabbedPage.Children property which is what it sounds like you are running into):
TabbedPage tab = new TabbedPage();
ContentPage page = new ContentPage();
tab.Children.Add(page);
tab.Children.Remove(page);
Where as the following will not work:
TabbedPage tab = new TabbedPage();
tab.Children = new List<Page>();

Xamarin.Forms: Can I embed one ContentPage or ContentView into another ContentPage

I have multiple ContentPage xaml files in my Xamarin project. I want to embed a shared piece of xaml into each ContentPage. There is nothing particularly special about the shared piece of xaml (it does't need to do anything platform specific). Shouldn't it be just as easy as embedding a tag in the xaml of the ContentPage to include the shared xaml file? Can someone point me in the right direction?
Thank you very much IdoT, It did work for me, but after adding some lines.
As this will help in making templates/custom controls/sub forms, easily added/shared across Xamarin.Forms.
Here is my full work based on your suggestion, so it can be used as is with others:
HeaderNavigationBar.xaml
<?xml version="1.0" encoding="utf-8" ?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App9.MVC.Views.HeaderNavigationBar"
Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
Padding="10"
ackgroundColor="White">
<Button Text="Internal 1" />
<Button Text="Internal 2" />
</StackLayout>
As you can see, added:
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
and in the HeaderNavigationBar.cs, it was declared as StackLayout:
HeaderNavigationBar.cs
using Xamarin.Forms;
namespace App9.MVC.Views
{
public partial class HeaderNavigationBar : StackLayout
{
public HeaderNavigationBar()
{
InitializeComponent();
}
}
}
then for the page that will hold it/show it:
MainView.xaml
<?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:common="clr-namespace:App9.MVC.Views;assembly=App9"
x:Class="App9.MVC.Views.MainView">
<StackLayout Padding="0,0,0,20">
<common:HeaderNavigationBar>
<Button Text="External 1" />
</common:HeaderNavigationBar>
<Button Text="Test Button 1
x:Name="btnPage1"
Clicked="btnPage1_clicked" />
</StackLayout>
</ContentPage>
As you can notice, the namespace has the full path, in the MainView:
xmlns:common="clr-namespace:App9.MVC.Views;assembly=App9"
Also, you can notice that there is a button called External 1, this will also show with the
Internal buttons, as the control is a StackLayout, so it can handle adding more controls.
Screenshot:
Also for Page inside another Page:
https://github.com/twintechs/TwinTechsFormsLib
http://blog.twintechs.com/advanced-xamarin-forms-techniques-for-flexible-and-performant-cross-platform-apps-part-5-page-in-page-embedding
Again thanks goes to IdoT.
You can take the parent child of your ContentPage (for example, a StackLayout that wraps all the children), put it in an external xaml file,
and then include that component in each one of your ContentPages.
The external xaml file will be a StackLayout type, rather than a ContentPage.
Edit - added a code sample:
Let's add a header StackLayout: we add a code behind class:
public partial class HeaderNavigationBar
{
public HeaderNavigationBar()
{
InitializeComponent();
}
}
Then add the XAML code:
<StackLayout x:Class="HeaderNavigationBar"
Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
Padding="10"
BackgroundColor="White">
<Image Source="burger_icon"
HorizontalOptions="StartAndExpand"
Aspect="AspectFit">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SlideNavigationDrawerCommand}" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
And finally, in the page where you want to reuse your component - add this reference:<HeaderNavigationBar />.

Resources