MediaElement in Xamarin Forms Community Toolkit is a view where we can play audio and video files. The media files (Audio / Video) can be in either remote or local and we can play those media files using uri. So In this article, I’m going to show you how to use MediaElement in Xamarin Forms.
Let’s Start
In this article you will see :
- MediaElement with local and remote source
- How to take screenshots and store in file
- Displaying all screenshots taken by app
MediaElement with local and remote source :
In this sample demo we will use Xamarin.CommunityToolkit nuget package.
Xamarin.CommunityToolkit
Xamarin.CommunityToolkit is a collection of Converters, Behaviours, Animations, Custom Views, Effects, Helpers etc. It simplifies the developers task when building Android, iOS and UWP applications using Xamarin Forms.
1 – Install Xamarin.CommunityToolkit nuget package

2 – Setting up the UI
2.1 – Create a MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="XFMediaElementSampleDemo.Views.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
NavigationPage.HasNavigationBar="False">
<StackLayout VerticalOptions="CenterAndExpand">
<Button
BackgroundColor="#559173"
Command="{Binding OnVideoListCommand}"
Text="Video List"
TextColor="White" />
<Button
BackgroundColor="#559173"
Command="{Binding OnScreenshotsCommand}"
Text="Screenshots List"
TextColor="White" />
</StackLayout>
</ContentPage>
- As in the above MainPage.xaml, I have taken 2 buttons as follows :
- Video List : Clicking on this will navigate to the Video List Page.
- Screenshots List : Clicking on this will navigate to the Screenshots List Page.
2.2 – Create a VideoListView.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
x:Class="XFMediaElementSampleDemo.Views.VideoListView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converter="clr-namespace:XFMediaElementSampleDemo.Converters"
xmlns:customMedia="clr-namespace:XFMediaElementSampleDemo.Views"
x:Name="videoView"
NavigationPage.HasNavigationBar="False">
<ContentPage.Resources>
<ResourceDictionary>
<converter:BoolToColorConverter x:Key="BoolToColor" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Spacing="0">
<BoxView
BackgroundColor="#559173"
HeightRequest="50"
IsVisible="{OnPlatform Android=False,
iOS=True}" />
<Grid
Padding="10"
BackgroundColor="#559173"
ColumnDefinitions="*,*,*"
HeightRequest="60"
HorizontalOptions="FillAndExpand">
<Image
Grid.Column="0"
HeightRequest="25"
HorizontalOptions="Start"
Source="left_arrow.png"
WidthRequest="25">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnBackCommand}" />
</Image.GestureRecognizers>
</Image>
<Label
Grid.Column="1"
FontSize="Medium"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
Text="Video List"
TextColor="White"
VerticalOptions="Center"
VerticalTextAlignment="Center" />
<Image
Grid.Column="2"
HeightRequest="35"
HorizontalOptions="End"
Source="camera.png"
WidthRequest="35">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnCaptureScreenCommand}" />
</Image.GestureRecognizers>
</Image>
</Grid>
<Grid RowDefinitions="*,Auto">
<!-- Top Selected Video List -->
<CollectionView
x:Name="ls"
Grid.Row="0"
ItemSizingStrategy="MeasureFirstItem"
ItemsSource="{Binding SelectedVideoList}"
SelectionMode="None"
VerticalOptions="FillAndExpand">
<CollectionView.ItemsLayout>
<GridItemsLayout
HorizontalItemSpacing="5"
Orientation="Vertical"
Span="2"
VerticalItemSpacing="5" />
</CollectionView.ItemsLayout>
<!-- Empty View -->
<CollectionView.EmptyView>
<StackLayout VerticalOptions="CenterAndExpand">
<Label
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
Text="No Video Found"
TextColor="Black"
VerticalOptions="CenterAndExpand"
VerticalTextAlignment="Center" />
</StackLayout>
</CollectionView.EmptyView>
<!-- Item Template -->
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout
Margin="5"
HeightRequest="230"
IsClippedToBounds="False"
VerticalOptions="Start">
<Label Text="{Binding Title}" TextColor="Black" />
<customMedia:CustomMediaElement IsStopMedia="{Binding IsStopMedia}" MediaUrl="{Binding VideoURL}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<!-- Bottom Horizontal Video List -->
<StackLayout Grid.Row="1" HeightRequest="170">
<Label Margin="0,10,0,0" Text="Select video for multiview layer" />
<StackLayout BackgroundColor="Black">
<CollectionView
Margin="5"
ItemSizingStrategy="MeasureFirstItem"
ItemsSource="{Binding VideoList}"
SelectionMode="None"
VerticalOptions="CenterAndExpand">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
<!-- Item Template -->
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame
Margin="5"
Padding="2"
BorderColor="{Binding IsSelected, Converter={StaticResource BoolToColor}}"
CornerRadius="0"
HeightRequest="110"
IsClippedToBounds="True"
WidthRequest="110">
<Grid>
<Image Source="play.png" />
<Frame
Margin="5"
Padding="3"
BackgroundColor="{Binding IsSelected, Converter={StaticResource BoolToColor}}"
CornerRadius="6"
HeightRequest="5"
HorizontalOptions="EndAndExpand"
VerticalOptions="EndAndExpand"
WidthRequest="5" />
</Grid>
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.OnVideoSelectedCommand, Source={x:Reference videoView}}" CommandParameter="{Binding .}" />
</Frame.GestureRecognizers>
</Frame>
<Label
FontSize="Medium"
HorizontalTextAlignment="Center"
Text="{Binding Title}"
TextColor="White" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</StackLayout>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
- As in the above VideoListView.xaml, I have taken 2 CollectionViews as follow :
- First CollectionView will show the selected videos from the second bottom CollectionView.
- Second CollectionView will horizontally show in the bottom so once the user selects videos those videos will add in the first CollectionView and play.
- BoolToColorConverter : I have used for changing the color based on bool value.
2.3 – Create a BoolToColorConverter.cs
using System;
using System.Globalization;
using Xamarin.Forms;
namespace XFMediaElementSampleDemo.Converters
{
public class BoolToColorConverter :IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool isTrue = (bool)value;
if (isTrue)
return Color.Green;
else
return Color.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}
2.4 – Create a CustomMediaElement.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="XFMediaElementSampleDemo.Views.CustomMediaElement"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
HeightRequest="200"
VerticalOptions="CenterAndExpand">
<ContentView.Content>
<xct:MediaElement
x:Name="mediaElement"
Aspect="AspectFit"
AutoPlay="True"
BackgroundColor="Black"
HeightRequest="200"
IsLooping="False"
KeepScreenOn="True"
ShowsPlaybackControls="True"
Source="{Binding VideoURL}"
VerticalOptions="CenterAndExpand" />
</ContentView.Content>
</ContentView>
2.5 – CustomMediaElement.xaml.cs
using System;
using System.Collections.Generic;
using Xamarin.CommunityToolkit.Core;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms;
namespace XFMediaElementSampleDemo.Views
{
public partial class CustomMediaElement : ContentView
{
private static MediaElement media;
public static readonly BindableProperty IsStopMediaProperty =
BindableProperty.Create(
"IsStopMedia",
typeof(bool),
typeof(CustomMediaElement),
false,
BindingMode.TwoWay,
propertyChanged: OnEventNameChanged);
public bool IsStopMedia
{
get { return (bool)GetValue(IsStopMediaProperty); }
set { SetValue(IsStopMediaProperty, value); }
}
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
{
if (!(bool)newValue)
media.Play();
else
media.Stop();
}
public static readonly BindableProperty MediaUrlProperty =
BindableProperty.Create(
"MediaUrl",
typeof(string),
typeof(CustomMediaElement),
string.Empty,
BindingMode.TwoWay,
propertyChanged: OnMediaUrlEventNameChanged);
public bool MediaUrl
{
get { return (bool)GetValue(MediaUrlProperty); }
set { SetValue(MediaUrlProperty, value); }
}
static void OnMediaUrlEventNameChanged(BindableObject bindable, object oldValue, object newValue)
{
string url = ((string)newValue);
if (!string.IsNullOrEmpty(url))
{
media.Source = MediaSource.FromUri(url);
}
}
public CustomMediaElement()
{
InitializeComponent();
CustomMediaElement.media = mediaElement;
}
}
}
- As in the above CustomMediaElement.xaml, I have used some properties in MediaElement as follows :
- Aspect : It determines how the video will be scaled to fit in a screen area.
- AutoPlay : It enables whether the video will play automatically or not.
- IsLooping : It enables whether the video will play again from start after reaching to end or not.
- KeepScreenOn : It enables whether the device screen will stay on during video play or not.
- ShowsPlaybackControls : It enables whether platform playback control will show or not.
- Source : It indicates the media source.
3 – Setting up the ViewModels
3.1 – Create a BaseViewModel.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace XFMediaElementSampleDemo.ViewModels
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public BaseViewModel()
{
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
3.2 – Create a VideoListViewModel.cs
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XFMediaElementSampleDemo.Models;
using XFMediaElementSampleDemo.Utiility;
namespace XFMediaElementSampleDemo.ViewModels
{
public class VideoListViewModel : BaseViewModel
{
#region Constructor
public VideoListViewModel()
{
GetVideoList();
OnVideoSelectedCommand = new Command<VideoItem>(t => OnVideoSelected(t));
OnCaptureScreenCommand = new Command(async () => await OnCaptureImageClick());
OnBackCommand = new Command(async () => await OnBackClick());
}
#endregion
#region Handle Click Event
private void OnVideoSelected(VideoItem videoItem)
{
Task.Run(() =>
{
var selectedVideoList = VideoList.Where<VideoItem>(t => t.IsSelected == true).ToList();
if ((videoItem != null && selectedVideoList.Count <= 3) || (videoItem.IsSelected == true && selectedVideoList.Count == 4))
{
videoItem.IsSelected = !videoItem.IsSelected;
if (SelectedVideoList != null)
{
var video = SelectedVideoList.Where<VideoItem>(t => t.Title.Equals(videoItem.Title)).FirstOrDefault();
Device.BeginInvokeOnMainThread(() =>
{
if (videoItem.IsSelected && video == null)
{
videoItem.IsStopMedia = false;
SelectedVideoList.Add(videoItem);
}
else if (videoItem.IsSelected == false && video != null)
{
videoItem.IsStopMedia = true;
SelectedVideoList.Remove(video);
}
});
}
}
else
{
Device.BeginInvokeOnMainThread(() =>
{
App.Current.MainPage.DisplayAlert("", "You can't select more than 4 videos", "ok");
});
}
});
}
private async Task OnCaptureImageClick()
{
var screenshot = await Xamarin.Essentials.Screenshot.CaptureAsync();
var stream = await screenshot.OpenReadAsync();
var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
bool isSaved = await FileHelper.SaveImage(memoryStream.ToArray(), "screen_" + DateTime.Now.Ticks + ".png");
if (isSaved)
await App.Current.MainPage.DisplayAlert("", "Image captured and saved.", "ok");
}
private async Task OnBackClick()
{
await App.Current.MainPage.Navigation.PopAsync();
}
#endregion
#region Properties
private ObservableCollection<VideoItem> _selectedVideoList = new ObservableCollection<VideoItem>();
public ObservableCollection<VideoItem> SelectedVideoList
{
get => _selectedVideoList;
set
{
_selectedVideoList = value;
OnPropertyChanged();
}
}
private ObservableCollection<VideoItem> _videoList = new ObservableCollection<VideoItem>();
public ObservableCollection<VideoItem> VideoList
{
get => _videoList;
set
{
_videoList = value;
OnPropertyChanged();
}
}
public ICommand OnVideoSelectedCommand { get; set; }
public ICommand OnCaptureScreenCommand { get; set; }
public ICommand OnBackCommand { get; set; }
#endregion
#region Making Dummy Video List
private void GetVideoList()
{
VideoList = new ObservableCollection<VideoItem>();
VideoList.Add(new VideoItem("Cam_01", "ms-appx:///video.mp4"));
VideoList.Add(new VideoItem("Cam_02", "ms-appx:///video1.mp4"));
VideoList.Add(new VideoItem("Cam_03", "ms-appx:///video2.mp4"));
VideoList.Add(new VideoItem("Cam_04", "ms-appx:///video3.mp4"));
VideoList.Add(new VideoItem("Cam_05", "ms-appx:///video4.mp4"));
}
#endregion
}
}
- As in the above VideoListViewModel.cs class, I am performing operations like Video Selection, Take Screenshots.
- OnVideoSelected() method is used for selecting video from the second bottom Collectionview and adding to the first CollectionView.
- GetVideoList() method is preparing a list of local videos. We can also use remote media uri instead of local both will work.
- Add all five videos :
- In Android, create a raw folder outside of the Resources folder and add all media files to there and make sure to set BUILD_ACTION to AndroidResource.
- In iOS, add all media files to Resources folder and make sure to set BUILD_ACTION to BundleResource.
- Add all five videos :
- OnCaptureImageClick() method is used to capture the screenshot and save it to the local XamarinScreenshots folder.
4 – Setting up the Model
4.1 – Create a VideoItem.cs
using System;
using XFMediaElementSampleDemo.ViewModels;
namespace XFMediaElementSampleDemo.Models
{
public class VideoItem : BaseViewModel
{
public string Title { get; set; }
public string VideoURL { get; set; }
//public string VideoURL { get; set; } = "ms-appx:///video.mp4";
//public string VideoURL { get; set; } = "https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4";
//public string VideoURL { get; set; } = "https://multiplatform-" +"f.akamaihd.net/i/multi/will/bunny/big_buck_bunny_,640x360_400,640x36" +"0_700,640x360_1000,950x540_1500,.f4v.csmil/master.m3u8";
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
_isSelected = value;
OnPropertyChanged();
}
}
private bool _isStopMedia;
public bool IsStopMedia
{
get => _isStopMedia;
set
{
_isStopMedia = value;
OnPropertyChanged();
}
}
public VideoItem(string title, string videoURL)
{
Title = title;
VideoURL = videoURL;
}
}
}
How to take screenshots and store in file :
I have used PCLStorage nuget package for taking screenshots and storing into local folder.
PCLStorage provides a set of local file IO api’s for Xamarin Android, Xamarin iOS, Windows Phone etc.
1 – Install PCLStorage nuget package

