Command Prompt (2)

Keywords: Xamarin.Forms, ScrollView, ScrollToAsync, PCL Storage, Command Prompt, Entry without Border Line, Blinking Cursor

I redeveloped Command Prompt (1) that emulates MS-DOS Command-Prompt-Like UI. In this App, command lines are simply added on ScrollView, the screen design is basically same as the Command Prompt (1). However, in the Command Prompt (1), I couldn’t make ScrollView size expansion and ScrollToAsync method work well, so I modified the App with techniques that I learned afterwards. Since PCL Storage is used for folder and file handling, the title of this App can be PCL Storage (3), the new version of PCL Storage (1) and (2), as well as Command Prompt (2).


A screen shot of the iOS Simullator just after launching the App.


MainPage.xaml
MainPage.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"
             xmlns:local="clr-namespace:CommandPrompt"
             x:Class="CommandPrompt.MainPage">

    <Grid x:Name="grid" RowSpacing="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- Title -->
        <StackLayout Grid.Row="0" BackgroundColor="Gray" 
                     Padding="0,0,0,1" HeightRequest="50">
            <StackLayout BackgroundColor="White" HeightRequest="50">
                <Label Text="Command Prompt Demo" 
                       Grid.Row="0" VerticalOptions="EndAndExpand"/>
            </StackLayout>
        </StackLayout>

        <!-- Buttons to control this App -->
        <StackLayout Grid.Row="1" Padding="0,0,0,1" BackgroundColor="Gray">
            <StackLayout Orientation="Horizontal" BackgroundColor="White">
                <Button x:Name="Button1"
                    Text="B1" Clicked="Button01"
                    WidthRequest="50" HeightRequest="25"
                    BorderWidth="1" Margin="3,3,0,3"/>
                <Button x:Name="Button2"
                    Text="B2" Clicked="Button02"
                    WidthRequest="50" HeightRequest="25"
                    BorderWidth="1" Margin="3,3,0,3"/>
                <Button x:Name="Button3"
                    Text="B3"
                    WidthRequest="50" HeightRequest="25"
                    BorderWidth="1" Margin="3,3,0,3"/>
                <Label x:Name="StatusLabel" Text="Status Label"
                   HorizontalOptions="EndAndExpand" VerticalOptions="Center"/>
            </StackLayout>
        </StackLayout>


        <!-- Command Prompt Console -->
        <ScrollView x:Name="ConsoleBack" Grid.Row="2" BackgroundColor="Gray" 
                    Padding="0" VerticalOptions="FillAndExpand" Scrolled="ConsoleBackScrolled">
            <StackLayout x:Name="Console" BackgroundColor="White" Spacing="0"
                         SizeChanged="GetConsoleSize">
                <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnTapConsole"/>
                </StackLayout.GestureRecognizers>
            </StackLayout>
        </ScrollView>

        <!-- File Editor -->
        <Grid x:Name="FileEditorGrid" Grid.Row="2" BackgroundColor="Gray" IsVisible="false" 
                          Padding="1" RowSpacing="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <!-- Title -->
            <Label x:Name="FileEditorTitle" BackgroundColor="White"
                                Grid.Row="0" Grid.Column="0"/>

            <!-- File Editor -->
            <Editor x:Name="FileEditor" BackgroundColor="White"
                    VerticalOptions="FillAndExpand" Keyboard="Plain"
                                Grid.Row="1" Grid.Column="0"/>

            <!-- Button for Save File and Cancel -->
            <StackLayout BackgroundColor="White" Grid.Row="2" Grid.Column="0">
                <StackLayout Orientation="Horizontal" HorizontalOptions="EndAndExpand">
                    <Button Text="Save" TextColor="Black" Clicked="SaveFile" HeightRequest="20"
                                        BackgroundColor="White" BorderWidth="1" />
                    <Button Text="Cancel" TextColor="Black" Clicked="CancelEditor" HeightRequest="20"
                                        BackgroundColor="White" BorderWidth="1" />
                </StackLayout>
            </StackLayout>
        </Grid>


        <!-- Monitor some variables for Debug -->
        <StackLayout x:Name="Debug" Grid.Row="3"
                     BackgroundColor="Gray" Padding="0,1,0,0">
            <StackLayout BackgroundColor="White">
                <Label x:Name="Label1" Text=" "/>
                <Label x:Name="Label2" Text=" "/>
                <Label x:Name="Label3" Text=" "/>
            </StackLayout>
        </StackLayout>

    </Grid>
