diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index 940794e..3c4efe2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.suo @@ -42,11 +40,10 @@ TestResult.xml [Rr]eleasePS/ dlldata.c -# .NET Core +# DNX project.lock.json project.fragment.lock.json artifacts/ -**/Properties/launchSettings.json *_i.c *_p.c @@ -113,10 +110,6 @@ _TeamCity* # DotCover is a Code Coverage Tool *.dotCover -# Visual Studio code coverage results -*.coverage -*.coveragexml - # NCrunch _NCrunch_* .*crunch*.local.xml @@ -150,7 +143,7 @@ publish/ *.azurePubxml # TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted -*.pubxml +#*.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to @@ -166,7 +159,7 @@ PublishScripts/ !**/packages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/packages/repositories.config -# NuGet v3's project.json files produces more ignorable files +# NuGet v3's project.json files produces more ignoreable files *.nuget.props *.nuget.targets @@ -199,6 +192,7 @@ ClientBin/ *.jfm *.pfx *.publishsettings +node_modules/ orleans.codegen.cs # Since there are multiple workflows, uncomment next line to ignore bower_components @@ -219,7 +213,6 @@ UpgradeLog*.htm # SQL Server files *.mdf *.ldf -*.ndf # Business Intelligence projects *.rdl.data @@ -234,10 +227,6 @@ FakesAssemblies/ # Node.js Tools for Visual Studio .ntvs_analysis.dat -node_modules/ - -# Typescript v1 declaration files -typings/ # Visual Studio 6 build log *.plg @@ -245,9 +234,6 @@ typings/ # Visual Studio 6 workspace options file *.opt -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -272,17 +258,4 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs +*.pyc \ No newline at end of file diff --git a/AMP.sln b/AMP.sln new file mode 100644 index 0000000..587bd46 --- /dev/null +++ b/AMP.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.16 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AMP", "AMP\AMP.csproj", "{3381EB7B-7266-440E-AE0F-E8CAD7376281}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|ARM.ActiveCfg = Debug|ARM + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|ARM.Build.0 = Debug|ARM + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|x64.ActiveCfg = Debug|x64 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|x64.Build.0 = Debug|x64 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|x86.ActiveCfg = Debug|x86 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Debug|x86.Build.0 = Debug|x86 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|Any CPU.Build.0 = Release|Any CPU + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|ARM.ActiveCfg = Release|ARM + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|ARM.Build.0 = Release|ARM + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|x64.ActiveCfg = Release|x64 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|x64.Build.0 = Release|x64 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|x86.ActiveCfg = Release|x86 + {3381EB7B-7266-440E-AE0F-E8CAD7376281}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AMP/AMP.csproj b/AMP/AMP.csproj new file mode 100644 index 0000000..580cc3a --- /dev/null +++ b/AMP/AMP.csproj @@ -0,0 +1,151 @@ + + + + + Debug + AnyCPU + {3381EB7B-7266-440E-AE0F-E8CAD7376281} + Library + Properties + AMP + AMP + en-US + UAP + 10.0.15063.0 + 10.0.10586.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + + + PackageReference + + + + + + + + + + + + + + + + + + + + + + 5.2.3 + + + 5.3.0 + + + 10.0.3 + + + + + + + 14.0 + + + + \ No newline at end of file diff --git a/AMP/Properties/AMP.rd.xml b/AMP/Properties/AMP.rd.xml new file mode 100644 index 0000000..e60065a --- /dev/null +++ b/AMP/Properties/AMP.rd.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/AMP/Properties/AssemblyInfo.cs b/AMP/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fd7c33e --- /dev/null +++ b/AMP/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AMP")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AMP")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/README.md b/AMP/README.md similarity index 100% rename from README.md rename to AMP/README.md diff --git a/AMP/Services/IAsyncInitialization.cs b/AMP/Services/IAsyncInitialization.cs new file mode 100644 index 0000000..739b06d --- /dev/null +++ b/AMP/Services/IAsyncInitialization.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AMP.Services +{ + public interface IAsyncInitialization + { + Task Initialization { get; } + } +} diff --git a/AMP/UX/Services/FrameNavigationService.cs b/AMP/UX/Services/FrameNavigationService.cs new file mode 100644 index 0000000..012466a --- /dev/null +++ b/AMP/UX/Services/FrameNavigationService.cs @@ -0,0 +1,224 @@ +// **************************************************************************** +// +// Copyright © GalaSoft Laurent Bugnion 2009-2016 +// +// **************************************************************************** +// Laurent Bugnion +// laurent@galasoft.ch +// 02.10.2014 +// GalaSoft.MvvmLight +// http://www.mvvmlight.net +// +// See license.txt in this solution or http://www.galasoft.ch/license_MIT.txt +// +// **************************************************************************** + +using GalaSoft.MvvmLight.Views; +using System; +using System.Collections.Generic; +using System.Linq; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace AMP.UX.Services +{ + /// + /// Windows 8 and Windows Phone Application 8.1 implementation of . + /// + + public class FrameNavigationService : INavigationService, INavigationServiceEx + { + ViewTarget _lastTarget; + Frame _subFrame; + /// + /// The key that is returned by the property + /// when the current Page is the root page. + /// + public const string RootPageKey = "-- ROOT --"; + + /// + /// The key that is returned by the property + /// when the current Page is not found. + /// This can be the case when the navigation wasn't managed by this NavigationService, + /// for example when it is directly triggered in the code behind, and the + /// NavigationService was not configured for this page type. + /// + public const string UnknownPageKey = "-- UNKNOWN --"; + + private readonly Dictionary _pagesByKey = new Dictionary(); + + /// + /// The key corresponding to the currently displayed page. + /// + public string CurrentPageKey + { + get + { + lock (_pagesByKey) + { + var frame = GetCurrentFrame(); + + if (frame.BackStackDepth == 0) + { + return RootPageKey; + } + + if (frame.Content == null) + { + return UnknownPageKey; + } + + var currentType = frame.Content.GetType(); + + if (_pagesByKey.All(p => p.Value.View != currentType)) + { + return UnknownPageKey; + } + + var item = _pagesByKey.FirstOrDefault( + i => i.Value.View == currentType); + + return item.Key; + } + } + } + + + public Frame SubFrame + { + get { return _subFrame; } + set { _subFrame = value; } + } + + + + + public bool CanGoBack + { + get + { + + var frame = this.GetCurrentFrame(); + if (frame != null) + return frame.CanGoBack; + + return false; + + } + } + + public bool RemoveBackEntry() + { + var frame = this.GetCurrentFrame(); + if (frame.CanGoBack) + { + frame.BackStack.RemoveAt(frame.BackStackDepth - 1); + return true; + } + + return false; + + } + + private Frame GetCurrentFrame() + { + if (_lastTarget == ViewTarget.MainFrame) + return (Frame)Window.Current.Content; + + return _subFrame; + } + + private Frame GetTargetFrame(ViewTarget target) + { + _lastTarget = target; + if (target == ViewTarget.MainFrame) + return (Frame)Window.Current.Content; + + return _subFrame; + } + + /// + /// Displays a new page corresponding to the given key. + /// Make sure to call the + /// method first. + /// + /// The key corresponding to the page + /// that should be displayed. + /// When this method is called for + /// a key that has not been configured earlier. + public void NavigateTo(string pageKey) + { + NavigateTo(pageKey, null); + } + + /// + /// Displays a new page corresponding to the given key, + /// and passes a parameter to the new page. + /// Make sure to call the + /// method first. + /// + /// The key corresponding to the page + /// that should be displayed. + /// The parameter that should be passed + /// to the new page. + /// When this method is called for + /// a key that has not been configured earlier. + public virtual void NavigateTo(string pageKey, object parameter) + { + lock (_pagesByKey) + { + if (!_pagesByKey.ContainsKey(pageKey)) + { + throw new ArgumentException( + string.Format( + "No such page: {0}. Did you forget to call NavigationService.Configure?", + pageKey), + "pageKey"); + } + var frame = GetTargetFrame(_pagesByKey[pageKey].Target); + + frame.Navigate(_pagesByKey[pageKey].View, parameter); + } + } + + + + /// + /// Adds a key/page pair to the navigation service. + /// + /// The key that will be used later + /// in the or methods. + /// The type of the page corresponding to the key. + public void Configure(string key, ViewInfo viewInfo) + { + lock (_pagesByKey) + { + if (_pagesByKey.ContainsKey(key)) + { + throw new ArgumentException("This key is already used: " + key); + } + + if (_pagesByKey.Any(p => p.Value.View == viewInfo.View)) + { + throw new ArgumentException( + "This type is already configured with key " + _pagesByKey.First(p => p.Value.View == viewInfo.View).Key); + } + + _pagesByKey.Add( + key, + viewInfo); + } + } + + public void GoBack() + { + var frame = GetCurrentFrame(); + + if (frame.CanGoBack) + { + frame.GoBack(); + } + + } + } +} diff --git a/AMP/UX/Services/FrameViewInfo.cs b/AMP/UX/Services/FrameViewInfo.cs new file mode 100644 index 0000000..5b2cafb --- /dev/null +++ b/AMP/UX/Services/FrameViewInfo.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AMP.UX.Services +{ + public enum ViewTarget + { + MainFrame, + SubFrame + } + public class ViewInfo + { + public Type View { get; set; } + public ViewTarget Target { get; set; } + } +} diff --git a/AMP/UX/Services/INavigationServiceEx.cs b/AMP/UX/Services/INavigationServiceEx.cs new file mode 100644 index 0000000..c7172e6 --- /dev/null +++ b/AMP/UX/Services/INavigationServiceEx.cs @@ -0,0 +1,18 @@ +using GalaSoft.MvvmLight.Views; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml.Controls; + +namespace AMP.UX.Services +{ + public interface INavigationServiceEx : INavigationService + { + Frame SubFrame { get; set; } + + bool CanGoBack { get; } + bool RemoveBackEntry(); + } +} diff --git a/AMP/ViewModels/AsyncViewModel.cs b/AMP/ViewModels/AsyncViewModel.cs new file mode 100644 index 0000000..cf1b127 --- /dev/null +++ b/AMP/ViewModels/AsyncViewModel.cs @@ -0,0 +1,37 @@ +using GalaSoft.MvvmLight; +using AMP.Services; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Core; + +namespace AMP.ViewModels +{ + + public abstract class AsyncViewModel : ViewModelBase, IAsyncInitialization, INavAware + { + private static CoreDispatcher _dispatcher; + + public Task Initialization { get { return InitializeAsync(); } } + + protected AsyncViewModel() :base() + { + Debug.WriteLine("AsyncViewModel ctor"); + + if (_dispatcher == null) + _dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; + } + + protected Task RunAsync(Action a) { + return _dispatcher.RunAsync(CoreDispatcherPriority.Normal, ()=> { a.Invoke(); }).AsTask(); + } + protected virtual async Task InitializeAsync() { } + + public virtual void Activate(object parameter) { } + + public virtual void Deactivate(object parameter) { } + } +} diff --git a/AMP/ViewModels/INavAware.cs b/AMP/ViewModels/INavAware.cs new file mode 100644 index 0000000..ac07d8f --- /dev/null +++ b/AMP/ViewModels/INavAware.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AMP.ViewModels +{ + public interface INavAware + { + void Activate(object parameter); + void Deactivate(object parameter); + } +} diff --git a/AMP/ViewModels/IVisualState.cs b/AMP/ViewModels/IVisualState.cs new file mode 100644 index 0000000..41bdba7 --- /dev/null +++ b/AMP/ViewModels/IVisualState.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AMP.ViewModels +{ + public class VisualStateEventArgs : EventArgs + { + public string NewState { get; set; } + + public VisualStateEventArgs() + { + + } + + public VisualStateEventArgs(string newState) + { + NewState = newState; + } + } + + public interface IVisualState + { + event EventHandler VisualStateChanged; + } +} diff --git a/AMP/ViewModels/NavAwareViewModel.cs b/AMP/ViewModels/NavAwareViewModel.cs new file mode 100644 index 0000000..f1e35b7 --- /dev/null +++ b/AMP/ViewModels/NavAwareViewModel.cs @@ -0,0 +1,18 @@ + +using GalaSoft.MvvmLight; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AMP.ViewModels +{ + public abstract class NavAwareViewModel : ViewModelBase, INavAware + { + public abstract void Activate(object parameter); + + public abstract void Deactivate(object parameter); + + } +} diff --git a/AMP/Views/AsyncUserControl.cs b/AMP/Views/AsyncUserControl.cs new file mode 100644 index 0000000..caa7070 --- /dev/null +++ b/AMP/Views/AsyncUserControl.cs @@ -0,0 +1,27 @@ +using AMP.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml.Controls; + +namespace AMP.Views +{ + public class AsyncUserControl : UserControl + { + public AsyncUserControl() : base() + { + this.Loaded += AsyncUserControl_Loaded; + } + + private async void AsyncUserControl_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + var vm = this.DataContext; + if (vm is AsyncViewModel) + { + await (vm as AsyncViewModel).Initialization; + } + } + } +} diff --git a/AMP/Views/Commands/ItemClickCommand.cs b/AMP/Views/Commands/ItemClickCommand.cs new file mode 100644 index 0000000..951e626 --- /dev/null +++ b/AMP/Views/Commands/ItemClickCommand.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace AMP.Views.Commands +{ + public static class ItemClickCommand + { + public static readonly DependencyProperty CommandProperty = + DependencyProperty.RegisterAttached("Command", typeof(ICommand), + typeof(ItemClickCommand), new PropertyMetadata(null, OnCommandPropertyChanged)); + + public static void SetCommand(DependencyObject d, ICommand value) + { + d.SetValue(CommandProperty, value); + } + + public static ICommand GetCommand(DependencyObject d) + { + return (ICommand)d.GetValue(CommandProperty); + } + + private static void OnCommandPropertyChanged(DependencyObject d, + DependencyPropertyChangedEventArgs e) + { + var control = d as ListViewBase; + if (control != null) + control.ItemClick += OnItemClick; + } + + + // Using a DependencyProperty as the backing store for CommandParameter. This enables animation, styling, binding, etc... + + private static void OnItemClick(object sender, ItemClickEventArgs e) + { + Type castType; + var control = sender as ListViewBase; + var command = GetCommand(control); + + var generics = command.GetType().GetGenericArguments(); + if (generics.Length > 0) + castType = generics[0]; + + if (command != null && command.CanExecute(e.ClickedItem)) + command.Execute(e.ClickedItem); + } + } + +} + diff --git a/AMP/Views/Converters/BoolToVisibilityConverter.cs b/AMP/Views/Converters/BoolToVisibilityConverter.cs new file mode 100644 index 0000000..c49a7b8 --- /dev/null +++ b/AMP/Views/Converters/BoolToVisibilityConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Data; + +namespace AMP.Views.Converters +{ + public class BoolToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + return ((bool)value) ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/AMP/Views/Converters/InverseBoolToVisibilityConverter.cs b/AMP/Views/Converters/InverseBoolToVisibilityConverter.cs new file mode 100644 index 0000000..27b2bd5 --- /dev/null +++ b/AMP/Views/Converters/InverseBoolToVisibilityConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Data; + +namespace AMP.Views.Converters +{ + public class InverseBoolToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + return ((bool)value) ? Visibility.Collapsed : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/AMP/Views/NavAwarePage.cs b/AMP/Views/NavAwarePage.cs new file mode 100644 index 0000000..f54932f --- /dev/null +++ b/AMP/Views/NavAwarePage.cs @@ -0,0 +1,52 @@ +using AMP.ViewModels; +using AMP.Services; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; + +namespace AMP.Views +{ + public class NavAwarePage : Page + { + + public NavAwarePage() : base() + { + this.Loaded += NavAwarePage_Loaded; + } + + private void NavAwarePage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + Debug.WriteLine("loaded"); + } + + protected async override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + var navigableViewModel = this.DataContext as INavAware; + if (navigableViewModel != null) + navigableViewModel.Activate(e.Parameter); + + var asyncViewModel = this.DataContext as IAsyncInitialization; + if (asyncViewModel != null) + await asyncViewModel.Initialization; + } + + + + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + base.OnNavigatedFrom(e); + + var navigableViewModel = this.DataContext as INavAware; + if (navigableViewModel != null) + navigableViewModel.Deactivate(e.Parameter); + } + + } +} diff --git a/AMP/Views/Triggers/VisualStateTrigger.cs b/AMP/Views/Triggers/VisualStateTrigger.cs new file mode 100644 index 0000000..8c48a74 --- /dev/null +++ b/AMP/Views/Triggers/VisualStateTrigger.cs @@ -0,0 +1,58 @@ +using AMP.ViewModels; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml; + +namespace AMP.Views.Triggers +{ + public class VisualStateTrigger : StateTriggerBase + { + string _guid; + + public VisualStateTrigger() + { + _guid = Guid.NewGuid().ToString(); + } + public IVisualState ViewModel + { + get { return (IVisualState)GetValue(ViewModelProperty); } + set { SetValue(ViewModelProperty, value); } + } + + // Using a DependencyProperty as the backing store for ViewModel. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ViewModelProperty = + DependencyProperty.Register("ViewModel", typeof(IVisualState), typeof(VisualStateTrigger), new PropertyMetadata(null, OnViewModelChanged)); + + private static void OnViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var model = e.NewValue as IVisualState; + var me = d as VisualStateTrigger; + + + if (model != null) + model.VisualStateChanged += me.Model_StateChanged; + } + + + + public string TargetState { get; set; } + + private async void Model_StateChanged(object model, VisualStateEventArgs args) + { + var me = model as VisualStateTrigger; + var isActive = args.NewState.ToString().Equals(TargetState); + Debug.WriteLine($"VisualStateTrigger {_guid}: target = {TargetState} new: {args.NewState.ToString()} result={isActive}"); + await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => + { + + SetActive(isActive); + }); + + + } + } +}