├── .editorconfig
├── .github
├── CODEOWNERS
└── workflows
│ └── build-package.yml
├── .gitignore
├── LICENSE
├── README.md
├── avalonia-extensions.sln
├── avalonia-extensions.sln.DotSettings
├── samples
└── SampleApp
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── Assets
│ ├── Add.svg
│ ├── AddThin.svg
│ ├── Computer.svg
│ ├── CopyHost.svg
│ ├── CopyName.svg
│ ├── CopyPassword.svg
│ ├── CopyUserName.svg
│ ├── CopyUserNamePassword.svg
│ ├── Details.svg
│ ├── DisableUser.svg
│ ├── EnableUser.svg
│ ├── Folder.svg
│ ├── Help.svg
│ ├── HorizontalLine.svg
│ ├── More.svg
│ ├── Padlock.svg
│ ├── PasswordAnalyser.svg
│ ├── PrivateKey.svg
│ ├── Properties.svg
│ ├── ResetPassword.svg
│ ├── SampleImage.jpg
│ ├── UnlockUser.svg
│ └── User.svg
│ ├── DemoPages
│ ├── ButtonDemo.axaml
│ ├── ButtonDemo.axaml.cs
│ ├── CheckBoxDemo.axaml
│ ├── CheckBoxDemo.axaml.cs
│ ├── ComboBoxDemo.axaml
│ ├── ComboBoxDemo.axaml.cs
│ ├── ContextMenuDemo.axaml
│ ├── ContextMenuDemo.axaml.cs
│ ├── ControlAlignment.axaml
│ ├── ControlAlignment.axaml.cs
│ ├── DataGridDemo.axaml
│ ├── DataGridDemo.axaml.cs
│ ├── DataGridGroupedDemo.axaml
│ ├── DataGridGroupedDemo.axaml.cs
│ ├── EditableComboBoxDemo.axaml
│ ├── EditableComboBoxDemo.axaml.cs
│ ├── GridSplitterDemo.axaml
│ ├── GridSplitterDemo.axaml.cs
│ ├── MenuDemo.axaml
│ ├── MenuDemo.axaml.cs
│ ├── MenuFlyoutDemo.axaml
│ ├── MenuFlyoutDemo.axaml.cs
│ ├── NumericUpDownDemo.axaml
│ ├── NumericUpDownDemo.axaml.cs
│ ├── Overview.axaml
│ ├── Overview.axaml.cs
│ ├── ScrollViewerDemo.axaml
│ ├── ScrollViewerDemo.axaml.cs
│ ├── TabControlDemo.axaml
│ ├── TabControlDemo.axaml.cs
│ ├── TextBoxDemo.axaml
│ ├── TextBoxDemo.axaml.cs
│ ├── ToggleSwitchDemo.axaml
│ ├── ToggleSwitchDemo.axaml.cs
│ ├── ToolTipDemo.axaml
│ ├── ToolTipDemo.axaml.cs
│ ├── TreeViewDemo.axaml
│ └── TreeViewDemo.axaml.cs
│ ├── Experiments
│ ├── SystemColoursDemo.axaml
│ ├── SystemColoursDemo.axaml.cs
│ ├── ToggleButtonExperiments.axaml
│ └── ToggleButtonExperiments.axaml.cs
│ ├── MainWindow.axaml
│ ├── MainWindow.axaml.cs
│ ├── Models
│ └── DataGridItem.cs
│ ├── Program.cs
│ ├── SampleApp.csproj
│ ├── Styles.axaml
│ ├── ViewModels
│ ├── DataGridGroupedViewModel.cs
│ ├── DataGridViewModel.cs
│ ├── MainWindowViewModel.cs
│ └── TextBoxViewModel.cs
│ └── app.manifest
└── src
├── Devolutions.AvaloniaControls
├── Controls
│ ├── EditableComboBox
│ │ ├── EditableComboBox.axaml
│ │ ├── EditableComboBox.axaml.cs
│ │ ├── EditableComboBoxItem.cs
│ │ ├── EditableComboBoxMode.cs
│ │ ├── InnerComboBox.cs
│ │ └── InnerTextBox.cs
│ ├── SearchHighlightTextBlock.axaml
│ └── SearchHighlightTextBlock.axaml.cs
├── Converters
│ ├── BooleanToChoiceConverter.cs
│ ├── ClassToChoiceConverter.cs
│ ├── ColorToCssFillConverter.cs
│ ├── CornerRadiusExtractor.cs
│ ├── DevoConverters.cs
│ ├── DevoDoubleConverters.cs
│ ├── DevoMultiConverters.cs
│ ├── FirstNonNullValueMultiConverter.cs
│ ├── HasClassConverter.cs
│ ├── IsExplicitlyTrueConverter.cs
│ ├── IsUnsetConverter.cs
│ ├── RevealPasswordToFontSizeConverter.cs
│ ├── SelectedIndexToPopupOffsetConverter.cs
│ ├── TabBorderVisibilityConverter.cs
│ ├── ThicknessExtractor.cs
│ ├── ThicknessToSelectiveThicknessConverter.cs
│ └── TotalWidthConverter.cs
├── DefaultControlTemplates.axaml
├── Devolutions.AvaloniaControls.csproj
├── EnumerableExtensions.cs
├── Enums
│ └── SortDirection.cs
├── Helpers
│ ├── MarkupExtensionHelpers.cs
│ └── ObservableHelpers.cs
├── INativeWindowAvaloniaHost.cs
├── MarkupExtensions
│ ├── AbstractMultipleValueBinding.cs
│ ├── AddBinding.cs
│ ├── AndBinding.cs
│ ├── BindingToggler.cs
│ ├── ChangeColorOpacity.cs
│ ├── DynamicResourceToggler.cs
│ ├── MultiplyBinding.cs
│ ├── OrBinding.cs
│ ├── WindowActiveBindingToggler.cs
│ ├── WindowActiveResourceToggler.cs
│ └── WindowIsActiveBinding.cs
├── Properties
│ └── AssemblyInfo.cs
└── README.md
├── Devolutions.AvaloniaTheme.DevExpress
├── Accents
│ ├── Icons.axaml
│ ├── Styles.axaml
│ └── ThemeResources.axaml
├── Controls
│ ├── Button.axaml
│ ├── ButtonSpinner.axaml
│ ├── CheckBox.axaml
│ ├── ComboBox.axaml
│ ├── ComboBoxItem.axaml
│ ├── ContextMenu.axaml
│ ├── DataGrid.axaml
│ ├── EditableComboBox.axaml
│ ├── EmbeddableControlRoot.axaml
│ ├── NumericUpDown.axaml
│ ├── ScrollBar.axaml
│ ├── ScrollViewer.axaml
│ ├── SplitButton.axaml
│ ├── TabControl.axaml
│ ├── TabItem.axaml
│ ├── TextBox.axaml
│ ├── TreeView.axaml
│ ├── TreeViewItem.axaml
│ ├── Window.axaml
│ └── _index.axaml
├── Converters
│ ├── CharToDevExpressPasswordCharConverter.cs
│ └── DevExpressConverters.cs
├── DevExpressTheme.axaml
├── Devolutions.AvaloniaTheme.DevExpress.csproj
└── README.md
├── Devolutions.AvaloniaTheme.Linux
├── Accents
│ ├── Icons.axaml
│ ├── Styles.axaml
│ └── ThemeResources.axaml
├── Controls
│ ├── Button.axaml
│ ├── ButtonSpinner.axaml
│ ├── CheckBox.axaml
│ ├── ContextMenu.axaml
│ ├── DataGrid.axaml
│ ├── EmbeddableControlRoot.axaml
│ ├── ListBox.axaml
│ ├── NumericUpDown.axaml
│ ├── TabControl.axaml
│ ├── TabItem.axaml
│ ├── TextBox.axaml
│ ├── Window.axaml
│ └── _index.axaml
├── Devolutions.AvaloniaTheme.Linux.csproj
├── LinuxTheme.axaml
└── README.md
└── Devolutions.AvaloniaTheme.MacOS
├── Accents
├── Assets
│ ├── Alternating_Row_Background_Dark.png
│ ├── Alternating_Row_Background_Light.png
│ └── TestIconForDesignPreview.svg
├── Icons.axaml
├── Light
│ └── ToggleSwitch.axaml
├── Shared
│ └── ToggleSwitch.axaml
├── Styles.axaml
└── ThemeResources.axaml
├── Controls
├── Button.axaml
├── ButtonSpinner.axaml
├── CheckBox.axaml
├── ComboBox.axaml
├── ComboBoxItem.axaml
├── ContextMenu.axaml
├── DataGrid.axaml
├── EditableComboBox.axaml
├── EmbeddableControlRoot.axaml
├── GridSplitter.axaml
├── Menu.axaml
├── MenuFlyoutPresenter.axaml
├── MenuItem.axaml
├── NumericUpDown.axaml
├── ScrollBar.axaml
├── ScrollViewer.axaml
├── Separator.axaml
├── TabControl.axaml
├── TabItem.axaml
├── TextBox.axaml
├── ToggleSwitch.axaml
├── ToolTip.axaml
├── TreeView.axaml
├── TreeViewItem.axaml
├── Window.axaml
└── _index.axaml
├── Converters
├── CharToMacOsPasswordCharConverter.cs
└── MacOSConverters.cs
├── Devolutions.AvaloniaTheme.MacOS.csproj
├── MacOSTheme.axaml
└── README.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.md]
2 | indent_style = space
3 | indent_size = 2
4 |
5 | [*.xml]
6 | indent_style = space
7 | indent_size = 2
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # File auto-generated and managed by Devops
2 | /.github/ @devolutions/devops @devolutions/architecture-maintainers
3 | /.github/dependabot.yml @devolutions/security-managers
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | /package/
4 | /packages/
5 | riderModule.iml
6 | /_ReSharper.Caches/
7 |
8 | # Rider
9 | .idea
10 | *.sln.DotSettings.user
11 |
12 | # VS Code
13 | .vs
14 |
15 | # local
16 | global.json
17 |
18 | # macOS
19 | .DS_Store
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Devolutions
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://devolutions.net/)
2 |
3 |
4 | # avalonia-themes
5 | Custom Avalonia Themes developed by [Devolutions](https://devolutions.net/)
6 |
7 | ➡️ [MacOS Theme](https://github.com/Devolutions/avalonia-themes/blob/master/src/Devolutions.AvaloniaTheme.MacOS/README.md)
8 |
9 | ➡️ [DevExpress Theme](https://github.com/Devolutions/avalonia-themes/blob/master/src/Devolutions.AvaloniaTheme.DevExpress/README.md)
10 |
11 | ➡️ [Linux Theme](https://github.com/Devolutions/avalonia-themes/blob/master/src/Devolutions.AvaloniaTheme.Linux/README.md)
12 |
13 | ➡️ [Avalonia Controls](https://github.com/Devolutions/avalonia-themes/blob/master/src/Devolutions.AvaloniaControls/README.md)
14 |
15 | # Sample App
16 |
17 | Contributors can use the SampleApp to test, debug and document styles for the various controls under each theme.
18 |
19 | ## Debugging
20 |
21 | The SampleApp attaches the Avalonia Dev Tools for inspecting controls (open with F12).
22 |
23 | If you own a licence for the new Dev Tools in _Avalonia Accelerate_, you can set an environment variable in your IDE's debug configuration.
24 | For example, in Rider:
25 |
26 | - Open **Run > Edit Configurations**
27 | - Pick your configuration for the SampleApp
28 | - In the **Environment Variables** field add `USE_AVALONIA_ACCELERATE_TOOLS=true`
29 |
30 | The F12 key then opens the new Dev Tools, and F10 opens the old version
--------------------------------------------------------------------------------
/avalonia-extensions.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApp", "samples\SampleApp\SampleApp.csproj", "{8FB0A38F-D80A-45A1-9796-FD22FDB14064}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Devolutions.AvaloniaTheme.MacOS", "src\Devolutions.AvaloniaTheme.MacOS\Devolutions.AvaloniaTheme.MacOS.csproj", "{052424E1-48F3-4D8E-A780-DEB4D33B4482}"
6 | EndProject
7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7756B42B-13EB-4DC9-BA61-11997466D93C}"
8 | EndProject
9 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{8D46D8D5-74CA-4EC1-ACA9-1AF9E5A92550}"
10 | EndProject
11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Devolutions.AvaloniaTheme.DevExpress", "src\Devolutions.AvaloniaTheme.DevExpress\Devolutions.AvaloniaTheme.DevExpress.csproj", "{DDDC64A4-451A-4496-841C-30C3C4BA62AE}"
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Devolutions.AvaloniaTheme.Linux", "src\Devolutions.AvaloniaTheme.Linux\Devolutions.AvaloniaTheme.Linux.csproj", "{2B21E358-E385-44C8-B346-8654E9D61377}"
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Devolutions.AvaloniaControls", "src\Devolutions.AvaloniaControls\Devolutions.AvaloniaControls.csproj", "{3652052E-B032-409A-AB43-C18CB6A18086}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {8FB0A38F-D80A-45A1-9796-FD22FDB14064}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {8FB0A38F-D80A-45A1-9796-FD22FDB14064}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {8FB0A38F-D80A-45A1-9796-FD22FDB14064}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {8FB0A38F-D80A-45A1-9796-FD22FDB14064}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {052424E1-48F3-4D8E-A780-DEB4D33B4482}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {052424E1-48F3-4D8E-A780-DEB4D33B4482}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {052424E1-48F3-4D8E-A780-DEB4D33B4482}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {052424E1-48F3-4D8E-A780-DEB4D33B4482}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {DDDC64A4-451A-4496-841C-30C3C4BA62AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {DDDC64A4-451A-4496-841C-30C3C4BA62AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {DDDC64A4-451A-4496-841C-30C3C4BA62AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {DDDC64A4-451A-4496-841C-30C3C4BA62AE}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {2B21E358-E385-44C8-B346-8654E9D61377}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {2B21E358-E385-44C8-B346-8654E9D61377}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {2B21E358-E385-44C8-B346-8654E9D61377}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {2B21E358-E385-44C8-B346-8654E9D61377}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {3652052E-B032-409A-AB43-C18CB6A18086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {3652052E-B032-409A-AB43-C18CB6A18086}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {3652052E-B032-409A-AB43-C18CB6A18086}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {3652052E-B032-409A-AB43-C18CB6A18086}.Release|Any CPU.Build.0 = Release|Any CPU
43 | EndGlobalSection
44 | GlobalSection(NestedProjects) = preSolution
45 | {052424E1-48F3-4D8E-A780-DEB4D33B4482} = {7756B42B-13EB-4DC9-BA61-11997466D93C}
46 | {8FB0A38F-D80A-45A1-9796-FD22FDB14064} = {8D46D8D5-74CA-4EC1-ACA9-1AF9E5A92550}
47 | {DDDC64A4-451A-4496-841C-30C3C4BA62AE} = {7756B42B-13EB-4DC9-BA61-11997466D93C}
48 | {2B21E358-E385-44C8-B346-8654E9D61377} = {7756B42B-13EB-4DC9-BA61-11997466D93C}
49 | {3652052E-B032-409A-AB43-C18CB6A18086} = {7756B42B-13EB-4DC9-BA61-11997466D93C}
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/samples/SampleApp/App.axaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/samples/SampleApp/App.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp;
2 |
3 | using System;
4 | using Avalonia;
5 | using Avalonia.Controls;
6 | using Avalonia.Controls.ApplicationLifetimes;
7 | using Avalonia.Markup.Xaml;
8 | using Avalonia.Styling;
9 | using Avalonia.Svg.Skia;
10 | using ViewModels;
11 |
12 | public class App : Application
13 | {
14 | private readonly Styles themeStylesContainer = new();
15 | private Styles? devExpressStyles;
16 | private Styles? linuxYaruStyles;
17 | private Styles? macOsStyles;
18 | private bool devToolsAttached;
19 | public static Theme? CurrentTheme { get; set; }
20 |
21 | public override void Initialize()
22 | {
23 | AvaloniaXamlLoader.Load(this);
24 |
25 | if (!Design.IsDesignMode)
26 | {
27 | this.Styles.Clear();
28 | this.Styles.Add(this.themeStylesContainer);
29 | }
30 |
31 | this.linuxYaruStyles = this.Resources["LinuxYaruStyles"] as Styles;
32 | this.devExpressStyles = this.Resources["DevExpressStyles"] as Styles;
33 | this.macOsStyles = this.Resources["MacOsStyles"] as Styles;
34 |
35 | GC.KeepAlive(typeof(Svg).Assembly);
36 | GC.KeepAlive(typeof(SvgImageExtension).Assembly);
37 |
38 | if (!Design.IsDesignMode)
39 | {
40 | Theme theme;
41 | if (OperatingSystem.IsWindows())
42 | theme = new DevExpressTheme();
43 | else if (OperatingSystem.IsMacOS())
44 | theme = new MacOsTheme();
45 | else if (OperatingSystem.IsLinux())
46 | theme = new LinuxYaruTheme();
47 | else
48 | theme = new MacOsTheme();
49 |
50 | SetTheme(theme);
51 | }
52 | }
53 |
54 | public static void SetTheme(Theme theme)
55 | {
56 | App app = (App)Current!;
57 | Theme? previousTheme = CurrentTheme;
58 | CurrentTheme = theme;
59 |
60 | bool reopenWindow = previousTheme != null && previousTheme.Name != theme.Name;
61 |
62 | Styles? styles = theme switch
63 | {
64 | LinuxYaruTheme => app.linuxYaruStyles,
65 | DevExpressTheme => app.devExpressStyles,
66 | MacOsTheme => app.macOsStyles,
67 | _ => null
68 | };
69 |
70 | app.themeStylesContainer.Clear();
71 | app.themeStylesContainer.AddRange(styles!);
72 |
73 | if (reopenWindow)
74 | if (app.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
75 | {
76 | Window? oldWindow = desktopLifetime.MainWindow;
77 | object? dataContext = oldWindow?.DataContext;
78 | MainWindow newWindow = new() { DataContext = dataContext };
79 | desktopLifetime.MainWindow = newWindow;
80 | newWindow.Show();
81 | oldWindow?.Close();
82 | }
83 | }
84 |
85 | public override void OnFrameworkInitializationCompleted()
86 | {
87 | if (this.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
88 | desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel() };
89 |
90 | base.OnFrameworkInitializationCompleted();
91 | }
92 |
93 | public void AttacheDevToolsOnce()
94 | {
95 | if (this.devToolsAttached) return;
96 |
97 | this.AttachDeveloperTools();
98 | this.devToolsAttached = true;
99 | }
100 | }
101 |
102 | public abstract class Theme
103 | {
104 | public abstract string Name { get; }
105 |
106 | public override bool Equals(object? obj)
107 | {
108 | if (obj is null) return false;
109 | if (ReferenceEquals(this, obj)) return true;
110 | if (obj.GetType() != this.GetType()) return false;
111 | return this.Equals((Theme)obj);
112 | }
113 |
114 | protected bool Equals(Theme other) =>
115 | this.Name == other.Name;
116 |
117 | public override int GetHashCode() =>
118 | this.Name.GetHashCode();
119 | }
120 |
121 | public class LinuxYaruTheme : Theme
122 | {
123 | public override string Name => "Linux - Yaru";
124 | }
125 |
126 | public class DevExpressTheme : Theme
127 | {
128 | public override string Name => "Windows - DevExpress";
129 | }
130 |
131 | public class MacOsTheme : Theme
132 | {
133 | public override string Name => "MacOS";
134 | }
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Add.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/AddThin.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Computer.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/CopyHost.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/CopyName.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/CopyPassword.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/CopyUserName.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/CopyUserNamePassword.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Details.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/DisableUser.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/EnableUser.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Folder.svg:
--------------------------------------------------------------------------------
1 |
9 |
10 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Help.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/HorizontalLine.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/More.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Padlock.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/PasswordAnalyser.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/PrivateKey.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/Properties.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/ResetPassword.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/SampleImage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devolutions/avalonia-extensions/ecdfd801ad6f5cc55fc447b7d93716e79739b8e9/samples/SampleApp/Assets/SampleImage.jpg
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/UnlockUser.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/samples/SampleApp/Assets/User.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ButtonDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Default
12 |
13 | accent
14 |
15 | Disabled
16 |
17 | /
18 |
19 | (MacOS: More precise look, but not responsive to user-selected accent colour)
20 |
21 |
22 |
23 |
24 | Default
25 |
26 | accent
27 |
28 | Disabled
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ButtonDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ButtonDemo : UserControl
6 | {
7 | public ButtonDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/CheckBoxDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
11 |
12 |
13 | Enabled
14 |
15 |
16 | Unchecked
17 | Checked
18 | Partially checked
19 |
20 |
21 | Disabled
22 |
23 |
24 | Unchecked
25 | Checked
26 |
30 | Partially checked
31 |
32 |
33 |
37 |
38 | Unchecked
39 | Checked
40 | Partially checked
41 |
42 |
43 | Unchecked
44 | Checked
45 |
49 | Partially checked
50 |
51 |
52 |
56 |
57 | Unchecked
58 | Checked
59 | Partially checked
60 |
61 |
62 | Unchecked
63 | Checked
64 |
69 | Partially checked
70 |
71 |
72 |
73 |
74 | Text wrapping
75 |
76 | Longer checkbox labels will wrap
77 | (Set bottom margin to 5 to make checkbox spacing larger than the line height)
78 |
79 |
80 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/CheckBoxDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class CheckBoxDemo : UserControl
6 | {
7 | public CheckBoxDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ComboBoxDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Preferred Usage Pattern:
12 |
13 |
14 | - all options fit,- sensible default pre-selected)
15 |
16 |
17 | Option 1
18 | Option 2
19 | Option 3 (Default)
20 | Option 4
21 |
22 |
23 | - explicit user choice required:
24 |
25 | Option 1
26 | Option 2
27 | Option 3
28 | Option 4
29 |
30 |
31 | Disabled
32 |
33 |
35 | Option 1
36 | Option 2
37 | Option 3
38 |
39 |
40 |
41 | Not ideal:
42 |
43 |
44 | - scrolling options list:
45 | (results in minor positioning bug)
46 |
47 |
49 | Option 1
50 | Option 2
51 | Option 3
52 | Option 4
53 | Option 5
54 | Option 6
55 | Option 7
56 | Option 8
57 | Option 9
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ComboBoxDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ComboBoxDemo : UserControl
6 | {
7 | public ComboBoxDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ContextMenuDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 | Right-click anywhere in this space
24 |
25 |
26 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ContextMenuDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ContextMenuDemo : UserControl
6 | {
7 | public ContextMenuDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ControlAlignment.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ControlAlignment : UserControl
6 | {
7 | public ControlAlignment()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/DataGridDemo.axaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | With
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/DataGridDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class DataGridDemo : UserControl
6 | {
7 | public DataGridDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/DataGridGroupedDemo.axaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/DataGridGroupedDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 | using ViewModels;
5 |
6 | public partial class DataGridGroupedDemo : UserControl
7 | {
8 | public DataGridGroupedDemo()
9 | {
10 | InitializeComponent();
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/EditableComboBoxDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class EditableComboBoxDemo : UserControl
6 | {
7 | public EditableComboBoxDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/GridSplitterDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/GridSplitterDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class GridSplitterDemo : UserControl
6 | {
7 | public GridSplitterDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/MenuDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class MenuDemo : UserControl
6 | {
7 | public MenuDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/MenuFlyoutDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
11 |
12 |
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 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/MenuFlyoutDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class MenuFlyoutDemo : UserControl
6 | {
7 | public MenuFlyoutDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/NumericUpDownDemo.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 | Watermark:
11 | 0 - 10 only:
12 | Disabled:
13 | Read-only:
14 | Error:
15 |
20 |
27 |
35 |
43 |
46 |
47 |
48 |
49 | Error
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/NumericUpDownDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class NumericUpDownDemo : UserControl
6 | {
7 | public NumericUpDownDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/Overview.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class Overview : UserControl
6 | {
7 | public Overview()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ScrollViewerDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ScrollViewerDemo : UserControl
6 | {
7 | public ScrollViewerDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/TabControlDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/TabControlDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class TabControlDemo : UserControl
6 | {
7 | public TabControlDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/TextBoxDemo.axaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 | With 'Clear' button
30 |
31 | Disabled Filled
32 | Reveal Password
33 | Password Revealed
34 | Custom Height:
35 |
36 |
37 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/TextBoxDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 | using ViewModels;
5 |
6 | public partial class TextBoxDemo : UserControl
7 | {
8 | public TextBoxDemo()
9 | {
10 | this.InitializeComponent();
11 | this.DataContext = new TextBoxViewModel();
12 | }
13 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ToggleSwitchDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | Toggle with Title
10 | Toggle
11 | Toggle
12 |
13 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ToggleSwitchDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ToggleSwitchDemo : UserControl
6 | {
7 | public ToggleSwitchDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ToolTipDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
13 | Hover over the question mark to see a tool tip above text
14 |
15 |
16 | Text Content
17 | Very long text content which should exceed the maximum with of the tooltip and wrap.
18 |
19 |
20 | Complex
21 |
22 | ToolTip Content
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/ToolTipDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class ToolTipDemo : UserControl
6 | {
7 | public ToolTipDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/DemoPages/TreeViewDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.DemoPages;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class TreeViewDemo : UserControl
6 | {
7 | public TreeViewDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/Experiments/SystemColoursDemo.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 | SystemAccentColorLight3
9 | SystemAccentColorLight2
10 | SystemAccentColorLight1
11 | SystemAccentColor
12 | SystemAccentColorDark1
13 | SystemAccentColorDark2
14 | SystemAccentColorDark3
15 | #CEE5FF
16 | #8CC3FF
17 | #4EA3FF
18 | #007AFF
19 | #005FC6
20 | #004B9D
21 | #00336A
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
37 |
--------------------------------------------------------------------------------
/samples/SampleApp/Experiments/SystemColoursDemo.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.Experiments;
2 |
3 | using Avalonia.Controls;
4 |
5 | public partial class SystemColoursDemo : UserControl
6 | {
7 | public SystemColoursDemo()
8 | {
9 | this.InitializeComponent();
10 | }
11 | }
--------------------------------------------------------------------------------
/samples/SampleApp/Experiments/ToggleButtonExperiments.axaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | Built-in Toggle Button:
10 | Test
11 |
12 | Button w. code-behind:
13 |
15 |
16 |
--------------------------------------------------------------------------------
/samples/SampleApp/Experiments/ToggleButtonExperiments.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.Experiments;
2 |
3 | using Avalonia.Controls;
4 | using Avalonia.Input;
5 | using Avalonia.Interactivity;
6 |
7 | public partial class ToggleButtonExperiments : UserControl
8 | {
9 | public ToggleButtonExperiments()
10 | {
11 | this.InitializeComponent();
12 | this.ToggleButton.Cursor = new Cursor(StandardCursorType.Cross);
13 | }
14 |
15 | private void Button_OnClickHandler(object? sender, RoutedEventArgs e)
16 | {
17 | this.ToggleButton.Content = this.ToggleButton.Content?.ToString() == "On" ? "Off" : "On";
18 | }
19 | }
--------------------------------------------------------------------------------
/samples/SampleApp/MainWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp;
2 |
3 | using System;
4 | using Avalonia;
5 | using Avalonia.Controls;
6 | using Avalonia.Controls.Primitives;
7 | using Avalonia.Input;
8 | using Avalonia.Styling;
9 |
10 | public partial class MainWindow : Window
11 | {
12 | public MainWindow()
13 | {
14 | this.InitializeComponent();
15 | #if DEBUG
16 | bool useAccelerate = Environment.GetEnvironmentVariable("USE_AVALONIA_ACCELERATE_TOOLS")?.ToLowerInvariant() == "true";
17 |
18 | if (useAccelerate)
19 | {
20 | // Enable Accelerate dev tools (AvaloniaUI.DiagnosticsSupport) - requiring a licence to use
21 | (Application.Current as App)?.AttacheDevToolsOnce();
22 | // Enable original free dev tools (Avalonia.Diagnostics) as an additional option available on F10
23 | this.AttachDevTools(new KeyGesture(Key.F10));
24 | }
25 | else
26 | {
27 | // Enable original free dev tools (Avalonia.Diagnostics)
28 | this.AttachDevTools();
29 | }
30 | #endif
31 | }
32 |
33 | private void Themes_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
34 | {
35 | SelectingItemsControl? cb = sender as SelectingItemsControl;
36 | if (cb?.SelectedItem is Theme newTheme) App.SetTheme(newTheme);
37 | }
38 |
39 | private void ThemeVariants_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
40 | {
41 | SelectingItemsControl? cb = sender as SelectingItemsControl;
42 | if (cb?.SelectedItem is ThemeVariant themeVariant) Application.Current!.RequestedThemeVariant = themeVariant;
43 | }
44 | }
--------------------------------------------------------------------------------
/samples/SampleApp/Models/DataGridItem.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.Models;
2 |
3 | public class DataGridItem
4 | {
5 | public DataGridItem(string itemType, string commonName, string accountName, string lastModified)
6 | {
7 | this.ItemType = itemType;
8 | this.CommonName = commonName;
9 | this.AccountName = accountName;
10 | this.LastModified = lastModified;
11 | }
12 |
13 | public string ItemType { get; set; }
14 | public string CommonName { get; set; }
15 | public string AccountName { get; set; }
16 | public string LastModified { get; set; }
17 | }
--------------------------------------------------------------------------------
/samples/SampleApp/Program.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp;
2 |
3 | using System;
4 | using Avalonia;
5 |
6 | internal class Program
7 | {
8 | // Initialization code. Don't use any Avalonia, third-party APIs or any
9 | // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
10 | // yet and stuff might break.
11 | [STAThread]
12 | public static void Main(string[] args) => BuildAvaloniaApp()
13 | .StartWithClassicDesktopLifetime(args);
14 |
15 | // Avalonia configuration, don't remove; also used by visual designer.
16 | public static AppBuilder BuildAvaloniaApp()
17 | => AppBuilder.Configure()
18 | .UsePlatformDetect()
19 | .WithInterFont()
20 | .LogToTrace();
21 | }
--------------------------------------------------------------------------------
/samples/SampleApp/SampleApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | WinExe
4 | net9.0
5 | enable
6 | true
7 | app.manifest
8 | true
9 |
10 |
11 |
12 |
13 | false
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | None
28 | All
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | EditableComboBoxDemo.axaml
53 | Code
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/samples/SampleApp/Styles.axaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | 16
6 | Bold
7 | 0,0,0,10
8 |
9 | "Courier New, Courier, monospace"
10 | #23b4c8
11 |
12 |
13 |
16 |
17 |
22 |
23 |
31 |
--------------------------------------------------------------------------------
/samples/SampleApp/ViewModels/DataGridGroupedViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.ViewModels;
2 |
3 | using System.Collections.Generic;
4 | using Avalonia.Collections;
5 | using CommunityToolkit.Mvvm.ComponentModel;
6 | using Models;
7 |
8 | public class DataGridGroupedViewModel : ObservableObject
9 | {
10 | public DataGridGroupedViewModel()
11 | {
12 | List items =
13 | [
14 | new("computer", "PDQ-VM", "PDQ-VM$", "6/26/2023"),
15 | new("user", "AD TEST Guy2", "ADGuysam", "5/2/2023"),
16 | new("user", "krbtgt", "krbtgt", "11/10/2021"),
17 | new("computer", "WIN11-VM-BT", "WIN11-VM-BT$", "11/12/2021"),
18 | new("computer", "RDS6", "RDS6$", "30/03/2021"),
19 | new("computer", "MSSQL1", "MSSQL1$", "14/10/2024"),
20 | new("computer", "ITMANGER-DRIVE", "ITMANGER-DRIVE$", "13/10/2021")
21 | ];
22 | this.Items = new DataGridCollectionView(items);
23 | this.Items.GroupDescriptions.Add(new DataGridPathGroupDescription("ItemType"));
24 | }
25 |
26 | public DataGridCollectionView Items { get; }
27 | }
--------------------------------------------------------------------------------
/samples/SampleApp/ViewModels/DataGridViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.ViewModels;
2 |
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using CommunityToolkit.Mvvm.ComponentModel;
6 | using Models;
7 |
8 | public class DataGridViewModel : ObservableObject
9 | {
10 | public DataGridViewModel()
11 | {
12 | List items = new()
13 | {
14 | new DataGridItem("computer", "PDQ-VM", "PDQ-VM$", "6/26/2023"),
15 | new DataGridItem("user", "AD TEST Guy2", "ADGuysam", "5/2/2023"),
16 | new DataGridItem("user", "krbtgt", "krbtgt", "11/10/2021"),
17 | new DataGridItem("computer", "WIN11-VM-BT", "WIN11-VM-BT$", "11/12/2021"),
18 | new DataGridItem("computer", "RDS6", "RDS6$", "30/03/2021"),
19 | new DataGridItem("computer", "MSSQL1", "MSSQL1$", "14/10/2024"),
20 | new DataGridItem("computer", "ITMANGER-DRIVE", "ITMANGER-DRIVE$", "13/10/2021")
21 | };
22 | this.Items = new ObservableCollection(items);
23 | }
24 |
25 | public ObservableCollection Items { get; }
26 | }
--------------------------------------------------------------------------------
/samples/SampleApp/ViewModels/MainWindowViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.ViewModels;
2 |
3 | using System.Linq;
4 | using CommunityToolkit.Mvvm.ComponentModel;
5 |
6 | public partial class MainWindowViewModel : ObservableObject
7 | {
8 | [ObservableProperty] private Theme[] availableThemes =
9 | [
10 | new LinuxYaruTheme(),
11 | new DevExpressTheme(),
12 | new MacOsTheme()
13 | ];
14 |
15 | [ObservableProperty] private Theme currentTheme;
16 |
17 | public MainWindowViewModel()
18 | {
19 | this.CurrentTheme = this.AvailableThemes.FirstOrDefault(t => Equals(t, App.CurrentTheme!))!;
20 | }
21 | }
--------------------------------------------------------------------------------
/samples/SampleApp/ViewModels/TextBoxViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp.ViewModels;
2 |
3 | using System.ComponentModel.DataAnnotations;
4 | using CommunityToolkit.Mvvm.ComponentModel;
5 |
6 | public partial class TextBoxViewModel : ObservableValidator
7 | {
8 | [ObservableProperty] [Required(ErrorMessage = "This Input is required.", AllowEmptyStrings = false)] [NotifyDataErrorInfo]
9 | private string _requiredInput = string.Empty;
10 | }
--------------------------------------------------------------------------------
/samples/SampleApp/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Devolutions.AvaloniaControls/Controls/EditableComboBox/EditableComboBoxMode.cs:
--------------------------------------------------------------------------------
1 | namespace Devolutions.AvaloniaControls.Controls;
2 |
3 | public enum EditableComboBoxMode
4 | {
5 | Normal = 0,
6 |
7 | Immediate = 1,
8 |
9 | Filter = 2
10 | }
--------------------------------------------------------------------------------
/src/Devolutions.AvaloniaControls/Controls/EditableComboBox/InnerTextBox.cs:
--------------------------------------------------------------------------------
1 | namespace Devolutions.AvaloniaControls.Controls;
2 |
3 | using Avalonia.Controls;
4 | using Avalonia.Input;
5 |
6 | public partial class EditableComboBox
7 | {
8 | public sealed class InnerTextBox : TextBox
9 | {
10 | protected override void OnGotFocus(GotFocusEventArgs e)
11 | {
12 | base.OnGotFocus(e);
13 | this.SelectAll();
14 | }
15 |
16 | public void TriggerOnKeyDown(KeyEventArgs e)
17 | {
18 | this.OnKeyDown(e);
19 | }
20 |
21 | protected override void OnKeyDown(KeyEventArgs e)
22 | {
23 | if (e.Handled) return;
24 |
25 | base.OnKeyDown(e);
26 |
27 | if (e.Key == Key.Up || e.Key == Key.Down) e.Handled = false;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Devolutions.AvaloniaControls/Controls/SearchHighlightTextBlock.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Devolutions.AvaloniaControls/Controls/SearchHighlightTextBlock.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace Devolutions.AvaloniaControls.Controls;
2 |
3 | using Avalonia;
4 | using Avalonia.Controls;
5 | using Avalonia.Media;
6 | using System;
7 |
8 | public class SearchHighlightTextBlock : ContentControl
9 | {
10 | public static readonly DirectProperty LeftTextProperty =
11 | AvaloniaProperty.RegisterDirect(nameof(LeftText), static o => o.leftText);
12 |
13 | public static readonly DirectProperty HighlightedTextProperty =
14 | AvaloniaProperty.RegisterDirect(nameof(HighlightedText), static o => o.highlightedText);
15 |
16 | public static readonly DirectProperty RightTextProperty =
17 | AvaloniaProperty.RegisterDirect(nameof(RightText), static o => o.rightText);
18 |
19 | public static readonly DirectProperty SearchProperty =
20 | AvaloniaProperty.RegisterDirect(nameof(Search), static o => o.Search, static (o, v) => o.Search = v);
21 |
22 | public static readonly StyledProperty HighlightBackgroundProperty =
23 | AvaloniaProperty.Register(nameof(HighlightBackground));
24 |
25 | public static readonly StyledProperty HighlightForegroundProperty =
26 | AvaloniaProperty.Register(nameof(HighlightForeground));
27 |
28 | private string highlightedText = string.Empty;
29 |
30 | private string leftText = string.Empty;
31 |
32 | private string rightText = string.Empty;
33 |
34 | private string? search;
35 |
36 | public SearchHighlightTextBlock()
37 | {
38 | this.GetObservable(ContentProperty).Subscribe(_ => this.ProcessHighlight());
39 | this.GetObservable(SearchProperty).Subscribe(_ => this.ProcessHighlight());
40 | this.ProcessHighlight();
41 | }
42 |
43 | public string LeftText => this.leftText;
44 |
45 | public string HighlightedText => this.highlightedText;
46 |
47 | public string RightText => this.rightText;
48 |
49 | public string? Search
50 | {
51 | get => this.search;
52 | set => this.SetAndRaise(SearchProperty, ref this.search, value);
53 | }
54 |
55 | public IBrush? HighlightBackground
56 | {
57 | get => this.GetValue(HighlightBackgroundProperty);
58 | set => this.SetValue(HighlightBackgroundProperty, value);
59 | }
60 |
61 | public IBrush? HighlightForeground
62 | {
63 | get => this.GetValue(HighlightForegroundProperty);
64 | set => this.SetValue(HighlightForegroundProperty, value);
65 | }
66 |
67 | private void ProcessHighlight()
68 | {
69 | string currentSearch = this.Search ?? string.Empty;
70 | string content = this.Content?.ToString() ?? string.Empty;
71 |
72 | var oldLeftText = this.leftText;
73 | var oldHighlightedText = this.highlightedText;
74 | var oldRightText = this.rightText;
75 |
76 | int highlightIndex = content.IndexOf(currentSearch, StringComparison.OrdinalIgnoreCase);
77 | if (highlightIndex >= 0)
78 | {
79 | this.leftText = content[..highlightIndex];
80 | this.highlightedText = content.Substring(highlightIndex, currentSearch.Length);
81 | this.rightText = content[(highlightIndex + currentSearch.Length)..];
82 | }
83 | else
84 | {
85 | this.leftText = content;
86 | this.highlightedText = string.Empty;
87 | this.rightText = string.Empty;
88 | }
89 |
90 | this.RaisePropertyChanged(LeftTextProperty, oldLeftText, this.leftText);
91 | this.RaisePropertyChanged(HighlightedTextProperty, oldHighlightedText, this.highlightedText);
92 | this.RaisePropertyChanged(RightTextProperty, oldRightText, this.rightText);
93 | }
94 | }
--------------------------------------------------------------------------------
/src/Devolutions.AvaloniaControls/Converters/BooleanToChoiceConverter.cs:
--------------------------------------------------------------------------------
1 | namespace Devolutions.AvaloniaControls.Converters;
2 |
3 | using System.Globalization;
4 | using Avalonia;
5 | using Avalonia.Data.Converters;
6 |
7 | public class BooleanToChoiceConverter : IMultiValueConverter
8 | {
9 | public object Convert(IList