</ContentPage>

The source code is also here.

Designed the screen layout with four rows and one column Grid.  From the upper row, App title, some Buttons to control somthing, main area displaying the command lines, and the bottom area is to show some variables for debugging. In the main area, the ScrollVew “ConsoleBack” are placed in the Grid that surrounds the StackLayout “Console.” The other Grid “FileEditorGrid” is also overlaid in the main area that shows the file editor. The IsVisible property of the “FileEditorGrid” is false initially, so it is pop-up dilplayed when the file editor is launched.





CommandInterpreter.cs
CommandInterpreter.cs
using System;
using System.Linq;
using System.Collections.Generic;

using Xamarin.Forms;

namespace CommandPrompt
{
    public partial class MainPage : ContentPage
    {

        class CommandLine        
        {
            // Prompt
            public string Prompt { get; set; }
            private Label promptlabel()
            {
                return new Label() { Text = Prompt,
                                     TextColor = Color.Blue };
            }
            public Label PromptLabel { get { return this.promptlabel(); } }


            // Command            
            public string Command { get { return CommandEntry.Text; } }
            private Label commandlabel = new Label() { Text = " " };
            public Label CommandLabel { get { return this.commandlabel; } }


            // Command Input
            private Entry commandentry = new Entry()
            {
                BackgroundColor = Color.Transparent,
                TextColor = Color.Transparent,
                HeightRequest = 0,      // Not to display this entry                
                Keyboard = Keyboard.Plain
            };
            public Entry CommandEntry { get { return this.commandentry; } }


            // StackLayout including all parts of Command Line
            private StackLayout promptcommand()
            {
                StackLayout s1 = new StackLayout()
                {
                    BackgroundColor = Color.Transparent,
                    Orientation = StackOrientation.Horizontal,
                    Children = { PromptLabel, CommandLabel }
                };
                StackLayout s2 = new StackLayout()
                {
                    Spacing = 0,
                    Children = { s1, CommandEntry }
                };

                return s2;
            }
            public StackLayout PromptCommand { get { return promptcommand(); } }


            // Blink Cursor and its Switch            
            public string BlinkString = "|";
            public bool BlinkOff { get; set; }


            // Solution Results
            public string Results { get; set; }
        }
        List<CommandLine> CommandLines = new List<CommandLine>();


        int ConsoleSizeChanged = 0;
        int TextInputed = 0;
        int TextInputCompleted = 0;

        double ConsoleWidth, ConsoleHeight;
        double ScrollWidth, ScrollHeight;



        //Get "Console" size properly and Scroll "Console" to the end        
        void GetConsoleSize(object sender, EventArgs args)
        {
            ConsoleWidth = Console.Width;
            ConsoleHeight = Console.Height;
            ScrollHeight = ConsoleBack.Height;

            // Scroll "Console" to the End
            // Make ScrollToAsync into Timer due to timing probelm(?)
            Device.StartTimer(TimeSpan.FromMilliseconds(1), () =>
            {
                ConsoleBack.ScrollToAsync(0, ConsoleHeight - ScrollHeight, false);
                return false;   // Timer Cycle is only one time
            });

        }



        // Add a new Command Input Line
        void AddPrompt(string prompt)
        {
            CommandLine commandLine = new CommandLine();

            commandLine.Prompt = prompt;
            Label comLabel = commandLine.CommandLabel;
            Entry comEntry = commandLine.CommandEntry;

            Console.Children.Add(commandLine.PromptCommand);
            CommandLines.Add(commandLine);


            // Add TextChanged & Completed Event on entry
            comEntry.TextChanged += InputChanged;
            comEntry.Completed += InputCompleted;

            comEntry.Focus();


            // Blink Cursor in Command Line
            Device.StartTimer(TimeSpan.FromMilliseconds(300), () =>
            {
                // If Text Inputed in Command Line, finish this Timer                
                bool NextTimerStart = !commandLine.BlinkOff;
                if (!NextTimerStart)
                {
                    // Not to let label be "|             "
                    if (comEntry.Text == null) comLabel.Text = "";

                    // Delete BlinkString
                    comLabel.Text = comEntry.Text;

                    return NextTimerStart;
                }

                // Toggle Cursor to Blink                
                if (commandLine.BlinkString == "|") commandLine.BlinkString = "";
                else commandLine.BlinkString = "|";

                comLabel.Text = comEntry.Text + commandLine.BlinkString;

                return NextTimerStart;
            });
        }        

        
        // Display the Input Command (entry.Text) as Label
        void InputChanged(object sender, EventArgs args)
        {
            Entry entry = (Entry)sender;

            CommandLines.Last().CommandLabel.Text = entry.Text;

            TextInputed++;
        }


