diff --git a/Console/Services/ConsoleUIBindings.cs b/Console/Services/ConsoleUIBindings.cs index eb8d925..933a2be 100644 --- a/Console/Services/ConsoleUIBindings.cs +++ b/Console/Services/ConsoleUIBindings.cs @@ -33,7 +33,23 @@ public override Task PromptUserAsync(string Title, string Message, if (!string.IsNullOrWhiteSpace(SecondaryButtonText)) { - result = ConsoleHelpers.PromptYesNo($"{PrimaryButtonText}/{SecondaryButtonText}?") ? result = DialogResult.Primary : DialogResult.Secondary; + Console.WriteLine($"{PrimaryButtonText}/{SecondaryButtonText}?" + " (1/2)"); + while (true) + { + var res = Console.ReadKey(); + if (res.Key == ConsoleKey.D1) + { + Console.WriteLine(); + result = DialogResult.Primary; + break; + } + else if (res.Key == ConsoleKey.D2) + { + Console.WriteLine(); + result = DialogResult.Secondary; + break; + } + } } else { diff --git a/Core/Models/FileSystem/Containers/CoreFolderContainer.cs b/Core/Models/FileSystem/Containers/CoreFolderContainer.cs index 5551fa4..75a3629 100644 --- a/Core/Models/FileSystem/Containers/CoreFolderContainer.cs +++ b/Core/Models/FileSystem/Containers/CoreFolderContainer.cs @@ -51,19 +51,6 @@ public override Task DeleteAsync() return Task.FromResult(success); } - public override async Task GetFileAsync(string FileName) - { - var files = await GetFilesAsync(); - var file = files.FirstOrDefault(item => item.Name == FileName); - - return file; - } - - public override Task GetFolderAsync(string FolderName) - { - return CreateFolderAsync(FolderName); - } - public override Task> GetFoldersAsync() { var folders = Folder.GetDirectories().Select(item => new CoreFolderContainer(item)).ToList(); diff --git a/NETCore/Models/Settings/CoreSettingsContainer.cs b/NETCore/Models/Settings/CoreSettingsContainer.cs index 3df935e..1a61422 100644 --- a/NETCore/Models/Settings/CoreSettingsContainer.cs +++ b/NETCore/Models/Settings/CoreSettingsContainer.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using PlatformBindings.Enums; using PlatformBindings.Models.FileSystem; using System.Collections.Generic; @@ -23,7 +24,7 @@ internal CoreSettingsContainer(CoreFolderContainer Directory, CoreSettingsContai private void CreateDirectory() { var parent = Parent as CoreSettingsContainer; - Directory = parent.Directory.CreateFolderAsync(Name).Result as CoreFolderContainer; + Directory = parent.Directory.CreateFolderAsync(Name, CreationCollisionOption.OpenIfExists).Result as CoreFolderContainer; } public void Clear() diff --git a/NETCore/NETCoreServices.cs b/NETCore/NETCoreServices.cs index 23b0954..3455288 100644 --- a/NETCore/NETCoreServices.cs +++ b/NETCore/NETCoreServices.cs @@ -7,8 +7,8 @@ public class NETCoreServices : AppServices { public NETCoreServices() : base(true, Enums.Platform.NETCore) { - UI = new CoreUIBindings(); IO = new CoreIOBindings(); + UI = new CoreUIBindings(); } public static bool UseGlobalAppData = true; diff --git a/NETCore/Services/CoreIOBindings.cs b/NETCore/Services/CoreIOBindings.cs index a1d68dd..d6576dc 100644 --- a/NETCore/Services/CoreIOBindings.cs +++ b/NETCore/Services/CoreIOBindings.cs @@ -12,6 +12,11 @@ namespace PlatformBindings.Services { public class CoreIOBindings : IOBindings { + public CoreIOBindings() + { + LocalSettings = new CoreSettingsContainer(GetSettingsCluster(), null); + } + public override bool SupportsRoaming => false; public override bool SupportsOpenFolderForDisplay => false; public override bool SupportsOpenFileForDisplay => false; @@ -19,12 +24,12 @@ public class CoreIOBindings : IOBindings public override IFutureAccessManager FutureAccess => null; public override FileSystemPickers Pickers => null; - public override ISettingsContainer LocalSettings { get; } = new CoreSettingsContainer(GetSettingsCluster(), null); + public override ISettingsContainer LocalSettings { get; } - private static CoreFolderContainer GetSettingsCluster() + private CoreFolderContainer GetSettingsCluster() { - var root = AppServices.IO.GetBaseFolder(PathRoot.Application); - var settings = root.CreateFolderAsync("Settings").Result as CoreFolderContainer; + var root = GetBaseFolder(PathRoot.Application); + var settings = root.CreateFolderAsync("Settings", CreationCollisionOption.OpenIfExists).Result as CoreFolderContainer; return settings; } diff --git a/PlatformBindingsFramework.sln b/PlatformBindingsFramework.sln index 2426464..ddc9bcc 100644 --- a/PlatformBindingsFramework.sln +++ b/PlatformBindingsFramework.sln @@ -27,7 +27,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformBindings-XamarinFor EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformBindings-NETCore", "NETCore\PlatformBindings-NETCore.csproj", "{0CA1BCF8-F846-4A13-A4C1-4624018B1852}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlatformBindings-SMB", "SMB\PlatformBindings-SMB.csproj", "{6F2B13E8-FC4F-49CB-AD27-3CCA3AFC0E1B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformBindings-SMB", "SMB\PlatformBindings-SMB.csproj", "{6F2B13E8-FC4F-49CB-AD27-3CCA3AFC0E1B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NETCore", "NETCore", "{7B5B14B7-0E13-425C-9951-CF4B8D62E283}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test-NETCore", "Test-NETCore\Test-NETCore.csproj", "{8D084D1C-3C66-49DC-B90A-8BA0A27248BA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -213,6 +217,22 @@ Global {6F2B13E8-FC4F-49CB-AD27-3CCA3AFC0E1B}.Release|x64.Build.0 = Release|Any CPU {6F2B13E8-FC4F-49CB-AD27-3CCA3AFC0E1B}.Release|x86.ActiveCfg = Release|Any CPU {6F2B13E8-FC4F-49CB-AD27-3CCA3AFC0E1B}.Release|x86.Build.0 = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|ARM.ActiveCfg = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|ARM.Build.0 = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|x64.ActiveCfg = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|x64.Build.0 = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|x86.ActiveCfg = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Debug|x86.Build.0 = Debug|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|Any CPU.Build.0 = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|ARM.ActiveCfg = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|ARM.Build.0 = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|x64.ActiveCfg = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|x64.Build.0 = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|x86.ActiveCfg = Release|Any CPU + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -223,6 +243,8 @@ Global {D75853E5-F084-4D29-BB6F-26C14CA16F64} = {5004EF8D-9B09-4468-BDE1-2F1455C2FAAE} {BEE63EBC-97B3-4215-A1A8-C6054C834238} = {1250BD7A-49BF-463E-A53F-B5B5A8AE787E} {B7A60FD7-AEB0-4FBB-90BF-3393996942BD} = {A51388C3-40E5-4DA4-AA2D-349D75E592DB} + {7B5B14B7-0E13-425C-9951-CF4B8D62E283} = {5004EF8D-9B09-4468-BDE1-2F1455C2FAAE} + {8D084D1C-3C66-49DC-B90A-8BA0A27248BA} = {7B5B14B7-0E13-425C-9951-CF4B8D62E283} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F29D3568-CA96-478E-B0F4-76698467FEF6} diff --git a/Test-NETCore/Program.cs b/Test-NETCore/Program.cs new file mode 100644 index 0000000..b621087 --- /dev/null +++ b/Test-NETCore/Program.cs @@ -0,0 +1,24 @@ +using PlatformBindings; +using PlatformBindings.ConsoleTools; + +namespace Test_NETCore +{ + internal class Program + { + public static NETCoreServices Services { get; private set; } + + private static void Main(string[] args) + { + Services = new NETCoreServices(); + ConsoleHelpers.SystemWriteLine("Hello World!"); + Init(); + ConsoleHelpers.PreventClose(); + } + + private static async void Init() + { + var result = await AppServices.UI.PromptUserAsync("Hello", "This is an Example", "Opt1", "Opt2"); + ConsoleHelpers.SystemWriteLine("Result: " + result); + } + } +} \ No newline at end of file diff --git a/Test-NETCore/Test-NETCore.csproj b/Test-NETCore/Test-NETCore.csproj new file mode 100644 index 0000000..8fa131c --- /dev/null +++ b/Test-NETCore/Test-NETCore.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + diff --git a/TestApps/Android/Test-Android/MainActivity.cs b/TestApps/Android/Test-Android/MainActivity.cs index 9deb0b4..6b2b654 100644 --- a/TestApps/Android/Test-Android/MainActivity.cs +++ b/TestApps/Android/Test-Android/MainActivity.cs @@ -3,18 +3,14 @@ using Test_Android.Views; using PlatformBindings; using PlatformBindings.Activities; +using PlatformBindings.Models.Settings; namespace Test_Android { [Activity(Label = "Test_Android", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : PlatformBindingActivity { - public static AndroidAppServices Services { get; private set; } - - public MainActivity() - { - Services = new AndroidAppServices(true); - } + public static AndroidAppServices Services { get; private set; } = new AndroidAppServices(true); protected override void OnCreate(Bundle bundle) { diff --git a/_docs/GettingStarted.md b/_docs/GettingStarted.md index e59d038..e69967f 100644 --- a/_docs/GettingStarted.md +++ b/_docs/GettingStarted.md @@ -1 +1,29 @@ -boop +# Getting Started with the Platform Bindings Framework + +## Initialisation + +In order to be able to use this Framework, you must first Initalise the AppServices Class at your Application's Startup. This must be in your App's Project, as it requires the Project's Platform. + +To see how to Initialise your Platform, see: +* [UWP](Platform/UWP/UWPRemarks.md#Getting-Started) +* [Android](Platform/Android/AndroidRemarks.md#Getting-Started) +* [Xamarin Forms](Platform/XamarinForms/XamarinFormsRemarks.md) +* [NETCore](Platform/NETCore/NETCoreRemarks.md#Getting-Started) + +### Things to be aware of + +Due to AppServices being Initialised after Static Construction, be wary of `AppSettings`, and other Settings Classes that try to Access AppServices.IO.LocalSettings or AppServices.IO.RoamingSettings. These will cause and exception if that is the case. + +Instead use a static Property with a Getter to construct the Property, only when needed. This should also be better for memory usage, as it allows the Garbage Collector to clean up the Object when finished manipulation. As well as update values when they change from other sources. + +**Use:** +```c# +public static AppSetting ExampleToggleSetting => new AppSetting(); +``` + +**Instead of:** +```C# +public static AppSetting ExampleToggleSetting = new AppSetting(); +``` + +While the latter might work, if the Static Property is constructed before AppServices, it will cause an Exception. \ No newline at end of file diff --git a/_docs/Platform/Android/AndroidRemarks.md b/_docs/Platform/Android/AndroidRemarks.md index e69de29..a77a632 100644 --- a/_docs/Platform/Android/AndroidRemarks.md +++ b/_docs/Platform/Android/AndroidRemarks.md @@ -0,0 +1,37 @@ +# PlatformBindings-Android Remarks + +## Getting Started + +To use the Android Platform Library, you must first have the `PlatformBindings-Android` Package installed. + +### Activity Inheritance + +In order to use all of PlatformBindings-Android's Functionality, you must have an Activity that is compatible with the ActivityHandler, this can be achieved multiple ways for different Reasons. + +You can Inherit your Activity from `PlatformBindingActivity`, this is a Super Class of `Activity`, where Overriden methods handoff to the ActivityHandler. + +You can Inherit your Activity from `PlatformBindingCompatActivity`, this is a Super Class of `Android.Support.V7.App.AppCompatActivity`, where Overriden methods handoff to the ActivityHandler. + +If you already have your own Activity Super Class, or you inherit from another library, such as MVVMCross, then you can Override the Required Methods yourself to create your own PlatformBinding Supported Activity. + +See [here](https://github.com/WilliamABradley/PlatformBindingsFramework/blob/master/Android/Activities/PlatformBindingActivity.cs) for an example Implementation of an ActivityHandler handoff, Activtiy Super Class. + +### Initialisation + +In your First Activity, Create the AppServices Class Object either in the Constructor. It **MUST** be Constructed before `base.OnCreate(Bundle)` is called, as that is when Activity Registration begins. + +```C# +public class MainActivity : PlatformBindingActivity +{ + public static AndroidAppServices Services { get; private set; } = new AndroidAppServices(true); + + + protected override void OnCreate(Bundle bundle) + { + // Build App Services before calling base, to allow binding. + base.OnCreate(bundle); + StartActivity(typeof(Shell)); + Finish(); + } +} +``` \ No newline at end of file diff --git a/_docs/Platform/NETCore/NETCoreRemarks.md b/_docs/Platform/NETCore/NETCoreRemarks.md new file mode 100644 index 0000000..f049a06 --- /dev/null +++ b/_docs/Platform/NETCore/NETCoreRemarks.md @@ -0,0 +1,18 @@ +# PlatformBindings-NETCore Remarks + +## Getting Started + +To use the NETCore Platform Library, you must first have the `PlatformBindings-NETCore` Package installed. Then Create the AppServices Class Object in your Applications `static void Main(string[] args)` Method. +This can't be created Statically, as any Calls in the Main Method will come before Static Initialisation. + +```C# +internal class Program +{ + public static NETCoreServices Services { get; private set; } + + private static void Main(string[] args) + { + Services = new NETCoreServices(); + } +} +``` \ No newline at end of file diff --git a/_docs/Platform/UWP/UWPRemarks.md b/_docs/Platform/UWP/UWPRemarks.md index e69de29..299e4fa 100644 --- a/_docs/Platform/UWP/UWPRemarks.md +++ b/_docs/Platform/UWP/UWPRemarks.md @@ -0,0 +1,58 @@ +# PlatformBindings-UWP Remarks + +## Getting Started + +To use the UWP Platform Library, you must first have the `PlatformBindings-UWP` Package installed. Then in your Application Class (App.xaml.cs), Create the AppServices Class Object either in the Constructor or Statically. + +```C# +public static UWPAppServices Services = new UWPAppServices(true); +``` + +Due to UWP's Design, the Dispatcher isn't available yet, so you will need to attach the Dispatcher when it becomes available, such as in the `OnLaunched` Method. Make sure you don't call any AppServices.UI methods before Attaching the Dispatcher. + +After Attaching the Dispatcher is the best time to load any PlatformBindings extensions. Such as PlatformBindings-SMB. + +```C# +/// +/// Invoked when the application is launched normally by the end user. Other entry points +/// will be used such as when the application is launched to open a specific file. +/// +/// Details about the launch request and process. +protected override void OnLaunched(LaunchActivatedEventArgs e) +{ + Frame rootFrame = Window.Current.Content as Frame; + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == null) + { + // Create a Frame to act as the navigation context and navigate to the first page + rootFrame = new Frame(); + Services.AttachDispatcher(rootFrame.Dispatcher); + Tests.Preparation.Prepare(); + + rootFrame.NavigationFailed += OnNavigationFailed; + + if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) + { + //TODO: Load state from previously suspended application + } + + // Place the frame in the current Window + Window.Current.Content = rootFrame; + } + + if (e.PrelaunchActivated == false) + { + if (rootFrame.Content == null) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame.Navigate(typeof(MainPage), e.Arguments); + } + // Ensure the current window is active + Window.Current.Activate(); + } +} +``` \ No newline at end of file