PCL Storage (1)

In the sample programs of ListView (1) and (2), new book titles can be added to the book list, so I naturally wanted to build the new function to save the book list.

I found that there are some ways to save data processed in App.

  • Store data in Cloud, such as Azure and OneDrive
  • Link with Web service
  • Use local SQLite database
  • Use the file system plugin, PCL Storage
  • Dictionary Properties(?)
Cloud or Web service is the best choice to save various type of data, but it will be necessary to save data in device. So, firstly, I started to study PCL Storage.

MainPage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" 
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        xmlns:local="clr-namespace:PCLStrg;assembly=PCLStrg" 
        x:Class="PCLStrg.MainPage">

    <!-- 1st tabbed page: Folder I/O -->
    <local:FolderIO />

    <!-- 2nd tabbed page: File I/O -->
    <local:FileIO />

</TabbedPage>
(The source code is also here.)
This sample App is composed of two tabbed pages, and processing example of folder and file I/O has been implemented to the pages respectively.

MainPage.xaml.cs
using Xamarin.Forms;

namespace PCLStrg
{
    public partial class MainPage : TabbedPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
}


App.xaml.cs
using Xamarin.Forms;

namespace PCLStrg
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            //MainPage = new MainPage();
            MainPage = new NavigationPage(new MainPage());
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}


I explain how to build folder and file I/O below.

FolderIO.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="PCLStrg.FolderIO" Title="Folder I/O" Icon="Folder.png">

    <ContentPage.Content>
        <StackLayout Margin="0, 30, 0, 50">

            <Label Text="PCL Storage Folder and File I/O Sample App" />
            <Label Text="  --- Folder I/O ---" />

            <!-- Display Current Directory -->
            <Button Text="RootFolder Info." Clicked="DisplayRootFolder" HorizontalOptions="Start" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />

            <!-- Create a new Folder -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Create Folder" Clicked="CreateFolder" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1">
                    <!-- Enable Button, if Entry gets text input -->
                    <Button.Triggers>
                        <DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference EntCreateFolder}, Path=Text.Length}" Value="0">
                            <Setter Property="IsEnabled" Value="False" />
                        </DataTrigger>
                    </Button.Triggers>
                </Button>
                <Entry x:Name="EntCreateFolder" Placeholder="Input SubFolder Name" Text="" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Check Folder Existence -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Check Folder" Clicked="CheckFolder" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <Entry x:Name="EntCheckFolder" Placeholder="Input SubFolder Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Delete Folder -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Delete Folder" Clicked="DeleteFolder" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <Entry x:Name="EntDeleteFolder" Placeholder="Input SubFolder Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Display All Folders -->
            <Button Text="Show Folders" Clicked="GetFolders" HorizontalOptions="Start" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />

            <!-- Display Folder I/O Results -->
            <Label Text="  --- Folder I/O Results ---" />
            <ListView x:Name="FolderIOResult" ItemTapped="TappedResultItem" HasUnevenRows="false" RowHeight="25"/>
            <Button Text="Clear Result in the above List" Clicked="ClearFolderIOResult" HorizontalOptions="Center" WidthRequest="250" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />

        </StackLayout>
    </ContentPage.Content>

    <!-- Change color, if Entry is focused -->
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Entry">
                <Style.Triggers>
                    <Trigger  TargetType="Entry" Property="IsFocused" Value="True">
                        <Setter Property="BackgroundColor" Value="Aqua" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

</ContentPage>

Get the current folder path, create new folders, check folders already exists, delete folders are implemented in this Folder I/O tabbed page. The results of the processing are displayed in the ListView set at the bottom of the page.

I used Trigger function on some Entry and Button control to enhance their effect.

FolderIO.xaml.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Xamarin.Forms;
using PCLStorage;

namespace PCLStrg
{
    public partial class FolderIO : ContentPage
    {
        public FolderIO()
        {
            InitializeComponent();
        }

        //Get Root Folder Path
        IFolder rootFolder = FileSystem.Current.LocalStorage;

        //
        //  Folder I/O
        //
        //Display Root Folder's Name and Path
        void DisplayRootFolder(object sender, EventArgs e)
        {
            string[] RootFolderInfo = new string[]
            {
                "Root Folder Name:",
                "       - " + rootFolder.Name,
                "Root Folder Path:",
                "       - " + rootFolder.Path
            };
            DisplayResult(FolderIOResult, RootFolderInfo);
        }


