Xamarin Forms - sectionIndexTitlesForTableView customisation - xamarin.forms

I have a Xamarin Forms app in which the customer really wanted to use the iOS 'scrolling alphabet index' that's not supported on Android
I have therefore two UIs for the platforms, but I am now trying to change the default colour of the text on iOS
I've looked into how to do this and it appears to require customising TableView on iOS platform
How change iOS TableView index Color?
tableView.sectionIndexColor = UIColor.red
tableView.sectionIndexBackgroundColor = UIColor.clear
My question is how do I then consume that in the view? Because the only code required to have it work on ioS can be shown simply by the Xaml
<ListView Grid.Row="1"
x:Name="ItemList"
IsGroupingEnabled="True"
ItemsSource="{Binding allItems}"
GroupDisplayBinding="{Binding Item}"
GroupShortNameBinding="{Binding IndexLetter}"
ItemTapped="Handle_ItemTapped"
CachingStrategy="RecycleElement"
BackgroundColor="Black"
HasUnevenRows="True">
This is a list view, not a table view, so where in the Xamarin Forms could would I reference the Custom Table View Renderer required to alter the colour of the text on iOS?

You could implement it by using Custom Renderer .
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using xxx.iOS;
[assembly:ExportRenderer(typeof(ListView),typeof(MyTableViewRenderer))]
namespace xxx.iOS
{
public class MyTableViewRenderer:ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if(Control!=null)
{
Control.SectionIndexColor = UIColor.Red;
Control.SectionIndexBackgroundColor = UIColor.Clear;
}
}
}
}

Related

Xamarin Forms: How to show an audio player on all pages of the app?

I have a page for playing songs in my project. When I go back to the previous page after playing a song (without pausing it), it will continue to play in the background, and users can pause it at any time from the notification bar. I am using Plugin.MediaManager (Version: 1.1.1) for the integration of songs.
Current song screens on my App
But we have a new suggestion, like playing the songs in the app itself on top or bottom on all the other pages (like WhatsApp). Our application has more than 100 pages, so adding the audio player on all these pages is a tedious task. So any other tricky way to implement it on all the pages by reusing it or any other better solution for this feature?
The expected feature is like the below one, like WhatsApp
If you have a common TabbedPage such as the screenshot you attached of Whatsapp, you could add at the beginning of its xaml file before the definition of the views:
<NavigationPage.TitleView>
<StackLayout>
...
</StackLayout>
</NavigationPage.TitleView>
That way you will have a common Navigation view on top of all of them with custom data that you could modify in the associated xaml.cs file of that TabbedPage.
If you have a different structure for your views you could check the documentation for Control Templates in Xamarin Forms, and include it in your App.xaml.
Good luck!
We implemented this using a pop-up page.
XAML:
<StackLayout
HorizontalOptions="Center"
VerticalOptions="End">
<mm:VideoView
Grid.Column="0"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
AutoPlay="True"
IsVisible="True"
x:Name="audioplayer"
ShowControls="True">
<mm:VideoView.HeightRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>80</OnIdiom.Phone>
<OnIdiom.Tablet>120</OnIdiom.Tablet>
<OnIdiom.Desktop>80</OnIdiom.Desktop>
</OnIdiom>
</mm:VideoView.HeightRequest>
</mm:VideoView>
</StackLayout>
XAML.CS
public partial class AudioPopupPage : PopupPage
{
public AudioPopupPage(object source)
{
InitializeComponent();
if (source != null)
{
audioplayer.Source = source;
}
}
protected override bool OnBackgroundClicked()
{
BackgroundInputTransparent = true;
return false;
}
}
We call the pop-up page when we leave the song page.
protected override bool OnBackButtonPressed()
{
PopupNavigation.Instance.PushAsync(new Views.AudioPopupPage(CrossMediaManager.Current.State), true);
return base.OnBackButtonPressed();
}
With this approach, this audio player is showing on all pages, and it is working fine on all platforms.

Unable to bind ObservableCollection to DataGrid in UserControl

I am trying to pass ObservableCollection from the XAML Page to the UserControl.
In a normal Visual Studio WPF project .NET Framework 4.8, within the UserControl the below XAML code works fine and the data can be seen within the Page.
<DataGrid Grid.Row="0" x:Name="dgAuthors" ItemsSource="{Binding Authors, RelativeSource= RelativeSource Mode=FindAncestor, AncestorType=local:UserControl1}}
Code behind of User Control as below:
public UserControl1()
{
InitializeComponent();
dgAuthors.DataContext = this;
}
public ObservableCollection<Author> Authors
{
get { return (ObservableCollection<Author>)GetValue(AuthorsProperty); }
set { SetValue(AuthorsProperty, value); }
}
// Using a DependencyProperty as the backing store for Authors. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AuthorsProperty =
DependencyProperty.Register("Authors", typeof(ObservableCollection<Author>), typeof(UserControl1), null);
But in UNO for .NET 5.0 framework, it is unable to find the Mode=FindAncestor and AncestorType when Binding is used within the ItemSource of the DataGrid.
Any help would be highly appreciated.
Many thanks
Neeraj
With the WinUI flavour of XAML used by Uno Platform, you can use x:Bind syntax to bind to a property in code-behind:
<DataGrid Grid.Row="0" x:Name="dgAuthors" ItemsSource="{x:Bind Authors, Mode=OneWay}} />