        // When CR is entered, Execute the Input Command
        void InputCompleted(object sender, EventArgs args)
        {
            Entry entry = (Entry)sender;            

            CommandLines.Last().BlinkOff = true;

            CommandExecute(entry.Text);
            entry.IsEnabled = false;    // Not to focus the previous entry

            TextInputCompleted++;
        }


        void ConsoleBackScrolled(object sender, EventArgs args)
        {
            //Label3.Text = string.Format("Scroll Y = {0}, Scrolled Y = {1}",
            //                            ConsoleHeight - ScrollHeight,
            //                            ConsoleBack.ScrollY);
        }

    }
}

CommandLine class defined command prompt, command input and so on. The Entry “Command Entry” gets the text of command, but it is not displayed on the screen beause its HightRequest property is zero. The input command is transferred the Label “CommandLabel” through InputChanged event. This makes it possible to realize text input box without border line.
The timer in the “AddPrompt” method is to blink “|” at the end of command line to show command input waiting.
When Return key is pressed in command line, InputCompleted event is raised and the “CommandExecute” method is called.


MainPage.xaml.cs
MainPage.xaml.cs
using System;
using System.Linq;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace CommandPrompt
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            CreateRootFolder();

            AddPrompt(CurrentFolder.Path);

            // Just after launching the App, Entry.Focus() doesn't work like 
            // ScrollToAsync() due to timing probelm(?), so maake it into Timer 
            Device.StartTimer(TimeSpan.FromMilliseconds(1), () =>
            {
                CommandLines.Last().CommandEntry.Focus();
                return false;   // Timer Cycle is only one time
            });
            
        }

        
        // Focus Command Line, if Tap Console
        void OnTapConsole(object sender, EventArgs args)
        {
            CommandLines.Last().CommandEntry.Focus();
        }


        // Identify Input Command and Execute it
        async void CommandExecute(string command)
        {            
            string result = "";

            // Get the first three characters of command
            string com = command;
            if(command != null)
                if(command.Length>3)
                    com = command.Substring(0, 3);


            // Identify the command from the first three characters            
            switch (com)
            {
                case "":
                case null:
                    AddPrompt(CurrentFolder.Path);
                    return;

                case "dir":
                    result = dir();
                    break;

                case "pwd":
                    result = CurrentFolder.Path + "\n";
                    break;

                case "mkd":
                    result = await mkdir(command);
                    break;

                case "cd ":
                    result = await cd(command);
                    break;

                case "del":
                    result = await del(command);
                    break;                

                case "mor":
                    result = await more(command);
                    break;

                case "ed ":
                    result = await ed(command);
                    break;

                default:
                    result = "No Command" + "\n";
                    break;
            }

            // Display the Command Execute Result following the Command Line
            Console.Children.Add(new Label() { Text = result });

            // Store the result
            CommandLines.Last().Results = result;            

            // Add a new Command Line
            AddPrompt(CurrentFolder.Path);
            
        }


        // Display All Folders and Files
        string dir()
        {
            string result = "";
            Folder folder = CurrentFolder;

            foreach(Folder subfolder in folder.SubFolders)            
                result += string.Format("<DIR>  {0}\n", subfolder.Name);
            
            foreach(File file in folder.Files)            
                result += file.Name + "\n";
            
            return result;
        }


        // Make Directory
        async Task<string> mkdir(string command)
        {
            string result = " ";
            string name = "";
            Folder parent = CurrentFolder;

            if (command.Length < 6) return "Command Invalid";
            else if (command.Substring(0, 6) != "mkdir ")
                return "Command Invalid";
            else if (command.Substring(6) == "")
                return "No Folder Name";
            else name = command.Substring(6);

            Folder folder = new Folder()
            {
                Name = name,
                Parent = parent
            };

            // Check the existence of the IFolder corresponding to the Object "folder"
            bool IsExist = await ICheckFolderExist(name, parent.iFolder);
            if (IsExist) return name.ToString() + " already exists";

            folder.iFolder = await ICreateFolder(folder, parent.iFolder, false);
            parent.SubFolders.Add(folder);

            //Label3.Text = folder.iFolder.Name;

            return result;
        }

        // Change Directory
        async Task<string> cd(string command)
        {
            string result = " ";
            string name = "";

            if (command.Substring(3) == "")
                return "No Folder Name";
            else name = command.Substring(3);

            // Back to the Parent Folder
            if(name == "..")
            {
                if (CurrentFolder == LocalStorage) return "No Parent Folder";
                CurrentFolder = CurrentFolder.Parent;
                return result;
            }

            // Check the existence of the IFolder corresponding to the Object "folder"
            bool IsExist = await ICheckFolderExist(name, CurrentFolder.iFolder);
            if (!IsExist) return name + " doesn't exist";

            foreach(Folder folder in CurrentFolder.SubFolders)
            {
                if (folder.Name == name)
                {
                    CurrentFolder = folder;
                    break;
                }
            }

            return result;
        }

        // Delete a Folder or a File
        async Task<string> del(string command)
        {
            string result = " ";
            string name = "";

            if (command.Substring(0, 4) != "del ")
                return "Command Invalid";
            else if (command.Substring(4) == "")
                return "No Folder/File Name";
            else name = command.Substring(4);
            
            // Check the existence of the IFolder or the IFile
            bool IsExist1 = await ICheckFolderExist(name, CurrentFolder.iFolder);
            bool IsExist2 = await ICheckFileExist(name, CurrentFolder.iFolder);            

            if(IsExist1)        // Delete Folder
            {
                Folder DelFolder = new Folder();
                foreach(Folder folder in CurrentFolder.SubFolders)
                {
                    if(folder.Name==name)
                    {
                        await IDeleteFolder(folder.iFolder, folder.IParent);
                        DelFolder = folder;
                        break;
                    }
                }
                CurrentFolder.SubFolders.Remove(DelFolder);
            }
            else if(IsExist2)   // Delete File
            {
                File DelFile = new File();
                foreach (File file in CurrentFolder.Files)
                {
                    if (file.Name == name)
                    {
                        await IDeleteFile(file.iFile, file.IParent);
                        DelFile = file;
                        break;
                    }
                }
                CurrentFolder.Files.Remove(DelFile);                
            }
            else return name + " doesn't exist";

            return result;
        }


        // Display File Content
        async Task<string> more(string command)
        {
            //string result = " ";
            string name = "";
            Folder parent = CurrentFolder;

            if (command.Length < 5) return "Command Invalid";
            else if (command.Substring(0, 5) != "more ")
                return "Command Invalid";
            else if (command.Substring(5) == "")
                return "No File Name";
            else name = command.Substring(5);

            foreach (File file in parent.Files)            
                if (file.Name == name)                
                    return await IReadFile(file.iFile);                
            
            return "No such File";
        }

        // Edit File
        async Task<string> ed(string command)
        {
            string result = " ";
            string name = "";
            Folder parent = CurrentFolder;

            if (command.Substring(3) == "")
                return "No File Name";
            else name = command.Substring(3);

            // Check the existence of the File
            bool IsExist = await ICheckFileExist(name, parent.iFolder);

            if(IsExist)
            {
                foreach(File file in parent.Files)
                {
                    if (file.Name == name)
                    {                        
                        FileEditor.Text = await IReadFile(file.iFile);
                        CurrentFile = file;
                        break;
                    }
                }
            }
            else
            {
                File file = new File()
                {
                    Name = name,
                    Parent = parent
                };
                file.iFile = await ICreateFile(file, parent.iFolder);
                parent.Files.Add(file);

                CurrentFile = file;
            }

            FileEditorTitle.Text = "File Name: " + CurrentFile.Name;            
            FileEditorGrid.IsVisible = true;

            // Editor.Focus() doesn't work due to timing probelm(?), 
            // so maake it into Timer 
            Device.StartTimer(TimeSpan.FromMilliseconds(1), () =>
            {
                FileEditor.Focus();
                return false;   // Timer Cycle is only one time
            });            

            return result;
        }
        
        // Buttons of FileEditor Menu: save File, cancel Editor
        void SaveFile(object sender, EventArgs e)
        {
            // PCL Storage: Write content in IFile
            IWriteFile(CurrentFile.iFile, FileEditor.Text);
        }
        void CancelEditor(object sender, EventArgs e)
        {
            FileEditorGrid.IsVisible = false;
            CommandLines.Last().CommandEntry.Focus();
        }




        void Button01(object sender, EventArgs args)
        {
            
        }

        void Button02(object sender, EventArgs args)
        {            
            IDleteAllObjects(LocalStorage);
            CommandLines.Last().CommandEntry.Focus();
        }
    }
}