        //Create a new Folder
        async void CreateFolder(object sender, EventArgs e)
        {
            var Entry = EntCreateFolder;

            // Alert, if no Folder Name
            if (Entry.Text == null)
            {
                await DisplayAlert("Create Subfolder""Input Subfolder Name!""OK");
                return;
            }

            // Create a new Folder named in EntCreateSubFolder
            IFolder subfolder =
                await rootFolder.CreateFolderAsync(Entry.Text, CreationCollisionOption.OpenIfExists);
            await DisplayAlert("Create Subfolder", Entry.Text + " has been created successfully!""OK");
        }


        //Check Folder Existence
        async void CheckFolder(object sender, EventArgs e)
        {
            var Entry = EntCheckFolder;

            // Alert, if no Folder Name
            if (Entry.Text == null)
            {
                await DisplayAlert("Check Folder Result""Input Folder Name!""OK");
                return;
            }

            // Check Folder Existence entered in EntCheckSubFolder
            var subfolderExists = await rootFolder.CheckExistsAsync(Entry.Text);
            if (subfolderExists != ExistenceCheckResult.FolderExists)
            {
                await DisplayAlert("Check Folder Result", Entry.Text + " doesn't exist""OK");
                return;
            }
            await DisplayAlert("Check Folder Result", Entry.Text + " exists!""OK");
        }


        //Delete Folder
        async void DeleteFolder(object sender, EventArgs e)
        {
            var Entry = EntDeleteFolder;

            // Alert, if SubFolder Name was not entered
            if (Entry.Text == null)
            {
                await DisplayAlert("Delete Folder Result""Input Folder Name!""OK");
                return;
            }

            // Delete Folder entered in EntDeleteSubFolder
            var subfolderExists = await rootFolder.CheckExistsAsync(Entry.Text);
            if (subfolderExists != ExistenceCheckResult.FolderExists)
            {
                await DisplayAlert("Delete Folder Result", Entry.Text + " doesn't exist""OK");
                return;
            }
            IFolder subfolder = await rootFolder.GetFolderAsync(Entry.Text);
            await subfolder.DeleteAsync();
            await DisplayAlert("Delete Folder Result", Entry.Text + " has been deleted!""OK");
        }


        // Get & Display Folders list
        async void GetFolders(object sender, EventArgs e)
        {
            //Get the Folders list
            IList<IFolder> folders = await rootFolder.GetFoldersAsync();

            //Get all Folder name as string data
            IEnumerator foldersList = folders.GetEnumerator();
            int i = 0;
            string[] folderName = new string[10];
            folderName[i] = "Subfolders in the Root Folder:"; i++;
            while (foldersList.MoveNext())
            {
                IFolder val = (IFolder)foldersList.Current;
                folderName[i] = "     - " + val.Name;
                i++;
            }

            //The number of Folders
            folderName[i] = "//  " + folders.Count.ToString() + " subfolders";

            //Display Folder names and the number of them
            DisplayResult(FolderIOResult, folderName);
        }


        //
        //  Display & Clear Folder I/O Result
        //
        //Display the results in ListView
        void DisplayResult(ListView ListViewName, string[] result)
        {
            ListViewName.ItemsSource = result;
        }
        //Clear all the Folder I/O result
        void ClearFolderIOResult(object sender, EventArgs e)
        {
            FolderIOResult.ItemsSource = null;
        }
        //Display the tapped Folder
        void TappedResultItem(object sender, ItemTappedEventArgs e)
        {
            DisplayAlert("Item Tapped", e.Item.ToString(), "OK");
        }
    }
}

IFolder, async/await etc. were a little bit confusing, but I finally made the code shown above.
It was somewhat difficult to display folder list. I found that IEnumerator was useful to do it, and could successfully get folder names as text array data and show them in ListView. But I have not deeply understood IEnumerater yet, and I have to study it.

