├── .gitignore ├── README.md ├── SidebarPanel.Core ├── Helpers │ ├── Json.cs │ └── Singleton.cs ├── SidebarPanel.Core.csproj └── readme.txt ├── SidebarPanel.sln ├── SidebarPanel ├── .editorconfig ├── Activation │ ├── ActivationHandler.cs │ └── DefaultActivationHandler.cs ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png ├── Behaviors │ ├── NavigationViewHeaderBehavior.cs │ └── NavigationViewHeaderMode.cs ├── Helpers │ ├── EnumToBooleanConverter.cs │ ├── NavHelper.cs │ ├── ResourceExtensions.cs │ └── SettingsStorageExtensions.cs ├── Package.appxmanifest ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── Services │ ├── ActivationService.cs │ ├── NavigationService.cs │ └── ThemeSelectorService.cs ├── SidebarPanel.csproj ├── SidebarPanel_TemporaryKey.pfx ├── Strings │ └── en-us │ │ └── Resources.resw ├── Styles │ ├── Page.xaml │ ├── TextBlock.xaml │ ├── _Colors.xaml │ ├── _FontSizes.xaml │ └── _Thickness.xaml ├── UserControls │ ├── SidebarItem.xaml │ ├── SidebarItem.xaml.cs │ ├── SidebarPanel.xaml │ └── SidebarPanel.xaml.cs └── Views │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── SettingsPage.xaml │ ├── SettingsPage.xaml.cs │ ├── ShellPage.xaml │ └── ShellPage.xaml.cs └── animation.gif /.gitignore: -------------------------------------------------------------------------------- 1 | /.vs 2 | /SidebarPanel/bin 3 | /SidebarPanel/obj 4 | /SidebarPanel.Core/obj 5 | /SidebarPanel.Core/bin 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SidebarPanel for UWP 2 | this is a SidebarPanel control for UWP, allowing to slide windows/controls to slide out from the side (left or right) and also allows docking. 3 | 4 | ![alt text](https://raw.githubusercontent.com/stefankueng/SidebarPanel/master/animation.gif "SidebarPanel animation") 5 | 6 | 7 | example use: 8 | 9 | 10 | ```xaml 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | ``` -------------------------------------------------------------------------------- /SidebarPanel.Core/Helpers/Json.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | using Newtonsoft.Json; 5 | 6 | namespace SidebarPanel.Core.Helpers 7 | { 8 | public static class Json 9 | { 10 | public static async Task ToObjectAsync(string value) 11 | { 12 | return await Task.Run(() => 13 | { 14 | return JsonConvert.DeserializeObject(value); 15 | }); 16 | } 17 | 18 | public static async Task StringifyAsync(object value) 19 | { 20 | return await Task.Run(() => 21 | { 22 | return JsonConvert.SerializeObject(value); 23 | }); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SidebarPanel.Core/Helpers/Singleton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | 4 | namespace SidebarPanel.Core.Helpers 5 | { 6 | public static class Singleton 7 | where T : new() 8 | { 9 | private static ConcurrentDictionary _instances = new ConcurrentDictionary(); 10 | 11 | public static T Instance 12 | { 13 | get 14 | { 15 | return _instances.GetOrAdd(typeof(T), (t) => new T()); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SidebarPanel.Core/SidebarPanel.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | SidebarPanel.Core 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /SidebarPanel.Core/readme.txt: -------------------------------------------------------------------------------- 1 | This core project is a .net standard project. 2 | It's a great place to put all your logic that is not platform dependent (e.g. model/helper classes) so they can be reused. -------------------------------------------------------------------------------- /SidebarPanel.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29403.142 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SidebarPanel", "SidebarPanel\SidebarPanel.csproj", "{CFC61D44-C644-4862-8588-E6B94DC957E5}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SidebarPanel.Core", "SidebarPanel.Core\SidebarPanel.Core.csproj", "{E39C7780-1C77-4061-B589-18203E0EAD48}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|ARM = Debug|ARM 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|Any CPU = Release|Any CPU 17 | Release|ARM = Release|ARM 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|Any CPU.ActiveCfg = Debug|x86 23 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|ARM.ActiveCfg = Debug|ARM 24 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|ARM.Build.0 = Debug|ARM 25 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|ARM.Deploy.0 = Debug|ARM 26 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|x64.ActiveCfg = Debug|x64 27 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|x64.Build.0 = Debug|x64 28 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|x64.Deploy.0 = Debug|x64 29 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|x86.ActiveCfg = Debug|x86 30 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|x86.Build.0 = Debug|x86 31 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Debug|x86.Deploy.0 = Debug|x86 32 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|Any CPU.ActiveCfg = Release|x86 33 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|ARM.ActiveCfg = Release|ARM 34 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|ARM.Build.0 = Release|ARM 35 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|ARM.Deploy.0 = Release|ARM 36 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|x64.ActiveCfg = Release|x64 37 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|x64.Build.0 = Release|x64 38 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|x64.Deploy.0 = Release|x64 39 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|x86.ActiveCfg = Release|x86 40 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|x86.Build.0 = Release|x86 41 | {CFC61D44-C644-4862-8588-E6B94DC957E5}.Release|x86.Deploy.0 = Release|x86 42 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|ARM.ActiveCfg = Debug|Any CPU 45 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|ARM.Build.0 = Debug|Any CPU 46 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|x64.ActiveCfg = Debug|Any CPU 47 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|x64.Build.0 = Debug|Any CPU 48 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|x86.ActiveCfg = Debug|Any CPU 49 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Debug|x86.Build.0 = Debug|Any CPU 50 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|ARM.ActiveCfg = Release|Any CPU 53 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|ARM.Build.0 = Release|Any CPU 54 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|x64.ActiveCfg = Release|Any CPU 55 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|x64.Build.0 = Release|Any CPU 56 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|x86.ActiveCfg = Release|Any CPU 57 | {E39C7780-1C77-4061-B589-18203E0EAD48}.Release|x86.Build.0 = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {742094F6-112D-4CEB-8CE9-CA361F783876} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /SidebarPanel/.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | end_of_line = crlf 6 | 7 | [*.{cs,xaml}] 8 | indent_style = space 9 | indent_size = 4 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /SidebarPanel/Activation/ActivationHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace SidebarPanel.Activation 5 | { 6 | // For more information on understanding and extending activation flow see 7 | // https://github.com/Microsoft/WindowsTemplateStudio/blob/master/docs/activation.md 8 | internal abstract class ActivationHandler 9 | { 10 | public abstract bool CanHandle(object args); 11 | 12 | public abstract Task HandleAsync(object args); 13 | } 14 | 15 | // Extend this class to implement new ActivationHandlers 16 | internal abstract class ActivationHandler : ActivationHandler 17 | where T : class 18 | { 19 | // Override this method to add the activation logic in your activation handler 20 | protected abstract Task HandleInternalAsync(T args); 21 | 22 | public override async Task HandleAsync(object args) 23 | { 24 | await HandleInternalAsync(args as T); 25 | } 26 | 27 | public override bool CanHandle(object args) 28 | { 29 | // CanHandle checks the args is of type you have configured 30 | return args is T && CanHandleInternal(args as T); 31 | } 32 | 33 | // You can override this method to add extra validation on activation args 34 | // to determine if your ActivationHandler should handle this activation args 35 | protected virtual bool CanHandleInternal(T args) 36 | { 37 | return true; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SidebarPanel/Activation/DefaultActivationHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | using SidebarPanel.Services; 5 | 6 | using Windows.ApplicationModel.Activation; 7 | 8 | namespace SidebarPanel.Activation 9 | { 10 | internal class DefaultActivationHandler : ActivationHandler 11 | { 12 | private readonly Type _navElement; 13 | 14 | public DefaultActivationHandler(Type navElement) 15 | { 16 | _navElement = navElement; 17 | } 18 | 19 | protected override async Task HandleInternalAsync(IActivatedEventArgs args) 20 | { 21 | // When the navigation stack isn't restored, navigate to the first page and configure 22 | // the new page by passing required information in the navigation parameter 23 | object arguments = null; 24 | if (args is LaunchActivatedEventArgs launchArgs) 25 | { 26 | arguments = launchArgs.Arguments; 27 | } 28 | 29 | NavigationService.Navigate(_navElement, arguments); 30 | await Task.CompletedTask; 31 | } 32 | 33 | protected override bool CanHandleInternal(IActivatedEventArgs args) 34 | { 35 | // None of the ActivationHandlers has handled the app activation 36 | return NavigationService.Frame.Content == null && _navElement != null; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SidebarPanel/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SidebarPanel/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using SidebarPanel.Services; 4 | 5 | using Windows.ApplicationModel.Activation; 6 | using Windows.UI.Xaml; 7 | 8 | namespace SidebarPanel 9 | { 10 | public sealed partial class App : Application 11 | { 12 | private Lazy _activationService; 13 | 14 | private ActivationService ActivationService 15 | { 16 | get { return _activationService.Value; } 17 | } 18 | 19 | public App() 20 | { 21 | InitializeComponent(); 22 | 23 | // Deferred execution until used. Check https://msdn.microsoft.com/library/dd642331(v=vs.110).aspx for further info on Lazy class. 24 | _activationService = new Lazy(CreateActivationService); 25 | } 26 | 27 | protected override async void OnLaunched(LaunchActivatedEventArgs args) 28 | { 29 | if (!args.PrelaunchActivated) 30 | { 31 | await ActivationService.ActivateAsync(args); 32 | } 33 | } 34 | 35 | protected override async void OnActivated(IActivatedEventArgs args) 36 | { 37 | await ActivationService.ActivateAsync(args); 38 | } 39 | 40 | private ActivationService CreateActivationService() 41 | { 42 | return new ActivationService(this, typeof(Views.MainPage), new Lazy(CreateShell)); 43 | } 44 | 45 | private UIElement CreateShell() 46 | { 47 | return new Views.ShellPage(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SidebarPanel/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /SidebarPanel/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /SidebarPanel/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /SidebarPanel/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /SidebarPanel/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /SidebarPanel/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/StoreLogo.png -------------------------------------------------------------------------------- /SidebarPanel/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /SidebarPanel/Behaviors/NavigationViewHeaderBehavior.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xaml.Interactivity; 2 | 3 | using SidebarPanel.Services; 4 | 5 | using Windows.UI.Xaml; 6 | using Windows.UI.Xaml.Controls; 7 | using Windows.UI.Xaml.Navigation; 8 | 9 | using WinUI = Microsoft.UI.Xaml.Controls; 10 | 11 | namespace SidebarPanel.Behaviors 12 | { 13 | public class NavigationViewHeaderBehavior : Behavior 14 | { 15 | private static NavigationViewHeaderBehavior _current; 16 | private Page _currentPage; 17 | 18 | public DataTemplate DefaultHeaderTemplate { get; set; } 19 | 20 | public object DefaultHeader 21 | { 22 | get { return GetValue(DefaultHeaderProperty); } 23 | set { SetValue(DefaultHeaderProperty, value); } 24 | } 25 | 26 | public static readonly DependencyProperty DefaultHeaderProperty = DependencyProperty.Register("DefaultHeader", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current.UpdateHeader())); 27 | 28 | public static NavigationViewHeaderMode GetHeaderMode(Page item) 29 | { 30 | return (NavigationViewHeaderMode)item.GetValue(HeaderModeProperty); 31 | } 32 | 33 | public static void SetHeaderMode(Page item, NavigationViewHeaderMode value) 34 | { 35 | item.SetValue(HeaderModeProperty, value); 36 | } 37 | 38 | public static readonly DependencyProperty HeaderModeProperty = 39 | DependencyProperty.RegisterAttached("HeaderMode", typeof(bool), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(NavigationViewHeaderMode.Always, (d, e) => _current.UpdateHeader())); 40 | 41 | public static object GetHeaderContext(Page item) 42 | { 43 | return item.GetValue(HeaderContextProperty); 44 | } 45 | 46 | public static void SetHeaderContext(Page item, object value) 47 | { 48 | item.SetValue(HeaderContextProperty, value); 49 | } 50 | 51 | public static readonly DependencyProperty HeaderContextProperty = 52 | DependencyProperty.RegisterAttached("HeaderContext", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current.UpdateHeader())); 53 | 54 | public static DataTemplate GetHeaderTemplate(Page item) 55 | { 56 | return (DataTemplate)item.GetValue(HeaderTemplateProperty); 57 | } 58 | 59 | public static void SetHeaderTemplate(Page item, DataTemplate value) 60 | { 61 | item.SetValue(HeaderTemplateProperty, value); 62 | } 63 | 64 | public static readonly DependencyProperty HeaderTemplateProperty = 65 | DependencyProperty.RegisterAttached("HeaderTemplate", typeof(DataTemplate), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => _current.UpdateHeaderTemplate())); 66 | 67 | protected override void OnAttached() 68 | { 69 | base.OnAttached(); 70 | _current = this; 71 | NavigationService.Navigated += OnNavigated; 72 | } 73 | 74 | protected override void OnDetaching() 75 | { 76 | base.OnDetaching(); 77 | NavigationService.Navigated -= OnNavigated; 78 | } 79 | 80 | private void OnNavigated(object sender, NavigationEventArgs e) 81 | { 82 | var frame = sender as Frame; 83 | if (frame.Content is Page page) 84 | { 85 | _currentPage = page; 86 | 87 | UpdateHeader(); 88 | UpdateHeaderTemplate(); 89 | } 90 | } 91 | 92 | private void UpdateHeader() 93 | { 94 | if (_currentPage != null) 95 | { 96 | var headerMode = GetHeaderMode(_currentPage); 97 | if (headerMode == NavigationViewHeaderMode.Never) 98 | { 99 | AssociatedObject.Header = null; 100 | AssociatedObject.AlwaysShowHeader = false; 101 | } 102 | else 103 | { 104 | var headerFromPage = GetHeaderContext(_currentPage); 105 | if (headerFromPage != null) 106 | { 107 | AssociatedObject.Header = headerFromPage; 108 | } 109 | else 110 | { 111 | AssociatedObject.Header = DefaultHeader; 112 | } 113 | 114 | if (headerMode == NavigationViewHeaderMode.Always) 115 | { 116 | AssociatedObject.AlwaysShowHeader = true; 117 | } 118 | else 119 | { 120 | AssociatedObject.AlwaysShowHeader = false; 121 | } 122 | } 123 | } 124 | } 125 | 126 | private void UpdateHeaderTemplate() 127 | { 128 | if (_currentPage != null) 129 | { 130 | var headerTemplate = GetHeaderTemplate(_currentPage); 131 | AssociatedObject.HeaderTemplate = headerTemplate ?? DefaultHeaderTemplate; 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /SidebarPanel/Behaviors/NavigationViewHeaderMode.cs: -------------------------------------------------------------------------------- 1 | namespace SidebarPanel.Behaviors 2 | { 3 | public enum NavigationViewHeaderMode 4 | { 5 | Always, 6 | Never, 7 | Minimal 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SidebarPanel/Helpers/EnumToBooleanConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Windows.UI.Xaml.Data; 4 | 5 | namespace SidebarPanel.Helpers 6 | { 7 | public class EnumToBooleanConverter : IValueConverter 8 | { 9 | public Type EnumType { get; set; } 10 | 11 | public object Convert(object value, Type targetType, object parameter, string language) 12 | { 13 | if (parameter is string enumString) 14 | { 15 | if (!Enum.IsDefined(EnumType, value)) 16 | { 17 | throw new ArgumentException("ExceptionEnumToBooleanConverterValueMustBeAnEnum".GetLocalized()); 18 | } 19 | 20 | var enumValue = Enum.Parse(EnumType, enumString); 21 | 22 | return enumValue.Equals(value); 23 | } 24 | 25 | throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName".GetLocalized()); 26 | } 27 | 28 | public object ConvertBack(object value, Type targetType, object parameter, string language) 29 | { 30 | if (parameter is string enumString) 31 | { 32 | return Enum.Parse(EnumType, enumString); 33 | } 34 | 35 | throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName".GetLocalized()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SidebarPanel/Helpers/NavHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Microsoft.UI.Xaml.Controls; 4 | 5 | using Windows.UI.Xaml; 6 | 7 | namespace SidebarPanel.Helpers 8 | { 9 | public class NavHelper 10 | { 11 | // This helper class allows to specify the page that will be shown when you click on a NavigationViewItem 12 | // 13 | // Usage in xaml: 14 | // 15 | // 16 | // Usage in code: 17 | // NavHelper.SetNavigateTo(navigationViewItem, typeof(MainPage)); 18 | public static Type GetNavigateTo(NavigationViewItem item) 19 | { 20 | return (Type)item.GetValue(NavigateToProperty); 21 | } 22 | 23 | public static void SetNavigateTo(NavigationViewItem item, Type value) 24 | { 25 | item.SetValue(NavigateToProperty, value); 26 | } 27 | 28 | public static readonly DependencyProperty NavigateToProperty = 29 | DependencyProperty.RegisterAttached("NavigateTo", typeof(Type), typeof(NavHelper), new PropertyMetadata(null)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SidebarPanel/Helpers/ResourceExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | using Windows.ApplicationModel.Resources; 5 | 6 | namespace SidebarPanel.Helpers 7 | { 8 | internal static class ResourceExtensions 9 | { 10 | private static ResourceLoader _resLoader = new ResourceLoader(); 11 | 12 | public static string GetLocalized(this string resourceKey) 13 | { 14 | return _resLoader.GetString(resourceKey); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SidebarPanel/Helpers/SettingsStorageExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | 5 | using SidebarPanel.Core.Helpers; 6 | 7 | using Windows.Storage; 8 | using Windows.Storage.Streams; 9 | 10 | namespace SidebarPanel.Helpers 11 | { 12 | // Use these extension methods to store and retrieve local and roaming app data 13 | // More details regarding storing and retrieving app data at https://docs.microsoft.com/windows/uwp/app-settings/store-and-retrieve-app-data 14 | public static class SettingsStorageExtensions 15 | { 16 | private const string FileExtension = ".json"; 17 | 18 | public static bool IsRoamingStorageAvailable(this ApplicationData appData) 19 | { 20 | return appData.RoamingStorageQuota == 0; 21 | } 22 | 23 | public static async Task SaveAsync(this StorageFolder folder, string name, T content) 24 | { 25 | var file = await folder.CreateFileAsync(GetFileName(name), CreationCollisionOption.ReplaceExisting); 26 | var fileContent = await Json.StringifyAsync(content); 27 | 28 | await FileIO.WriteTextAsync(file, fileContent); 29 | } 30 | 31 | public static async Task ReadAsync(this StorageFolder folder, string name) 32 | { 33 | if (!File.Exists(Path.Combine(folder.Path, GetFileName(name)))) 34 | { 35 | return default(T); 36 | } 37 | 38 | var file = await folder.GetFileAsync($"{name}.json"); 39 | var fileContent = await FileIO.ReadTextAsync(file); 40 | 41 | return await Json.ToObjectAsync(fileContent); 42 | } 43 | 44 | public static async Task SaveAsync(this ApplicationDataContainer settings, string key, T value) 45 | { 46 | settings.SaveString(key, await Json.StringifyAsync(value)); 47 | } 48 | 49 | public static void SaveString(this ApplicationDataContainer settings, string key, string value) 50 | { 51 | settings.Values[key] = value; 52 | } 53 | 54 | public static async Task ReadAsync(this ApplicationDataContainer settings, string key) 55 | { 56 | object obj = null; 57 | 58 | if (settings.Values.TryGetValue(key, out obj)) 59 | { 60 | return await Json.ToObjectAsync((string)obj); 61 | } 62 | 63 | return default(T); 64 | } 65 | 66 | public static async Task SaveFileAsync(this StorageFolder folder, byte[] content, string fileName, CreationCollisionOption options = CreationCollisionOption.ReplaceExisting) 67 | { 68 | if (content == null) 69 | { 70 | throw new ArgumentNullException(nameof(content)); 71 | } 72 | 73 | if (string.IsNullOrEmpty(fileName)) 74 | { 75 | throw new ArgumentException("ExceptionSettingsStorageExtensionsFileNameIsNullOrEmpty".GetLocalized(), nameof(fileName)); 76 | } 77 | 78 | var storageFile = await folder.CreateFileAsync(fileName, options); 79 | await FileIO.WriteBytesAsync(storageFile, content); 80 | return storageFile; 81 | } 82 | 83 | public static async Task ReadFileAsync(this StorageFolder folder, string fileName) 84 | { 85 | var item = await folder.TryGetItemAsync(fileName).AsTask().ConfigureAwait(false); 86 | 87 | if ((item != null) && item.IsOfType(StorageItemTypes.File)) 88 | { 89 | var storageFile = await folder.GetFileAsync(fileName); 90 | byte[] content = await storageFile.ReadBytesAsync(); 91 | return content; 92 | } 93 | 94 | return null; 95 | } 96 | 97 | public static async Task ReadBytesAsync(this StorageFile file) 98 | { 99 | if (file != null) 100 | { 101 | using (IRandomAccessStream stream = await file.OpenReadAsync()) 102 | { 103 | using (var reader = new DataReader(stream.GetInputStreamAt(0))) 104 | { 105 | await reader.LoadAsync((uint)stream.Size); 106 | var bytes = new byte[stream.Size]; 107 | reader.ReadBytes(bytes); 108 | return bytes; 109 | } 110 | } 111 | } 112 | 113 | return null; 114 | } 115 | 116 | private static string GetFileName(string name) 117 | { 118 | return string.Concat(name, FileExtension); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /SidebarPanel/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | SidebarPanel 19 | kueng 20 | Assets\StoreLogo.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /SidebarPanel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("SidebarPanel")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("SidebarPanel")] 14 | [assembly: AssemblyCopyright("Copyright © 2019")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Version information for an assembly consists of the following four values: 19 | // 20 | // Major Version 21 | // Minor Version 22 | // Build Number 23 | // Revision 24 | // 25 | // You can specify all the values or you can default the Build and Revision Numbers 26 | // by using the '*' as shown below: 27 | // [assembly: AssemblyVersion("1.0.*")] 28 | [assembly: AssemblyVersion("1.0.0.0")] 29 | [assembly: AssemblyFileVersion("1.0.0.0")] 30 | [assembly: ComVisible(false)] 31 | -------------------------------------------------------------------------------- /SidebarPanel/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 |  17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /SidebarPanel/Services/ActivationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | using SidebarPanel.Activation; 7 | 8 | using Windows.ApplicationModel.Activation; 9 | using Windows.UI.Xaml; 10 | using Windows.UI.Xaml.Controls; 11 | 12 | namespace SidebarPanel.Services 13 | { 14 | // For more information on understanding and extending activation flow see 15 | // https://github.com/Microsoft/WindowsTemplateStudio/blob/master/docs/activation.md 16 | internal class ActivationService 17 | { 18 | private readonly App _app; 19 | private readonly Type _defaultNavItem; 20 | private Lazy _shell; 21 | 22 | private object _lastActivationArgs; 23 | 24 | public ActivationService(App app, Type defaultNavItem, Lazy shell = null) 25 | { 26 | _app = app; 27 | _shell = shell; 28 | _defaultNavItem = defaultNavItem; 29 | } 30 | 31 | public async Task ActivateAsync(object activationArgs) 32 | { 33 | if (IsInteractive(activationArgs)) 34 | { 35 | // Initialize services that you need before app activation 36 | // take into account that the splash screen is shown while this code runs. 37 | await InitializeAsync(); 38 | 39 | // Do not repeat app initialization when the Window already has content, 40 | // just ensure that the window is active 41 | if (Window.Current.Content == null) 42 | { 43 | // Create a Shell or Frame to act as the navigation context 44 | Window.Current.Content = _shell?.Value ?? new Frame(); 45 | } 46 | } 47 | 48 | // Depending on activationArgs one of ActivationHandlers or DefaultActivationHandler 49 | // will navigate to the first page 50 | await HandleActivationAsync(activationArgs); 51 | _lastActivationArgs = activationArgs; 52 | 53 | if (IsInteractive(activationArgs)) 54 | { 55 | // Ensure the current window is active 56 | Window.Current.Activate(); 57 | 58 | // Tasks after activation 59 | await StartupAsync(); 60 | } 61 | } 62 | 63 | private async Task InitializeAsync() 64 | { 65 | await ThemeSelectorService.InitializeAsync(); 66 | } 67 | 68 | private async Task HandleActivationAsync(object activationArgs) 69 | { 70 | var activationHandler = GetActivationHandlers() 71 | .FirstOrDefault(h => h.CanHandle(activationArgs)); 72 | 73 | if (activationHandler != null) 74 | { 75 | await activationHandler.HandleAsync(activationArgs); 76 | } 77 | 78 | if (IsInteractive(activationArgs)) 79 | { 80 | var defaultHandler = new DefaultActivationHandler(_defaultNavItem); 81 | if (defaultHandler.CanHandle(activationArgs)) 82 | { 83 | await defaultHandler.HandleAsync(activationArgs); 84 | } 85 | } 86 | } 87 | 88 | private async Task StartupAsync() 89 | { 90 | await ThemeSelectorService.SetRequestedThemeAsync(); 91 | } 92 | 93 | private IEnumerable GetActivationHandlers() 94 | { 95 | yield break; 96 | } 97 | 98 | private bool IsInteractive(object args) 99 | { 100 | return args is IActivatedEventArgs; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /SidebarPanel/Services/NavigationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Windows.UI.Xaml; 4 | using Windows.UI.Xaml.Controls; 5 | using Windows.UI.Xaml.Media.Animation; 6 | using Windows.UI.Xaml.Navigation; 7 | 8 | namespace SidebarPanel.Services 9 | { 10 | public static class NavigationService 11 | { 12 | public static event NavigatedEventHandler Navigated; 13 | 14 | public static event NavigationFailedEventHandler NavigationFailed; 15 | 16 | private static Frame _frame; 17 | private static object _lastParamUsed; 18 | 19 | public static Frame Frame 20 | { 21 | get 22 | { 23 | if (_frame == null) 24 | { 25 | _frame = Window.Current.Content as Frame; 26 | RegisterFrameEvents(); 27 | } 28 | 29 | return _frame; 30 | } 31 | 32 | set 33 | { 34 | UnregisterFrameEvents(); 35 | _frame = value; 36 | RegisterFrameEvents(); 37 | } 38 | } 39 | 40 | public static bool CanGoBack => Frame.CanGoBack; 41 | 42 | public static bool CanGoForward => Frame.CanGoForward; 43 | 44 | public static bool GoBack() 45 | { 46 | if (CanGoBack) 47 | { 48 | Frame.GoBack(); 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | public static void GoForward() => Frame.GoForward(); 56 | 57 | public static bool Navigate(Type pageType, object parameter = null, NavigationTransitionInfo infoOverride = null) 58 | { 59 | // Don't open the same page multiple times 60 | if (Frame.Content?.GetType() != pageType || (parameter != null && !parameter.Equals(_lastParamUsed))) 61 | { 62 | var navigationResult = Frame.Navigate(pageType, parameter, infoOverride); 63 | if (navigationResult) 64 | { 65 | _lastParamUsed = parameter; 66 | } 67 | 68 | return navigationResult; 69 | } 70 | else 71 | { 72 | return false; 73 | } 74 | } 75 | 76 | public static bool Navigate(object parameter = null, NavigationTransitionInfo infoOverride = null) 77 | where T : Page 78 | => Navigate(typeof(T), parameter, infoOverride); 79 | 80 | private static void RegisterFrameEvents() 81 | { 82 | if (_frame != null) 83 | { 84 | _frame.Navigated += Frame_Navigated; 85 | _frame.NavigationFailed += Frame_NavigationFailed; 86 | } 87 | } 88 | 89 | private static void UnregisterFrameEvents() 90 | { 91 | if (_frame != null) 92 | { 93 | _frame.Navigated -= Frame_Navigated; 94 | _frame.NavigationFailed -= Frame_NavigationFailed; 95 | } 96 | } 97 | 98 | private static void Frame_NavigationFailed(object sender, NavigationFailedEventArgs e) => NavigationFailed?.Invoke(sender, e); 99 | 100 | private static void Frame_Navigated(object sender, NavigationEventArgs e) => Navigated?.Invoke(sender, e); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /SidebarPanel/Services/ThemeSelectorService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | using SidebarPanel.Helpers; 5 | 6 | using Windows.ApplicationModel.Core; 7 | using Windows.Storage; 8 | using Windows.UI.Core; 9 | using Windows.UI.Xaml; 10 | 11 | namespace SidebarPanel.Services 12 | { 13 | public static class ThemeSelectorService 14 | { 15 | private const string SettingsKey = "AppBackgroundRequestedTheme"; 16 | 17 | public static ElementTheme Theme { get; set; } = ElementTheme.Default; 18 | 19 | public static async Task InitializeAsync() 20 | { 21 | Theme = await LoadThemeFromSettingsAsync(); 22 | } 23 | 24 | public static async Task SetThemeAsync(ElementTheme theme) 25 | { 26 | Theme = theme; 27 | 28 | await SetRequestedThemeAsync(); 29 | await SaveThemeInSettingsAsync(Theme); 30 | } 31 | 32 | public static async Task SetRequestedThemeAsync() 33 | { 34 | foreach (var view in CoreApplication.Views) 35 | { 36 | await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 37 | { 38 | if (Window.Current.Content is FrameworkElement frameworkElement) 39 | { 40 | frameworkElement.RequestedTheme = Theme; 41 | } 42 | }); 43 | } 44 | } 45 | 46 | private static async Task LoadThemeFromSettingsAsync() 47 | { 48 | ElementTheme cacheTheme = ElementTheme.Default; 49 | string themeName = await ApplicationData.Current.LocalSettings.ReadAsync(SettingsKey); 50 | 51 | if (!string.IsNullOrEmpty(themeName)) 52 | { 53 | Enum.TryParse(themeName, out cacheTheme); 54 | } 55 | 56 | return cacheTheme; 57 | } 58 | 59 | private static async Task SaveThemeInSettingsAsync(ElementTheme theme) 60 | { 61 | await ApplicationData.Current.LocalSettings.SaveAsync(SettingsKey, theme.ToString()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /SidebarPanel/SidebarPanel.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x86 7 | {CFC61D44-C644-4862-8588-E6B94DC957E5} 8 | AppContainerExe 9 | Properties 10 | SidebarPanel 11 | SidebarPanel 12 | en-US 13 | UAP 14 | 10.0.18362.0 15 | 10.0.18362.0 16 | 14 17 | 512 18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 19 | true 20 | SidebarPanel_TemporaryKey.pfx 21 | 22 | 23 | true 24 | bin\x86\Debug\ 25 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 26 | NU1603;2008; 27 | full 28 | x86 29 | false 30 | prompt 31 | true 32 | 33 | 34 | bin\x86\Release\ 35 | TRACE;NETFX_CORE;WINDOWS_UWP 36 | true 37 | NU1603;2008; 38 | pdbonly 39 | x86 40 | false 41 | prompt 42 | true 43 | true 44 | 45 | 46 | true 47 | bin\ARM\Debug\ 48 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 49 | NU1603;2008; 50 | full 51 | ARM 52 | false 53 | prompt 54 | true 55 | 56 | 57 | bin\ARM\Release\ 58 | TRACE;NETFX_CORE;WINDOWS_UWP 59 | true 60 | NU1603;2008; 61 | pdbonly 62 | ARM 63 | false 64 | prompt 65 | true 66 | true 67 | 68 | 69 | true 70 | bin\x64\Debug\ 71 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 72 | NU1603;2008; 73 | full 74 | x64 75 | false 76 | prompt 77 | true 78 | 79 | 80 | bin\x64\Release\ 81 | TRACE;NETFX_CORE;WINDOWS_UWP 82 | true 83 | NU1603;2008; 84 | pdbonly 85 | x64 86 | false 87 | prompt 88 | true 89 | true 90 | 91 | 92 | PackageReference 93 | 94 | 95 | 96 | 6.2.9 97 | 98 | 99 | 5.0.0 100 | 101 | 102 | 2.2.190917002 103 | 104 | 105 | 2.0.1 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | SidebarItem.xaml 124 | 125 | 126 | SidebarPanel.xaml 127 | 128 | 129 | MainPage.xaml 130 | 131 | 132 | SettingsPage.xaml 133 | 134 | 135 | ShellPage.xaml 136 | 137 | 138 | 139 | 140 | App.xaml 141 | 142 | 143 | 144 | 145 | 146 | MSBuild:Compile 147 | Designer 148 | 149 | 150 | Designer 151 | MSBuild:Compile 152 | 153 | 154 | Designer 155 | MSBuild:Compile 156 | 157 | 158 | Designer 159 | MSBuild:Compile 160 | 161 | 162 | Designer 163 | MSBuild:Compile 164 | 165 | 166 | MSBuild:Compile 167 | Designer 168 | 169 | 170 | MSBuild:Compile 171 | Designer 172 | 173 | 174 | MSBuild:Compile 175 | Designer 176 | 177 | 178 | MSBuild:Compile 179 | Designer 180 | 181 | 182 | MSBuild:Compile 183 | Designer 184 | 185 | 186 | 187 | 188 | Designer 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | MSBuild:Compile 211 | Designer 212 | 213 | 214 | 215 | 216 | {E39C7780-1C77-4061-B589-18203E0EAD48} 217 | SidebarPanel.Core 218 | 219 | 220 | 221 | 14.0 222 | 223 | 224 | 231 | -------------------------------------------------------------------------------- /SidebarPanel/SidebarPanel_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/SidebarPanel/b21308d8bb8481148278ec153d4ec3bd0544ad88/SidebarPanel/SidebarPanel_TemporaryKey.pfx -------------------------------------------------------------------------------- /SidebarPanel/Strings/en-us/Resources.resw: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | SidebarPanel 122 | Application display name 123 | 124 | 125 | SidebarPanel 126 | Application description 127 | 128 | 129 | Main 130 | Navigation view item name for Main 131 | 132 | 133 | File name is null or empty. Specify a valid file name 134 | File name is null or empty to save file in settings storage extensions 135 | 136 | 137 | Choose Theme 138 | Choose theme text for Settings 139 | 140 | 141 | Dark 142 | Dark theme text for Settings 143 | 144 | 145 | Windows default 146 | Windows default theme text for Settings 147 | 148 | 149 | Light 150 | Light theme text for Settings 151 | 152 | 153 | About this application 154 | About this application title for Settings 155 | 156 | 157 | Settings page placeholder text. Your app description goes here. 158 | About this application description for Settings 159 | 160 | 161 | Privacy Statement 162 | Privacy Statement link content for Settings 163 | 164 | 165 | https://YourPrivacyUrlGoesHere/ 166 | Here is your Privacy Statement url for Settings 167 | 168 | 169 | Personalization 170 | Personalization text for Settings 171 | 172 | 173 | value must be an Enum! 174 | Value must be an Enum in enum to boolean converter 175 | 176 | 177 | parameter must be an Enum name! 178 | Parameter must be an Enum name in enum to boolean converter 179 | 180 | 181 | -------------------------------------------------------------------------------- /SidebarPanel/Styles/Page.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SidebarPanel/Styles/TextBlock.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 13 | 14 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /SidebarPanel/Styles/_Colors.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | -------------------------------------------------------------------------------- /SidebarPanel/Styles/_FontSizes.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 24 6 | 16 7 | 8 | 9 | -------------------------------------------------------------------------------- /SidebarPanel/Styles/_Thickness.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 24,0,0,0 7 | 0,24,0,0 8 | 24,0,24,0 9 | 0,0,24,0 10 | 0,24,0,24 11 | 24,24,24,24 12 | 0,0,0,24 13 | 14 | 15 | 12, 0, 0, 0 16 | 0, 12, 0, 0 17 | 0, 12, 0, 12 18 | 12, 0, 12, 0 19 | 0, 0, 12, 0 20 | 21 | 22 | 8, 0, 0, 0 23 | 0, 8, 0, 0 24 | 8, 8, 8, 8 25 | 26 | 27 | 0, 4, 0, 0 28 | 0, 4, 4, 4 29 | 30 | -------------------------------------------------------------------------------- /SidebarPanel/UserControls/SidebarItem.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 38 |