The “CommandExecute” method identifies which command has been executed from the first three characters of the command text. All of the commands are familiar in MS-DOS. The command of “mkdir”, “del” etc. call some methods of PCL Storage.


PCLStorage.cs
PCLStorage.cs
using System.Collections.Generic;
using System.Threading.Tasks;

using Xamarin.Forms;
using PCLStorage;

namespace CommandPrompt
{
    public partial class MainPage : ContentPage
    {
        // Set LocalStorage
        //    Name: ILocalStorage.Name, Path: ILocalStorage.Path
        static IFolder ILocalStorage = FileSystem.Current.LocalStorage;

        // Create Folder class of LocalStorage and RootFolder
        static Folder LocalStorage = new Folder()
        {
            Name = "LocalStorage",
            Parent = null,
            iFolder = ILocalStorage
        };
        static Folder RootFolder = new Folder()
        {
            Name = "RootFolder",
            Parent = LocalStorage
        };
        Folder CurrentFolder = RootFolder;


        // Folsder class
        class Folder
        {
            public string Name { get; set; }    // Folder Name           
            public Folder Parent { get; set; }  // Parent Folder
            private string path()
            {
                if (Name == "LocalStorage") return "LocalStorage>";
                else if (Name == "RootFolder") return ">";
                else if (Parent == RootFolder) return Name + ">";
                else return Parent.Path + Name + ">";
            }
            public string Path { get { return path(); } } // Directory Path