How to bind image icon on ToolbarItem on Platform tag

How to bind an image icon on the ToolbarItem OnPlatform tag in Xamarin.Forms
This is my code:
<ToolbarItem
Icon="{OnPlatform iOS='iconscalendarplus64.png', Android='iconscalendarplus64.png'}"
Priority="0"
Order="Primary"
Command="{Binding PrikaziCommand}"
I am trying to bind images for the Android OnPlatform, but it is not working.
Since the Android and iOS properties of the OnPlatform are not BindableProperty
They don't support Data Binding. Hence you cannot bind those Property.
As an alternative you can set the platform specific image source to a property in the ViewModel and you it instead.
XAML
<ContentPage.ToolbarItems>
<ToolbarItem IconImageSource="{Binding PlatformSpecificImage}"/>
</ContentPage.ToolbarItems>
View Model
public ImageSource PlatformSpecificImage { get; set; }
public ViewModel()
{
if(Device.RuntimePlatform == Device.Android)
{
PlatformSpecificImage = "android_image.png";
}
else
{
PlatformSpecificImage = "iOS_image.png";
}
}
Hope this could help!
The easiest way would be something like :
<ToolbarItem.Icon>
<OnPlatform x:TypeArguments="ImageSource">
<OnPlatform.iOS><FileImageSource File=""icon.png""/></OnPlatform.iOS>
<OnPlatform.Android><FileImageSource File=""icon.png""/></OnPlatform.Android>
<OnPlatform.WinPhone><FileImageSource File=""Images/icon.png""/></OnPlatform.WinPhone>
</OnPlatform>
</ToolbarItem.Icon>
The good thing is you can use all 4 types of ImageSource here based on platforms.
Good luck feel free to get back if you have queries

How can I make CommandBar render in Xamarin Forms UWP?

I have a ContentPage (actually an MvxContentPage) with ToolbarItems defined. The Items appear in Android and iOS as expected, but do not appear at all in UWP. I have tried setting SetToolbarPlacement to both Top and Bottom manually, in both the constructor and the OnAppearing method. Thus far, I have not been able to affect any change in the UWP application. Am I doing something wrong? Can Mvx not render the Toolbar?
<mvx:MvxContentPage
xmlns:mvx="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
x:TypeArguments="viewModels:CategoryListViewModel"
xmlns:viewModels=""
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="GSP.X.AccuStore.Forms.Views.Site.Profiles.CategoryListView">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Areas" Command="{Binding Path=GoToAreasCommand}" />
</ContentPage.ToolbarItems>
</mvx:MvxContentPage>
The problem is you have not add start page to NavigationPage. I have test with the follow code in the blank Xamrin.Froms app, the ToolbarItem display well in the top of MainPage.
public App()
{
InitializeComponent();
var nav = new NavigationPage(new MainPage());
MainPage = nav;
}

How to remove the shadow of a button on Xamarin Forms

is it possible?
I would like to remove the shadow of the buttons on Xamarin Forms.
Thanks
For delete shadow on button Android you just need create a renderer in project Droid and set BackroundColor with transparent or other color.
For a project using PCL :
[assembly: ExportRenderer(typeof(Button),typeof(FlatButtonRenderer))]
namespace Project.Droid
{
public class FlatButtonRenderer : ButtonRenderer
{
protected override void OnDraw(Android.Graphics.Canvas canvas)
{
base.OnDraw(canvas);
}
}
}
In XAML :
<Button BackgroundColor="Transparent" Text="ClickMe"/>
Explaining with more detail.
using Android.App;
using Android.Content.PM;
using Android.OS;
using Xamarin.Forms.Platform.Android;
using ProjectName.Droid;
using Xamarin.Forms;
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(FlatButtonRenderer))]
namespace ProjectName.Droid
{
public class FlatButtonRenderer : ButtonRenderer
{
protected override void OnDraw(Android.Graphics.Canvas canvas)
{
base.OnDraw(canvas);
}
}
}
#Tonatio in your renderer instead of using
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(FlatButtonRenderer))]
use this
[assembly: ExportRenderer(typeof(YourCustomButton), typeof(FlatButtonRenderer))]
you will have to make a CustomButton control that inherits from Xamarin.Forms.Button and then use that custom button in your xaml instead of regular button. that should do the thing
//Add references to your custom control
xmlns:controls="clr-namespace:YourNameSpace.Controls"
//Use control
<Grid>
<controls:YourCustomButton x:Name="_customButton"/>
</Grid>
Feel free to drop by if you need some more help.
There's a simple hack around this. Simply wrap the button in a Frame element, with HasShadow set to False
<Frame HasShadow="False" Padding="0" Margin="0">
<Button Padding="15"
Text="Log in"
TextColor="Blue"
FontSize="17" />
</Frame>
This will remove the button's shadow 😉

Resources