2 – Create a FileHelper.cs class for managing file IO operations
using PCLStorage;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using Xamarin.Forms;
using XFMediaElementSampleDemo.Models;
using FileAccess = PCLStorage.FileAccess;
namespace XFMediaElementSampleDemo.Utiility
{
public static class FileHelper
{
public const string FOLDER_NAME = "XamarinScreenshots";
public async static Task<bool> IsFileExistAsync(this string fileName, IFolder rootFolder = null)
{
// get hold of the file system
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
ExistenceCheckResult folderexist = await folder.CheckExistsAsync(fileName);
// already run at least once, don't overwrite what's there
if (folderexist == ExistenceCheckResult.FileExists)
{
return true;
}
return false;
}
public async static Task<bool> IsFolderExistAsync(this string folderName, IFolder rootFolder = null)
{
// get hold of the file system
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
ExistenceCheckResult folderexist = await folder.CheckExistsAsync(folderName);
// already run at least once, don't overwrite what's there
if (folderexist == ExistenceCheckResult.FolderExists)
{
return true;
}
return false;
}
public async static Task<IFolder> CreateFolder(this string folderName, IFolder rootFolder = null)
{
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
folder = await folder.CreateFolderAsync(folderName, CreationCollisionOption.ReplaceExisting);
return folder;
}
public async static Task<IFile> CreateFile(this string filename, IFolder rootFolder = null)
{
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
IFile file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
return file;
}
public async static Task<bool> WriteTextAllAsync(this string filename, string content = "", IFolder rootFolder = null)
{
IFile file = await filename.CreateFile(rootFolder);
await file.WriteAllTextAsync(content);
return true;
}
public async static Task<string> ReadAllTextAsync(this string fileName, IFolder rootFolder = null)
{
string content = "";
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
bool exist = await fileName.IsFileExistAsync(folder);
if (exist == true)
{
IFile file = await folder.GetFileAsync(fileName);
content = await file.ReadAllTextAsync();
}
return content;
}
public async static Task<bool> DeleteFile(this string fileName, IFolder rootFolder = null)
{
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
bool exist = await fileName.IsFileExistAsync(folder);
if (exist == true)
{
IFile file = await folder.GetFileAsync(fileName);
await file.DeleteAsync();
return true;
}
return false;
}
public async static Task<bool> SaveImage(this byte[] image, String fileName, IFolder rootFolder = null)
{
try
{
if (!await IsFolderExistAsync(FOLDER_NAME))
{
await CreateFolder(FOLDER_NAME);
}
// get hold of the file system
IFolder folder = await FileSystem.Current.LocalStorage.GetFolderAsync(FOLDER_NAME);
// create a file, overwriting any existing file
IFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
// populate the file with image data
using (System.IO.Stream stream = await file.OpenAsync(FileAccess.ReadAndWrite))
{
stream.Write(image, 0, image.Length);
}
return true;
}
catch (Exception ex)
{
return false;
}
}
public async static Task<byte[]> LoadImage(this byte[] image, string fileName, IFolder rootFolder = null)
{
// get hold of the file system
IFolder folder = rootFolder ?? FileSystem.Current.LocalStorage;
//open file if exists
IFile file = await folder.GetFileAsync(fileName);
//load stream to buffer
using (System.IO.Stream stream = await file.OpenAsync(FileAccess.ReadAndWrite))
{
long length = stream.Length;
byte[] streamBuffer = new byte[length];
stream.Read(streamBuffer, 0, (int)length);
return streamBuffer;
}
}
public async static Task<ObservableCollection<ScreenShotItem>> LoadAllImage(IFolder rootFolder = null)
{
if (!await IsFolderExistAsync(FOLDER_NAME))
{
await CreateFolder(FOLDER_NAME);
}
// get hold of the file system
IFolder folder = await FileSystem.Current.LocalStorage.GetFolderAsync(FOLDER_NAME);
//open file if exists
var files = await folder.GetFilesAsync();
ObservableCollection<ScreenShotItem> screenShots = new ObservableCollection<ScreenShotItem>();
foreach (IFile file in files)
{
//load stream to buffer
using (System.IO.Stream stream = await file.OpenAsync(FileAccess.ReadAndWrite))
{
long length = stream.Length;
byte[] streamBuffer = new byte[length];
stream.Read(streamBuffer, 0, (int)length);
screenShots.Add(new ScreenShotItem() { Title = file.Name, Screenshots = ImageSource.FromStream(() => new MemoryStream(streamBuffer)) });
//screenShots.Add(new ScreenShotItem() { Title = file.Name, Screenshots = ImageSource.FromFile(file.Path) });
}
}
return screenShots;
}
public static byte[] ReadStream(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
}
Displaying all screenshots taken by app :
1 – Setting up the UI
1.1 – Create a ScreenShotsView.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
x:Class="XFMediaElementSampleDemo.Views.ScreenShotsView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
NavigationPage.HasNavigationBar="False">
<ContentPage.Content>
<StackLayout Spacing="0">
<BoxView
BackgroundColor="#559173"
HeightRequest="50"
IsVisible="{OnPlatform Android=False,
iOS=True}" />
<Grid
Padding="10"
BackgroundColor="#559173"
ColumnDefinitions="*,*,*"
HeightRequest="60"
HorizontalOptions="FillAndExpand">
<Image
Grid.Column="0"
HeightRequest="25"
HorizontalOptions="Start"
Source="left_arrow.png"
WidthRequest="25">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnBackCommand}" />
</Image.GestureRecognizers>
</Image>
<Label
Grid.Column="1"
FontSize="Medium"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
Text="Screenshot List"
TextColor="White"
VerticalOptions="Center"
VerticalTextAlignment="Center" />
</Grid>
<Grid RowDefinitions="*,Auto">
<!-- Top Selected Video List -->
<CollectionView
Grid.Row="0"
ItemSizingStrategy="MeasureFirstItem"
ItemsSource="{Binding ScreenShots}"
SelectionMode="None"
VerticalOptions="FillAndExpand">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!-- Empty View -->
<CollectionView.EmptyView>
<StackLayout VerticalOptions="CenterAndExpand">
<Label
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
Text="No Screenshot found"
TextColor="Black"
VerticalOptions="CenterAndExpand"
VerticalTextAlignment="Center" />
</StackLayout>
</CollectionView.EmptyView>
<!-- Item Template -->
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame
Margin="5"
Padding="2"
BorderColor="Black"
CornerRadius="0"
HasShadow="False"
HeightRequest="230"
VerticalOptions="Start">
<StackLayout>
<Label
HorizontalTextAlignment="Center"
Text="{Binding Title}"
TextColor="Black" />
<Image
Aspect="AspectFill"
BackgroundColor="Black"
HeightRequest="200"
Source="{Binding Screenshots}"
VerticalOptions="FillAndExpand" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
2 – Setting up the ViewModel
2.1 – Create a ScreenShotsViewModel.cs
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XFMediaElementSampleDemo.Models;
using XFMediaElementSampleDemo.Utiility;
namespace XFMediaElementSampleDemo.ViewModels
{
public class ScreenShotsViewModel : BaseViewModel
{
#region Constructor
public ScreenShotsViewModel()
{
OnBackCommand = new Command(async () => await OnBackClick());
_ = GetScreenShots();
}
#endregion
#region Handle Click Events
private async Task OnBackClick()
{
await App.Current.MainPage.Navigation.PopAsync();
}
#endregion
#region Properties
public ICommand OnBackCommand { get; set; }
private ObservableCollection<ScreenShotItem> _screenShots = new ObservableCollection<ScreenShotItem>();
public ObservableCollection<ScreenShotItem> ScreenShots
{
get => _screenShots;
set
{
_screenShots = value;
OnPropertyChanged();
}
}
#endregion
#region Get Screen Shots
private async Task GetScreenShots()
{
ScreenShots = await FileHelper.LoadAllImage();
}
#endregion
}
}
3 – Setting up the Model
3.1 – Create a ScreenShotItem.cs
using System;
using Xamarin.Forms;
namespace XFMediaElementSampleDemo.Models
{
public class ScreenShotItem
{
public string Title { get; set; }
public ImageSource Screenshots { get; set; }
}
}
Now, We have completed the coding, Let’s try to run the application.
Result
That’s all for now!
You can check the full source code here.
Happy Coding! 😀
You may also like