FileIO.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" 
    x:Class="PCLStrg.FileIO" Title="File I/O" Icon="File.png" >

    <ContentPage.Content>
        <StackLayout Margin="0, 30, 0, 30">

            <Label Text="PCL Storage Folder and File I/O Sample App" />
            <Label Text="  --- File I/O ---" />

            <!-- Create a new File -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Create New File" Clicked="CreateFile" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <Entry x:Name="EntCreateFile" Placeholder="Input File Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Check File Existence -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Check File" Clicked="CheckFile" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <Entry x:Name="EntCheckFile" Placeholder="Input File Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Delete File -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Delete File" Clicked="DeleteFile" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <Entry x:Name="EntDeleteFile" Placeholder="Input File Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Show All Files -->
            <Button Text="Show Files" Clicked="GetFiles" HorizontalOptions="Start" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />

            <!-- Additionally Write Content to File -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Write File" Clicked="WriteFile" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1">
                    <!-- Enable Button, if EntWriteFile_Content gets text input -->
                    <Button.Triggers>
                        <DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference EntWriteFile_Content}, Path=Text.Length}" Value="0">
                            <Setter Property="IsEnabled" Value="False" />
                        </DataTrigger>
                    </Button.Triggers>
                </Button>
                <StackLayout Margin="0, 0, 0, 0">
                    <Entry x:Name="EntWriteFile_FileName" Text="" Placeholder="Input File Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
                    <Entry x:Name="EntWriteFile_Content" Text="" Placeholder="Input Text" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" >
                        <!-- Enable Ent_WriteFile_Content, if EntWriteFile_FileName gets text input -->
                        <Entry.Triggers>
                            <DataTrigger TargetType="Entry" Binding="{Binding Source={x:Reference EntWriteFile_FileName}, Path=Text.Length}" Value="0">
                                <Setter Property="IsEnabled" Value="False" />
                            </DataTrigger>
                        </Entry.Triggers>
                    </Entry>
                </StackLayout>
            </StackLayout>

            <!-- Read File -->
            <StackLayout Orientation="Horizontal">
                <Button Text="Read File" Clicked="ReadFile" WidthRequest="150" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <Entry x:Name="EntReadFile" Placeholder="Input File Name" Keyboard="Text" HeightRequest="30" HorizontalOptions="FillAndExpand" />
            </StackLayout>

            <!-- Display File I/O Results -->
            <Label Text="  - - - File I/O Results - - -" />
            <!-- <ListView x:Name="FileIOResult" ItemTapped="TappedResultItem" RowHeight="25"> -->
            

            <ListView x:Name="FileIOResult" ItemTapped="TappedResultItem" RowHeight="25">

                <!-- Context Actions: MenuItem -->
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Label Text="{Binding .}" />
                            <ViewCell.ContextActions>
                                <MenuItem Clicked="MenuEdit" Text="Edit" CommandParameter="{Binding .}" />
                                <MenuItem Clicked="MenuDelete" Text="Delete" IsDestructive="true" CommandParameter="{Binding .}" />
                            </ViewCell.ContextActions>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>

            </ListView>
            <Button Text="Clear Result in the above List" Clicked="ClearFileIOResult" HorizontalOptions="Center" WidthRequest="250" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
        </StackLayout>
    </ContentPage.Content>

    <!-- Change color, if Entry is focused -->
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Entry">
                <Style.Triggers>
                    <Trigger  TargetType="Entry" Property="IsFocused" Value="True">
                        <Setter Property="BackgroundColor" Value="Aqua" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

</ContentPage>

In addition to create and delete files like folder I/O, read file contents and additionally write contents to file were also implemented. In display of file list, added MenuItem context actions, and move to the EditFile page explained later and delete file are available in it.

FileIO.xaml.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Xamarin.Forms;
using PCLStorage;

namespace PCLStrg
{
    public partial class FileIO : ContentPage
    {
        public FileIO()
        {
            InitializeComponent();
        }

        //Get Root Folder Path
        IFolder rootFolder = FileSystem.Current.LocalStorage;

        //
        //  File I/O
        //
        //Create a new File
        async void CreateFile(object sender, EventArgs e)
        {
            var Entry = EntCreateFile;

            // Alert, if no File Name
            if (Entry.Text == null)
            {
                await DisplayAlert("Create File""Input File Name!""OK");
                return;
            }

            // Create a new File named in EntCreateFile
            IFile newFile =
                await rootFolder.CreateFileAsync(Entry.Text, CreationCollisionOption.OpenIfExists);
            await DisplayAlert("Create File", Entry.Text + " has been created successfully!""OK");
        }


        //Check File Existence
        async void CheckFile(object sender, EventArgs e)
        {
            var Entry = EntCheckFile;

            // Alert, if no File name
            if (Entry.Text == null)
            {
                await DisplayAlert("Check File""Input File Name!""OK");
                return;
            }

            // Check File Existence entered in EntCheckFile
            var fileExists = await rootFolder.CheckExistsAsync(Entry.Text);
            if (fileExists != ExistenceCheckResult.FileExists)
            {
                await DisplayAlert("Check File", Entry.Text + " doesn't exist""OK");
                return;
            }
            await DisplayAlert("Check File", Entry.Text + " exists!""OK");
        }