            // SubFolder and File List in this Folder
            public List<Folder> SubFolders = new List<Folder>();
            public List<File> Files = new List<File>();
            
            public int NumChildren  // Number of Children in this folder
            {
                get { return SubFolders.Count + Files.Count; }
            }            
            public string NumChildrenText        // Text of NoChildren
            {
                get { return "(" + NumChildren.ToString() + ")"; }
            }
            
            // IFolder of this Folder and its Parent Folder
            public IFolder iFolder { get; set; }
            public IFolder IParent { get { return Parent.iFolder; } } // Parent IFolder

        }

        // File class
        class File
        {
            public string Name { get; set; }    // File Name
            public Folder Parent { get; set; }  // Parent Folder
            
            public string Path { get { return Parent.Path; } } // Directory Path

            // IFile of this File and its Parent Folder
            public IFile iFile { get; set; }
            public IFolder IParent { get { return Parent.iFolder; } } // Parent IFolder
        }
        File CurrentFile = new File();

        // Create the RootFolder in LocalStorage
        async void CreateRootFolder()
        {
            CurrentFolder = RootFolder;

            // PCL Storage: Create the IFolder of RootFolder (RootFolder.iFolder)
            RootFolder.iFolder = await ICreateFolder(RootFolder, ILocalStorage);
            LocalStorage.SubFolders.Add(RootFolder);
        }


        // Check existence of IFolder "name" in IFolder "iparent"
        async Task<bool> ICheckFolderExist(string name, IFolder iparent)
        {
            ExistenceCheckResult IsExist = await iparent.CheckExistsAsync(name);
            if (IsExist == ExistenceCheckResult.FolderExists) return true;
            return false;
        }

        

        // Create a new IFolder of the Folder "folder" in the IFolder "iparent"
        async Task<IFolder> ICreateFolder(Folder folder, IFolder iparent, bool replace = false)
        {            
            if(replace) return await iparent.CreateFolderAsync(folder.Name, CreationCollisionOption.ReplaceExisting);
            else return await iparent.CreateFolderAsync(folder.Name, CreationCollisionOption.GenerateUniqueName);     
        }      



        // Delete the IFolder "ifolder" in the IFolder "iparent"
        async Task IDeleteFolder(IFolder ifolder, IFolder iparent)
        {
            // Check the existence of the IFolder corresponding to the Object "folder"
            bool IsExist = await ICheckFolderExist(ifolder.Name, iparent);
            if (!IsExist)
            {
                await DisplayAlert("", ifolder.Name.ToString() + " doesn't exist", "OK");
                return;
            }

            await ifolder.DeleteAsync();
        }

