Xamarin forms ControlTemplate for header, another for footer and bindings - xamarin

I am making an App that has the same header on every screen, so I created a ControlTemplate for that part of the app, put some buttons on it and that works. I am pretty happy with it.
Three screens have almost identical footer, only different text color and images. I made another ControlTemplate for the footer, and I would like to manipulate the IsVisible property on the images with bindings, according to what page is currently dislayed, but I am not able to figure out how to do it.
I know that I need to write a converter, I did that, that doesn't seem to be complicated, but I can't figure out a way to actually bind the values in those properties.
Both of ControlTemplates are defined on the application level.
This is an example of how I use them, maybe this is wrong:
<ContentView ControlTemplate="{StaticResource Header}">
<!--This is the actuall page content-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="9*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Content of the page!-->
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="Center"
HorizontalOptions="Center"
Grid.Row="0"/>
<!--Footer of the page!-->
<ContentView ControlTemplate="{StaticResource BuySellPayFooter}"
Grid.Row="1"/>
</Grid>
</ContentView>
I need to bind properties of some class in the footer. How to do it? Is it achievable?

I use ControlTemplate to show an ActivityIndicator on every page.
For property IsVisible of the indicator, I bind it with property IsBusy of the
page.
And this is how I bind it in the XAML of the ControlTemplate:
IsVisible="{TemplateBinding BindingContext.IsBusy}"
If I want to change the color of the indicator on each page, I can define BusyColor property for the page and binding it:
Color="{TemplateBinding BindingContext.BusyColor}"

Related

Change ToolbarItem Text/Icon parameters

I am new to MAUI. And I haven't done anything complex with Xamarin as well.
The application I am testing with, has Shell navigation. And I can't find a way to change the toolbar items.
I would like to be able to change either the FontSize of the text, or the color of the SVG image. And I do not want those changes to affect the rest of my application, if possible. But if there is no other way, I can live with it.
I have managed to add styling to buttons, Labels etc... If styling is an option to this, it will be even better.
If I am on the wrong path, if you point me out why, I will be also grateful.
Thank you in advance!
If you want to just change a part of pages in your project. You can try to use a <Shell.TitleView> instead of the <Shell.ToolBarItem> in the content pages you want. Such as:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppTest.MainPage">
<Shell.TitleView>
<HorizontalStackLayout Margin="5" HorizontalOptions="End">
<Label Text="hello" TextColor="Red" FontSize="Medium" VerticalOptions="Center" HorizontalOptions="End" />
<Image Source="your image" Margin="10" Background="green"/>
</HorizontalStackLayout>
</Shell.TitleView>
You can change style of TabBar in Style.xaml in path \Resources\Style\. Search in file for Shell.TabBarForegroundColor. You will get TargetType="Shell" and this is style for AppShell.xaml.

Xamarin.Forms list through list of objects control

Which control in Xamarin can be utilized to do listing through a list of objects with the arrows left and right such as the one on the screenshot?
There is no such a control in Xmarin.forms .But you can implement it by yourself.
in xaml
<Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.15*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.15*" />
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Image Source="xxx" x:Name="rightBtn"/>
</StackLayout>
<controls:CarouselViewControl Grid.Column="1" Orientation="Horizontal" InterPageSpacing="10" Position="{Binding myPosition}" ItemsSource="{Binding myItemsSource}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<controls:CarouselViewControl.ItemTemplate>
<DataTemplate>
<local:MyView />
<!-- where MyView is a ContentView -->
</DataTemplate>
</controls:CarouselViewControl.ItemTemplate>
</controls:CarouselViewControl>
<StackLayout Grid.Column="2" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Image Source="xxx" x:Name="leftBtn"/>
</StackLayout>
</Grid>
You can use CarouselView . And change the position of it when you click right or left button .You can add a tap gesture recognizer on image or use ImageButton if you want to set button image by yourself. Or you can use default arrows of CarouselView .
If the arrows are a requirement and you don't have many items in your control (10 or less), the CarouselView is matching exactly your requirements. You can even show the arrows with the ShowArrows property.
https://github.com/alexrainman/CarouselView
Careful though cause this component doesn't recycle its views, that's why it's good only for a small number of views.
If you have a high number of views, you use this HorizontalListView with Carousel list layout:
https://github.com/roubachof/Sharpnado.Presentation.Forms#carousel-layout
What about the Xamarin.Forms CollectionView?
CollectionView has a flexible layout model, which allows data to be presented vertically or horizontally, in a list or a grid.
CollectionView supports single and multiple selection.
CollectionView has no concept of cells. Instead, a data template is used to define the appearance of each item of data in the list.
CollectionView automatically utilizes the virtualization provided by the underlying native controls.
CollectionView reduces the API surface of ListView. Many properties and events from ListView are not present in CollectionView.
CollectionView does not include built-in separators.
See documentation.