        //Delete File
        async void DeleteFile(object sender, EventArgs e)
        {
            var Entry = EntDeleteFile;

            // Alert, if no File Name
            if (Entry.Text == null)
            {
                await DisplayAlert("Delete File""Input File Name!""OK");
                return;
            }

            // Delete File entered in EntDeleteSubFolder
            var fileExists = await rootFolder.CheckExistsAsync(Entry.Text);
            if (fileExists != ExistenceCheckResult.FileExists)
            {
                await DisplayAlert("Delete File", Entry.Text + " doesn't exist""OK");
                return;
            }
            IFile file = await rootFolder.GetFileAsync(Entry.Text);
            await file.DeleteAsync();
            await DisplayAlert("Delete File", Entry.Text + " has been deleted!""OK");
        }


        // Get & Display File list
        async void GetFiles(object sender, EventArgs e)
        {
            //Get File list
            IList<IFile> files = await rootFolder.GetFilesAsync();

            //Get all File Name as string data
            IEnumerator filesList = files.GetEnumerator();
            int i = 0;
            string[] fileName = new string[10];
            fileName[i] = "Files in the Root Folder:"; i++;
            while (filesList.MoveNext())
            {
                IFile val = (IFile)filesList.Current;
                fileName[i] = "     - " + val.Name;
                i++;
            }

            //The number of Files
            fileName[i] = "//  " + files.Count.ToString() + " files";

            //Display File names and the number of them
            DisplayResult(FileIOResult, fileName);
        }


        // Additionally Write text to File
        async void WriteFile(object sender, EventArgs e)
        {
            var Entry_FileName = EntWriteFile_FileName;
            var Entry_Content = EntWriteFile_Content;
            string content = "";

            // Alert, if no File Name
            if (Entry_FileName.Text == null)
            {
                await DisplayAlert("Check File""Input File Name!""OK");
                return;
            }

            // Check File Existence entered in EntWriteFile
            var fileExists = await rootFolder.CheckExistsAsync(Entry_FileName.Text);
            if (fileExists != ExistenceCheckResult.FileExists)
            {
                // Create&Write File or Quit App, if File doesn't exist 
                if (await DisplayAlert("Write File""File doesn' exist""Create?""No"))
                {
                    IFile file1 = await rootFolder.CreateFileAsync(Entry_FileName.Text, CreationCollisionOption.OpenIfExists);
                    await file1.WriteAllTextAsync(Entry_Content.Text);
                }
                return;
            }

            // Add new content to existing content
            IFile file = await rootFolder.CreateFileAsync(Entry_FileName.Text, CreationCollisionOption.OpenIfExists);
            content = await file.ReadAllTextAsync();
            await file.WriteAllTextAsync(content + Environment.NewLine + Entry_Content.Text);
        }


        //Read File
        async void ReadFile(object sender, EventArgs e)
        {
            var Entry = EntReadFile;
            string content = "";

            // Alert, if no File Name
            if (Entry.Text == null)
            {
                await DisplayAlert("Read File""Input File Name!""OK");
                return;
            }

            // Read File entered in EntReadFile
            var fileExists = await rootFolder.CheckExistsAsync(Entry.Text);
            if (fileExists != ExistenceCheckResult.FileExists)
            {
                await DisplayAlert("Delete File", Entry.Text + " doesn't exist""OK");
                return;
            }
            IFile file = await rootFolder.GetFileAsync(Entry.Text);
            content = await file.ReadAllTextAsync();
            await DisplayAlert("Read File", content, "OK");
        }


        //
        //  Edit & Delete File from Menu Context Actions
        //
        async void MenuEdit(object sender, EventArgs e)
        {
            var item = (MenuItem)sender;

            // Move EditFile page
            await Navigation.PushAsync(new EditFile(item.CommandParameter.ToString()));
        }
        async void MenuDelete(object sender, EventArgs e)
        {
            var item = (MenuItem)sender;
            IFile file = await rootFolder.GetFileAsync(item.CommandParameter.ToString().Remove(07));

            // Delete File
            await file.DeleteAsync();

            // Re-Display List
            GetFiles(nullnull);
            await DisplayAlert("Delete File", item.CommandParameter + " has been deleted!""OK");
        }