        // Delete all of Folders and Files in the Folder "folder"
        async void IDleteAllObjects(Folder folder)
        {
            // Get ALl IFolders and IFiles in the Folder "folder"
            IList<IFolder> ifolders = await folder.iFolder.GetFoldersAsync();
            IList<IFile> ifiles = await folder.iFolder.GetFilesAsync();

            // Delete All IFolders
            foreach (IFolder ifolder in ifolders)
            {
                await ifolder.DeleteAsync();
            }

            // Delete All IFiles
            foreach (IFile ifile in ifiles)
            {
                await ifile.DeleteAsync();
            }

            // Delete All Folders & Files
            folder.SubFolders.Clear();
            folder.Files.Clear();

            // Recreate the new RootFolder
            CreateRootFolder();
        }


        // Get All IFolders in the IFolder "iparent"
        async Task<IList<IFolder>> IGetFolders(IFolder iparent)
        {
            return await iparent.GetFoldersAsync();
        }

        // Check existence of IFile "name" in IFolder "iparent"
        async Task<bool> ICheckFileExist(string name, IFolder iparent)
        {
            ExistenceCheckResult IsExist = await iparent.CheckExistsAsync(name);
            if (IsExist == ExistenceCheckResult.FileExists) return true;
            return false;
        }

        //Create a new IFile of the File "file" in the IFolder "iparent" 
        //  (If the IFile already exists, open it.)
        async Task<IFile> ICreateFile(File file, IFolder iparent)
        {
            return await iparent.CreateFileAsync(file.Name, CreationCollisionOption.ReplaceExisting);
        }


        // Delete IFile "ifile" in IFolder "iparent"
        async Task IDeleteFile(IFile ifile, IFolder iparent)
        {
            // Check the existence of "file"
            bool IsExist = await ICheckFileExist(ifile.Name, iparent);
            if (!IsExist)
            {
                await DisplayAlert("", ifile.Name.ToString() + " doesn't exist", "OK");
                return;
            }

            await ifile.DeleteAsync();     // Delete the IFile "file"
        }

        

        // Get All IFiles in in the IFolder "iparent"
        async void IGetFiles(IFolder iparent)
        {
            IList<IFile> ifiles = await iparent.GetFilesAsync();
        }

        // Write "content" to IFile "ifile"
        async void IWriteFile(IFile ifile, string content)
        {
            await ifile.WriteAllTextAsync(content);
        }

        // Read all text of IFile "ifile"
        async Task<string> IReadFile(IFile ifile)
        {
            string content = await ifile.ReadAllTextAsync();
            return content;
        }

        /*
        // Open IFile corresponding to the Object "file", 
        //          and set its content in the Editor "editor"
        async void IOpenFile(Object file, Editor editor)
        {
            string content = await (file.iFile).ReadAllTextAsync();
            editor.Text = content;
        }
        */

        // Get All IFolders and IFiles in IFolder "parent"
        async void IGetAllObjects(IFolder parent)
        {


            await DisplayAlert("", "Get All IFolders and IFiles in parent", "OK");
        }

        // Copy, Cut, Paste IFolder
        async void ICopyFolder()
        {
            await DisplayAlert("", "Copy IFolder", "OK");
        }
        async void ICutFolder()
        {
            await DisplayAlert("", "Cut IFolder", "OK");
        }
        async void IPasteFolder()
        {
            await DisplayAlert("", "Paste IFolder", "OK");
        }

        // Copy, Cut, Paste IFile
        async void ICopyFile()
        {
            await DisplayAlert("", "Copy IFile", "OK");
        }
        async void ICutFile()
        {
            await DisplayAlert("", "Cut IFile", "OK");
        }
        async void IPasteFile()
        {
            await DisplayAlert("", "Paste IFile", "OK");
        }
    }
}

The methods for PCL Storage is not so different from the ones of PCLStorage (2). The arguments of some methods are changed. And the “Folder” and “File” class are newly defined, and they make it easier to refer some properties.

A movie showing this App running.  You can get the original movie file from here (in "movie" folder). Since the PCL Storage is used in this App, folders and files are actually created in the LocalStorage of the PC in which the iOS simulator is running. So the movie also shows the LocalStorage folder.



Finally, I know that Command-Prompt-Like UI is not suitable for mobile application, but this is also my training!





コメント

このブログの人気の投稿

Get the Color Code from an Image Pixel

PCL Storage (1)

Optimal Rectangle Packing