Grid with RowSpacing(Xamarin Forms) and navigation

Now I'm working on updating the UI of my app(XF for Android). I found this UI solution for appbar(from source code Evolve 2016):
It looks beautiful and is implemented simply:
<ContentPage.Content>
<Grid RowSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout BackgroundColor={StaticResource Primary}, Grid.Row=0/>
<SearchBar/>
</StackLayout>
<StackLayout Grid.Row=1>
//other content
</StackLayout>
.....
For existing navigation(Master-Detail) it works fine. But I click by item (on this page) - than open new page(no Master Detail). Work like this:
await Navigation.PushAsync(new SessionDetailPage(), true);
I click back on toolbar - return to Session page than I get a white line display for a short time
it does not last long, a split second. then the white line disappears. But it's unpleasant to use.
Any ideas? How can I improve this?
Might be RowDefinition Height="Auto" calculating and resizing itself, try use absolute value to check if this is the cause.

Loader image in xamarin.forms?

How to display loader image. If service is hitting, I want to display loader image in background in Xamarin.Forms.
Xamarin.Forms has an ActivityIndicator: http://iosapi.xamarin.com/index.aspx?link=T%3AXamarin.Forms.ActivityIndicator
You'll probably find various code examples on how to use it.
If the core problem is how to load something in the background while displaying any "loading" indicator, you might look into this example: http://xforms-kickstarter.com/#asynchronous-web-requests
Use Xamarin.Forms' ActivityIndicator. Click here for details please.
This is how I use it, you just need to create a new property in your view model and call it as IsLoading, if this is set to true, then Activity Indicator will be visible, that is all you need;
// IsLoading property in the viewmodel
public bool IsLoading
{
get
{
return isLoading;
}
set
{
isLoading = value;
OnPropertyChanged();
}
}
//code sample in xaml
<Grid Grid.Row="1"
IsVisible="{Binding IsLoading}"
BackgroundColor="Black"
Opacity="0.25">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ActivityIndicator Grid.Row="0"
IsVisible="{Binding IsLoading}"
IsRunning="{Binding IsLoading}"
VerticalOptions="End"
HorizontalOptions="Center"/>
<Label Grid.Row="1"
Text="Please wait..."
TextColor="White"
VerticalOptions="Start"
HorizontalOptions="Center"/>
</Grid>
Your Question is not very clear,
I guess you just mean you want to notify the user with a loading animation, while a task running in the background is taking some time?
Check http://developer.xamarin.com/recipes/ios/standard_controls/popovers/display_a_loading_message/
for a quick and easy way to implement that. The code there is quite editable so you can adapt it for your needs.
For a cross platform solution (Xamarin.Forms), you might want to look at:
Xamarin Forms show blocking loading message
For implementation of Loader or ActivityIndicator, Xamarin has provided pretty good components for iOS and android. i.e. btprogresshud for iOS and Andhud for Android. These components can be used through Xamarin.Forms.

How to create a tablet UI with multiple ContentPages on one screen at the same time with Xamarin.Forms?

I want to design a UI for tablets (Android & iOS) with Xamarin.Forms where I want to have multiple ContentPages on one screen. I know how to achieve this for Android by using Fragments (afaik for iOS it's UISplitViewController).
How can I achieve this with Xamarin.Forms?
P.s. I definitely don't want a TabbedPage!
As far as I know you can't put multiple ContentPage items on the screen, at least not within the out-of-the-box Xamarin.Forms.
You can, however, put multiple ContentView items on the screen and you can reuse the ContentView items in stand-alone pages as well.
Essentially you can describe what you'd want to see on a single page as a ContentView and then make a page that just includes that
PhotoItem.xaml:
<ContentView>
<Grid>
<Image Source="{Binding MyImageSource}"/>
</Grid>
</ContentView>
PhotoBucket.xaml:
<ContentPage xmlns:local="namespace;assembly">
<ContentPage.Content>
<OnIdiom x:TypeArguments="View">
<OnIdiom.Phone>
<ListView>
... on list item tap do Navigation.PushAsync(new PhotoItemPage{BindingContext = itemTapped} );
</ListView>
</OnIdiom.Phone>
<OnIdiom.Tablet>
<Grid> // Add two columns
<ListView Grid.Column="0">
... on list item tap do PhotoItem.BindingContext = itemTapped
</ListView>
<local:PhotoItem Grid.Column="1"/>
</OnIdiom.Tablet>
</OnIdiom>
</ContentPage.Content>
</ContentPage>
PhotoItemPage.xaml:
<ContentPage xmlns:local="namespace;assembly">
<local:PhotoItem>
</ContentPage>
You can't have multiple pages, use content views for it. Or custom renderers

Resources