        //
        //  Display and Clear File I/O Result
        //
        //Display the results in ListView
        void DisplayResult(ListView ListViewName, string[] result)
        {
            ListViewName.ItemsSource = result;
        }
        //Clear all the File I/O result
        void ClearFileIOResult(object sender, EventArgs e)
        {
            FileIOResult.ItemsSource = null;
        }
        //Display the tapped File in EditFile page
        async void TappedResultItem(object sender, ItemTappedEventArgs e)
        {
            await Navigation.PushAsync(new EditFile(e.Item.ToString()));
        }
    }
}

By the way, text.Remove(m,n) is convenient to process string data, isn't it? And Environmental.NewLine seems to be a line feed code. There are many things I don't know!


EditFile.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" 
    x:Class="PCLStrg.EditFile">

    <ContentPage.Content>
        <StackLayout BackgroundColor="white" >

            <StackLayout Orientation="Horizontal" VerticalOptions="Center" >
                <Label Text="Tapped File:  " />
                <Label x:Name="TappedFileName" HeightRequest="25"/>
            </StackLayout>
            
            <!-- Edit File Contents -->
            <StackLayout BackgroundColor="gray" Padding="1"  Margin="20,0,0,0" HorizontalOptions="Start" WidthRequest="300" HeightRequest="300" >
                <Editor x:Name="FileContent" BackgroundColor="white" HorizontalOptions="Start" WidthRequest="300" HeightRequest="300" />
            </StackLayout>

            <StackLayout Orientation="Horizontal" VerticalOptions="Center" >
                <!-- Save File -->
                <Button Margin="20,0,0,0" Text="save" Clicked="SaveFile" HorizontalOptions="Start" WidthRequest="60" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <!-- not Save File -->
                <Button Margin="3,0,0,0" Text="don't save" Clicked="NotSaveFile" HorizontalOptions="Start" WidthRequest="100" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
                <!-- Close File -->
                <Button Margin="3,0,0,0" Text="close" Clicked="CloseFile" HorizontalOptions="Start" WidthRequest="60" HeightRequest="30" BorderColor="Blue" BorderWidth="1" />
            </StackLayout>
            
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

The tapped file in the file list of the previous FileIO page can be edited and saved in this page. Used a small technique to display a border line around the text input area of the Editor control.

EditFile.xaml.cs
using System;
using Xamarin.Forms;
using PCLStorage;

namespace PCLStrg
{
    public partial class EditFile : ContentPage
    {
        public EditFile(string filename)
        {
            InitializeComponent();

            // Get File Name tapped in the List
            TappedFileName.Text = filename.Remove(07);

            // Read File Contents and Bind Editor control
            ImportFile();
        }

        // Get Root Folder Path
        IFolder rootFolder = FileSystem.Current.LocalStorage;

        public string content0;

        // Read File Contents and Bind Editor Control
        async void ImportFile()
        {
            IFile file = await rootFolder.GetFileAsync(TappedFileName.Text);
            string content = await file.ReadAllTextAsync();
            content0 = content;
            FileContent.Text = content;
        }


        // Save File
        async void SaveFile(object sender, EventArgs e)
        {
            IFile file = await rootFolder.CreateFileAsync(TappedFileName.Text, CreationCollisionOption.OpenIfExists);
            await file.WriteAllTextAsync(FileContent.Text);
            await DisplayAlert("File Content", TappedFileName.Text + " has been saved successfully!""OK");
        }

        // not Save File
        async void NotSaveFile(object sender, EventArgs e)
        {
            IFile file = await rootFolder.CreateFileAsync(TappedFileName.Text, CreationCollisionOption.OpenIfExists);
            await file.WriteAllTextAsync(content0);
            await DisplayAlert("File Content", TappedFileName.Text + " has not been saved!""OK");
            await Navigation.PushAsync(new FileIO());
        }

        // Close File (Back to File I/O page)
        async void CloseFile(object sender, EventArgs e)
        {
            await Navigation.PushAsync(new FileIO());
        }
    }
}


Ran this sample App on iOS simulator:

The folder list are displayed in FolderIO page.


File IO page.


Editing file, Test1.txt, in the EditFile page.


As mentioned above, I studied various aspects of folder and file I/O of PCS Storage.





コメント

このブログの人気の投稿

Get the Color Code from an Image Pixel

Optimal Rectangle Packing