I have a page with a collection view. I have a button that allows the user to generate a pdf from the collection view data and share the pdf. the generation process takes a few seconds because there is a lot of data so I thought I should show something like a progress bar or progress ring to keep the user waiting and do nothing during this process. I tried to show something like a pop up using content view. this is the code: of the content view:
<ContentView x:Name="popupLoadingView" BackgroundColor="Transparent" Padding="10, 0" IsVisible="false" HorizontalOptions="Center" VerticalOptions="Center">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center">
<StackLayout Orientation="Vertical" HeightRequest="150" WidthRequest="200" BackgroundColor="White">
<ActivityIndicator x:Name="activityIndicator" Margin="0,50,0,0" VerticalOptions="Center" HorizontalOptions="Center" Color="Black" WidthRequest="30" HeightRequest="30" ></ActivityIndicator>
<Label x:Name="lblLoadingText" TextColor="Black" VerticalOptions="Center" HorizontalOptions="Center" VerticalTextAlignment="Center" Text="Loading..."></Label>
</StackLayout>
</StackLayout>
</ContentView>
and this is the code of my collection view
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="isc_alphaApp.Inventory">
<ContentPage.ToolbarItems >
<ToolbarItem Order="Secondary"
Text="logout"
Priority="2"
/>
</ContentPage.ToolbarItems>
<ContentPage.Resources>
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="#ffc40c" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout >
<SearchBar HorizontalOptions="FillAndExpand" x:Name="search" BackgroundColor="#ffc40c"/>
<CollectionView x:Name="lstl"
SelectionChanged="lstl_SelectionChanged"
SelectionMode="Single"
>
<CollectionView.Header>
<Grid Padding="2" ColumnSpacing="1" RowSpacing="1" >
<Grid.RowDefinitions>
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Text="Code"
FontAttributes="Bold"
LineBreakMode="TailTruncation"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="Black"/>
<Label Grid.Column="1"
Text="Description"
FontAttributes="Bold"
LineBreakMode="TailTruncation"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="Black"/>
<Label
TextColor="Black"
Grid.Column="2"
Text="Unit"
LineBreakMode="TailTruncation"
FontAttributes="Bold"
HorizontalOptions="Center"
VerticalOptions="Center"
/>
<Label
Grid.Column="3"
Text="Qty"
LineBreakMode="TailTruncation"
FontAttributes="Bold"
HorizontalOptions="Center"
TextColor="Black"
VerticalOptions="Center"
/>
<Label
TextColor="Black"
Grid.Column="4"
Text="U.Price"
LineBreakMode="TailTruncation"
FontAttributes="Bold"
HorizontalOptions="Center"
VerticalOptions="Center"
/>
</Grid>
</CollectionView.Header>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="1" ColumnSpacing="1" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<Label HorizontalOptions="Center"
Grid.Column="0"
TextColor="Black"
Text="{Binding itemcode}"
VerticalOptions="Center"
LineBreakMode="TailTruncation" />
<Label
Grid.Column="1"
VerticalOptions="Center"
HorizontalOptions="Center"
TextColor="Black"
Text="{Binding name}"
LineBreakMode="TailTruncation" />
<Label
Grid.Column="2"
TextColor="Black"
Text="{Binding itemsunitcode}"
LineBreakMode="TailTruncation"
VerticalOptions="Center"
HorizontalOptions="Center"
FontAttributes="Italic"
/>
<Label
TextColor="Black"
Grid.Column="3"
VerticalOptions="Center"
HorizontalOptions="Center"
Text="{Binding currentQuantity}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
/>
<Label
Grid.Column="4"
TextColor="Black"
Text="{Binding CostPrice}"
LineBreakMode="TailTruncation"
VerticalOptions="Center"
HorizontalOptions="Center"
FontAttributes="Italic"
/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<StackLayout VerticalOptions="EndAndExpand" HorizontalOptions="FillAndExpand" Orientation="Horizontal" BackgroundColor="#ffc40c">
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckcol">
<Image Margin="0,10,0,10" x:Name="imgAdd" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="del" Style="{StaticResource ButtonNavigationBarLabelStyle}" x:Name="col_add_remove"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckfilter">
<Image Margin="0,10,0,10" x:Name="imgfilter" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Filter" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckshare">
<Image Margin="0,10,0,10" x:Name="imgshare" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Share" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
i tried adding the content view code at the beginning of the collection view code, but it doesn't appear in the place intended. i want it to appear like an alert on top of the collection view layout and in the middle of the screen. this is the code of the pdf generation:
shareTap.Tapped += (sender, e) =>
{
popupLoadingView.IsVisible = true;
activityIndicator.IsRunning = true;
requestPermission();
};
async public void requestPermission()
{
var newstatus= Plugin.Permissions.Abstractions.PermissionStatus.Unknown;
var status = Plugin.Permissions.Abstractions.PermissionStatus.Unknown;
status = await CrossPermissions.Current.CheckPermissionStatusAsync<StoragePermission>();
if (status != Plugin.Permissions.Abstractions.PermissionStatus.Granted)
{
newstatus = await CrossPermissions.Current.RequestPermissionAsync<StoragePermission>();
if (newstatus == Plugin.Permissions.Abstractions.PermissionStatus.Granted)
{
generatePdf();
}
}
else
{
generatePdf();
}
}
private void generatePdf()
{
try
{
PdfDocument document = new PdfDocument();
//Add a new PDF page.
PdfPage page = document.Pages.Add();
//Get the font file as stream.
Stream fontStream = typeof(MainPage).GetTypeInfo().Assembly.GetManifestResourceStream("isc_alphaApp.Assets.arial.ttf");
//Create a new PdfTrueTypeFont instance.
PdfTrueTypeFont font = new PdfTrueTypeFont(fontStream, 14);
//Create a new bold stylePdfTrueTypeFont instance.
PdfTrueTypeFont boldFont = new PdfTrueTypeFont(fontStream, 14, PdfFontStyle.Bold);
page.Graphics.DrawString("Items", boldFont, PdfBrushes.Black, PointF.Empty);
//Create PdfGrid.
PdfGrid pdfGrid = new PdfGrid();
List<items_display> list_pdf = new List<items_display>();
for (int i = 0; i < list_total.Count; i++)
{
list_pdf.Add(new items_display { Code = list_total[i].itemcode, Description = list_total[i].name, Unit = list_total[i].itemsunitcode, Qty = list_total[i].currentQuantity, Price = list_total[i].CostPrice });
}
//Add values to list
List<items_display> data = list_pdf;
//Add list to IEnumerable.
IEnumerable<items_display> dataTable = data;
PdfStringFormat format_eng = new PdfStringFormat();
format_eng.TextDirection = PdfTextDirection.LeftToRight;
format_eng.Alignment = PdfTextAlignment.Center;
//Assign data source.
pdfGrid.DataSource = dataTable;
pdfGrid.Headers[0].Cells[0].StringFormat = format_eng;
pdfGrid.Headers[0].Cells[1].StringFormat = format_eng;
pdfGrid.Headers[0].Cells[2].StringFormat = format_eng;
pdfGrid.Headers[0].Cells[3].StringFormat = format_eng;
pdfGrid.Headers[0].Cells[4].StringFormat = format_eng;
//Assign bold font to pdfGrid header.
pdfGrid.Headers[0].Style.Font = boldFont;
//Assign font to PdfGrid.
pdfGrid.Style.Font = font;
Regex regex = new Regex("[\u0600-\u06ff]|[\u0750-\u077f]|[\ufb50-\ufc3f]|[\ufe70-\ufefc]");
//Create String format with RTL text direction and center text alignment.
PdfStringFormat format = new PdfStringFormat();
format.TextDirection = PdfTextDirection.RightToLeft;
format.Alignment = PdfTextAlignment.Center;
for (int i = 0; i < data.Count; i++)
{
if (regex.IsMatch(data[i].Code))
{
pdfGrid.Rows[i].Cells[0].StringFormat = format;
}
else
{
pdfGrid.Rows[i].Cells[0].StringFormat = format_eng;
}
if (regex.IsMatch(data[i].Description))
{
pdfGrid.Rows[i].Cells[1].StringFormat = format;
}
else
{
pdfGrid.Rows[i].Cells[1].StringFormat = format_eng;
}
if (regex.IsMatch(data[i].Unit))
{
pdfGrid.Rows[i].Cells[2].StringFormat = format;
}
else
{
pdfGrid.Rows[i].Cells[2].StringFormat = format_eng;
}
pdfGrid.Rows[i].Cells[3].StringFormat = format_eng;
pdfGrid.Rows[i].Cells[4].StringFormat = format_eng;
}
//Assign string format to draw RTL text with center alsignment
//pdfGrid.Rows[0].Cells[1].StringFormat = format;
//pdfGrid.Rows[1].Cells[1].StringFormat = format;
//Draw grid to the page of PDF document.
pdfGrid.Draw(page, new Syncfusion.Drawing.PointF(0, 20));
String file_Path;
string path = DependencyService.Get<getpath>().path();
file_Path = System.IO.Path.Combine(path.ToString(), "items.pdf");
FileStream stream = new FileStream(file_Path, FileMode.Create);
document.Save(stream);
//Close the document
document.Close(true);
Share.RequestAsync(new ShareFileRequest
{
Title = "Share PDF",
File = new ShareFile(file_Path)
});
}
catch(Exception exp)
{
DisplayAlert("No Space", "Not Enough Storage!", "Okay");
}
}
The place where I try to make the content view visible doesn't seem to be right too because it is not displayed until the pdf is already generated. I want it to appear once the user clicks the button.
You would need to make some changes to make it work
AbsoluteLayour
or Grid
on your Inventory
page. Because they allow "Stacking" views one on top of the other. Also here you need to add your loading screen.If your popupLoadingView
is in another XAML, you need to add it to your page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local=" <Insert your namespace here"
x:Class="isc_alphaApp.Inventory">
<!-- Rest of your code-->
<ContentPage.Content>
<Grid>
<local:popupLoadingView IsTrue="False" x:name="popupLoadingView"/>
<StackLayout>
<!-- Your collectionView goes here-->
</StackLayout>
</Grid>
</ContentPage.Content>
After doing all the pdf work, remember to turn the Visibility to false
shareTap.Tapped += (sender, e) =>
{
popupLoadingView.IsVisible = true;
//Do all the work that you need
popupLoadingView.IsVisible=false;
}