├── .gitignore
├── CHANGELOG.txt
├── LICENSE.txt
├── README-EN.md
├── README.md
├── Rakefile
├── Samples
├── Stylet.Samples.DryIoC
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── DryIocStyletApplication.cs
│ ├── MainView.axaml
│ ├── MainView.axaml.cs
│ ├── MainViewModel.cs
│ ├── Program.cs
│ ├── Stylet.Samples.DryIoC.csproj
│ └── app.manifest
├── Stylet.Samples.Hello
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── MainView.axaml
│ ├── MainView.axaml.cs
│ ├── MainViewModel.cs
│ ├── Program.cs
│ ├── RootView.axaml
│ ├── RootView.axaml.cs
│ └── Stylet.Samples.Hello.csproj
├── Stylet.Samples.HelloDialog
│ ├── .gitignore
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── Dialog1View.axaml
│ ├── Dialog1View.axaml.cs
│ ├── Dialog1ViewModel.cs
│ ├── Program.cs
│ ├── ShellView.axaml
│ ├── ShellView.axaml.cs
│ ├── ShellViewModel.cs
│ └── Stylet.Samples.HelloDialog.csproj
├── Stylet.Samples.MSIoC
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── MainView.axaml
│ ├── MainView.axaml.cs
│ ├── MainViewModel.cs
│ ├── MsStyletApplication.cs
│ ├── Program.cs
│ ├── Stylet.Samples.MSIoC.csproj
│ └── app.manifest
├── Stylet.Samples.MasterDetail
│ ├── .gitignore
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── Program.cs
│ ├── ShellView.axaml
│ ├── ShellView.axaml.cs
│ ├── ShellViewModel.cs
│ └── Stylet.Samples.MasterDetail.csproj
├── Stylet.Samples.NavigationController
│ ├── .gitignore
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── NavigationController.cs
│ ├── Pages
│ │ ├── HeaderView.axaml
│ │ ├── HeaderView.axaml.cs
│ │ ├── HeaderViewModel.cs
│ │ ├── Page1View.axaml
│ │ ├── Page1View.axaml.cs
│ │ ├── Page1ViewModel.cs
│ │ ├── Page2View.axaml
│ │ ├── Page2View.axaml.cs
│ │ ├── Page2ViewModel.cs
│ │ ├── ShellView.axaml
│ │ ├── ShellView.axaml.cs
│ │ └── ShellViewModel.cs
│ ├── Program.cs
│ └── Stylet.Samples.NavigationController.csproj
├── Stylet.Samples.OverridingViewManager
│ ├── .gitignore
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── CustomViewManager.cs
│ ├── Program.cs
│ ├── ShellView.axaml
│ ├── ShellView.axaml.cs
│ ├── ShellViewModel.cs
│ └── Stylet.Samples.OverridingViewManager.csproj
└── Stylet.Samples.TabNavigation
│ ├── .gitignore
│ ├── App.axaml
│ ├── App.axaml.cs
│ ├── Page1View.axaml
│ ├── Page1View.axaml.cs
│ ├── Page1ViewModel.cs
│ ├── Page2View.axaml
│ ├── Page2View.axaml.cs
│ ├── Page2ViewModel.cs
│ ├── Program.cs
│ ├── ShellView.axaml
│ ├── ShellView.axaml.cs
│ ├── ShellViewModel.cs
│ └── Stylet.Samples.TabNavigation.csproj
├── Stylet.Avalonia.sln
├── Stylet.Avalonia
├── Assets
│ ├── error.png
│ ├── information.png
│ ├── question.png
│ └── warning.png
├── BindableCollection.cs
├── Conductor.cs
├── ConductorAllActive.cs
├── ConductorBase.cs
├── ConductorBaseWithActiveItem.cs
├── ConductorNavigating.cs
├── ConductorOneActive.cs
├── EventAggregator.cs
├── Execute.cs
├── ExpressionExtensions.cs
├── Extensions
│ └── EnumExtensions.cs
├── IConductor.cs
├── IDispatcher.cs
├── INotifyCollectionChanging.cs
├── INotifyPropertyChangedDispatcher.cs
├── IScreen.cs
├── IValidationAdapter.cs
├── IoC.cs
├── LabelledValue.cs
├── Logging
│ ├── ILogger.cs
│ ├── LogManager.cs
│ ├── NullLogger.cs
│ └── TraceLogger.cs
├── Primitive
│ ├── IMessageBoxViewModel.cs
│ ├── MessageBoxView.axaml
│ ├── MessageBoxView.axaml.cs
│ └── MessageBoxViewModel.cs
├── Properties
│ └── AssemblyInfo.cs
├── PropertyChangedBase.cs
├── PropertyChangedExtensions.cs
├── PropertyChangedWeakEventManager.cs
├── RelayCommand.cs
├── RoutedCommand.cs
├── Screen.cs
├── ScreenExtensions.cs
├── Stylet.Avalonia.csproj
├── StyletApplicationBase.cs
├── StyletConductorExtensions.cs
├── StyletIoC
│ ├── Creation
│ │ ├── BuilderTypeKey.cs
│ │ ├── BuilderUpper.cs
│ │ ├── ICreator.cs
│ │ ├── IRegistration.cs
│ │ └── IRegistrationContext.cs
│ ├── FluentInterface.cs
│ ├── IContainer.cs
│ ├── IInjectionAware.cs
│ ├── InjectAttribute.cs
│ ├── Internal
│ │ ├── AbstractFactoryBuilder.cs
│ │ ├── Builders
│ │ │ ├── BuilderAbstractFactoryBinding.cs
│ │ │ ├── BuilderBindTo.cs
│ │ │ ├── BuilderBindingBase.cs
│ │ │ ├── BuilderFactoryBinding.cs
│ │ │ ├── BuilderInstanceBinding.cs
│ │ │ ├── BuilderToAllImplementationsBinding.cs
│ │ │ └── BuilderTypeBinding.cs
│ │ ├── Container.cs
│ │ ├── Creators
│ │ │ ├── AbstractFactoryCreator.cs
│ │ │ ├── CreatorBase.cs
│ │ │ ├── FactoryCreator.cs
│ │ │ └── TypeCreator.cs
│ │ ├── IRegistrationCollection.cs
│ │ ├── RegistrationCollections
│ │ │ ├── EmptyRegistrationCollection.cs
│ │ │ ├── RegistrationCollection.cs
│ │ │ └── SingleRegistration.cs
│ │ ├── Registrations
│ │ │ ├── FuncRegistration.cs
│ │ │ ├── GetAllRegistration.cs
│ │ │ ├── InstanceRegistration.cs
│ │ │ ├── RegistrationBase.cs
│ │ │ ├── SingletonRegistration.cs
│ │ │ └── TransientRegistration.cs
│ │ ├── TypeExtensions.cs
│ │ ├── TypeKey.cs
│ │ └── UnboundGeneric.cs
│ ├── StyletApplication.cs
│ ├── StyletIoCBuilder.cs
│ ├── StyletIoCContainer.cs
│ ├── StyletIoCException.cs
│ └── StyletIoCModule.cs
├── ValidatingModelBase.cs
├── ViewManager.cs
├── WeakEventManagerBase.cs
├── WindowManager.cs
└── Xaml
│ ├── ActionBase.cs
│ ├── ActionExtension.cs
│ ├── ApplicationLoader.cs
│ ├── CommandAction.cs
│ ├── DebugConverter.cs
│ ├── EqualityConverter.cs
│ ├── EventAction.cs
│ ├── IconToBitmapSourceConverter.cs
│ ├── RethrowingBinding.cs
│ ├── StyletResourceDictionary.axaml
│ ├── StyletResourceDictionary.xaml
│ ├── StyletResourceDictionary1.xaml
│ └── View.cs
├── Stylet.sln.DotSettings
├── StyletIcon.png
└── StyletIcon.svg
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2023 sealoyal
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
13 | all 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
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README-EN.md:
--------------------------------------------------------------------------------
1 |  Stylet
2 | ======================================
3 |
4 | [中文文档](./README.md)
5 |
6 | [](https://www.nuget.org/packages/Stylet/)
7 | [](https://ci.appveyor.com/project/canton7/stylet)
8 |
9 | Introduction
10 | ------------
11 |
12 | Stylet is a small but powerful ViewModel-first MVVM framework for Avaloinia UI (.NET 4.5+ and .NET Core 3.0+), which allows you to write maintainable and extensible code in a way which is easy to test.
13 | Stylet's aims are to:
14 |
15 | - Solve the blockers, niggles, and annoyances which hamper MVVM development without a framework, using simple but powerful concepts.
16 | - Be obvious to people picking up your project for the first time: there's very little magic
17 | - Be easy to verify/validate. The LOC count is low, and it comes with a very comprehensive test suite. The code is well-written and well-documented.
18 | - Be flexible while providing sensible defaults. Almost any part of the framework can be overridden if you wish, but you probably won't want to.
19 |
20 | It is inspired by [Caliburn.Micro](http://caliburnmicro.com/), and shares many of its concepts, but removes most of the magic (replacing it with more powerful alternatives), and simplifies parts considerably by targeting only MVVM and Avaloinia UI .
21 |
22 |
23 | Getting Started
24 | ---------------
25 |
26 | ### Avaloinia UI >= 0.11.0-preview [requirement]
27 |
28 |
29 |
30 | > **Please see the sample project about how to use**
31 |
32 |
33 |
34 |
35 |
36 |
37 | Documentation
38 | -------------
39 |
40 | [The Wiki is the documentation source](https://github.com/canton7/Stylet/wiki).
41 | There's loads of information there - go and have a look, or start with the [Quick Start](https://github.com/canton7/Stylet/wiki/Quick-Start).
42 |
43 |
44 | Contributing
45 | ------------
46 |
47 | Contributions are always welcome.
48 | If you've got a problem or a question, [raise an issue](https://github.com/rsdte/Avalonia.Stylet/issues).
49 | If you've got code you want to contribute, please read [the Contributing guidelines](https://github.com/canton7/Stylet/wiki/Contributing) first of all.
50 | Create a feature branch off the `develop` branch, add your changes there, and submit it as a pull request.
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |  Stylet.Avalonia
2 | ======================================
3 |
4 | [英文文档](./README-EN.md)
5 |
6 | > 请注意本项目需要 AvaloniaUI 版本 >= 11.x
7 |
8 | ## 项目介绍
9 |
10 | `Stylet.Avalonia`是原来[Stylet](https://github.com/canton7/Stylet)项目对[AvaloniaUI](https://github.com/AvaloniaUI/Avalonia) 框架的适配。具体介绍请查看[Stylet项目介绍](https://github.com/canton7/Stylet)
11 |
12 | ## 快速开始
13 |
14 | 第一步:创建一个Avalonia框架类型的项目
15 |
16 | 第二步:nuget 管理器安装 `Stylet.Avalonia`包
17 |
18 | 第三步:创建`ShellViewModel`类,以及名为`ShellView`的窗口组件(`Avalonia Window`类型),其内容如下【其实啥也没动】
19 |
20 | - ShellViewModel.cs
21 |
22 | ```c#
23 | public class ShellViewModel
24 | {
25 |
26 | }
27 | ```
28 |
29 | - ShellView.axaml
30 |
31 | ```xaml
32 |
39 | Welcome to Avalonia!
40 |
41 | ```
42 |
43 | - ShellView.axaml.cs
44 |
45 | ```csharp
46 | public partial class ShellView : Window
47 | {
48 | public ShellView()
49 | {
50 | InitializeComponent();
51 | }
52 | }
53 | ```
54 |
55 |
56 | 第四步:找到并打开`App.axaml.cs`文件,使其继承于`StyletApplication`其中`T`为任一`ViewModel`,当前设置为第三步创建的`ShellViewModel`,修改后内容如下
57 |
58 | ```c#
59 | public partial class App : StyletApplication
60 | {
61 | public override void Initialize()
62 | {
63 | AvaloniaXamlLoader.Load(this);
64 | base.Initialize(); // 初始化stylet,不能去掉
65 | }
66 | }
67 | ```
68 |
69 | 第五步:运行。快乐的写代码吧!
70 |
71 | ## 其他
72 |
73 | 更多资料点击[这里](https://github.com/canton7/Stylet/wiki)跳转查看。同时,可以查看本仓库中存放的示例项目。
74 |
75 |
76 |
77 | ## 从 0.0.1升级?
78 |
79 | > 请将avalonia 升级到11.x,[升级指南](https://docs.avaloniaui.net/docs/next/stay-up-to-date/upgrade-from-0.10)
80 |
81 | 0.将`nuget`包`XamlNameReferenceGenerator`移除(新版本已内置)
82 |
83 | 1.找到并打开`App.axaml`文件,移除`AppBootstrapper`资源,即:
84 |
85 | ```xaml
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | ```
98 |
99 | 2.找到并打开`App.axaml.cs`文件,使其继承于`StyletApplication`, 此时`App.axaml.cs`成为了原来`AppBootstrapper`, 将原来的`AppBootstrapper.cs`的内容移到`App.axaml.cs`文件中即可。
100 |
101 | ***其注意***:`App.axaml.cs`文件内`Initialize()`方法必须调用`base.Initialize();`
102 |
103 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | CONFIG = ENV['CONFIG'] || 'Debug'
2 |
3 | COVERAGE_DIR = 'Coverage'
4 | COVERAGE_FILE = File.join(COVERAGE_DIR, 'coverage.xml')
5 |
6 | GITLINK_REMOTE = 'https://github.com/canton7/stylet'
7 | NUSPEC = 'NuGet/Stylet.nuspec'
8 | NUSPEC_START = 'NuGet/Stylet.start.nuspec'
9 |
10 | ASSEMBLY_INFO = 'Stylet/Properties/AssemblyInfo.cs'
11 |
12 | CSPROJ = 'Stylet/Stylet.csproj'
13 | TEMPLATES_CSPROJ = 'StyletTemplates/StyletTemplates.csproj'
14 | UNIT_TESTS = 'StyletUnitTests/StyletUnitTests.csproj'
15 |
16 | TEMPLATES_DIR = 'StyletTemplates/templates'
17 |
18 | directory COVERAGE_DIR
19 |
20 | desc "Build the project using the current CONFIG (or Debug)"
21 | task :build do
22 | sh 'dotnet', 'build', '-c', CONFIG, CSPROJ
23 | end
24 |
25 | desc "Run unit tests using the current CONFIG (or Debug)"
26 | task :test do
27 | sh 'dotnet', 'test', '-c', CONFIG, UNIT_TESTS
28 | end
29 |
30 | desc "Create NuGet package"
31 | task :package do
32 | # Not sure why these have to be this way around, but they do
33 | sh 'dotnet', 'pack', '--no-build', '-c', CONFIG, CSPROJ, "-p:NuSpecFile=../#{NUSPEC_START}"
34 | sh 'dotnet', 'pack', '--no-build', '-c', CONFIG, CSPROJ, '-p:IncludeSymbols=true'
35 | sh 'dotnet', 'pack', '-c', CONFIG, TEMPLATES_CSPROJ
36 | end
37 |
38 | desc "Bump version number"
39 | task :version, [:version] do |t, args|
40 | parts = args[:version].split('.')
41 | parts << '0' if parts.length == 3
42 | version = parts.join('.')
43 |
44 | content = IO.read(CSPROJ)
45 | content[/(.+?)<\/VersionPrefix>/, 1] = version
46 | File.open(CSPROJ, 'w'){ |f| f.write(content) }
47 |
48 | content = IO.read(TEMPLATES_CSPROJ)
49 | content[/(.+?)<\/VersionPrefix>/, 1] = version
50 | File.open(TEMPLATES_CSPROJ, 'w'){ |f| f.write(content) }
51 |
52 | content = IO.read(NUSPEC_START)
53 | content[/(.+?)<\/version>/, 1] = args[:version]
54 | content[%r{}, 1] = args[:version]
55 | File.open(NUSPEC_START, 'w'){ |f| f.write(content) }
56 |
57 | Dir[File.join(TEMPLATES_DIR, '**/*.csproj')].each do |csproj|
58 | content = IO.read(csproj)
59 | content[//, 1] = version
60 | File.open(csproj, 'w'){ |f| f.write(content) }
61 | end
62 | end
63 |
64 | desc "Extract StyletIoC as a standalone file"
65 | task :"extract-stylet-ioc" do
66 | filenames = Dir['Stylet/StyletIoC/**/*.cs']
67 | usings = Set.new
68 | files = []
69 |
70 | filenames.each do |file|
71 | contents = File.read(file)
72 | file_usings = contents.scan(/using .*?;$/)
73 | usings.merge(file_usings)
74 |
75 | matches = contents.match(/namespace (.+?)\n{\n(.+)}.*/m)
76 | namespace, file_contents = matches.captures
77 |
78 | files << {
79 | :from => file,
80 | :contents => file_contents,
81 | :namespace => namespace
82 | }
83 | # merged_contents << " // Originally from #{file}\n\n" << file_contents << "\n"
84 | end
85 |
86 | File.open('StyletIoC.cs', 'w') do |outf|
87 | outf.write(usings.to_a.join("\n"))
88 |
89 | outf.puts
90 |
91 | files.group_by{ |x| x[:namespace ] }.each do |namespace, ns_files|
92 | outf.puts("\nnamespace #{namespace}")
93 | outf.puts("{")
94 |
95 | ns_files.each do |file|
96 | outf.puts("\n // Originally from #{file[:from]}\n\n")
97 | outf.puts(file[:contents])
98 | end
99 |
100 | outf.puts("}\n")
101 | end
102 | end
103 |
104 | # puts merged_contents
105 |
106 | end
107 |
108 |
--------------------------------------------------------------------------------
/Samples/Stylet.Samples.DryIoC/App.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Samples/Stylet.Samples.DryIoC/App.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Markup.Xaml;
2 |
3 | namespace Stylet.Samples.DryIoC;
4 |
5 | public partial class App : DryIocStyletApplication
6 | {
7 | public override void Initialize()
8 | {
9 | AvaloniaXamlLoader.Load(this);
10 | base.Initialize();
11 | }
12 | }
--------------------------------------------------------------------------------
/Samples/Stylet.Samples.DryIoC/DryIocStyletApplication.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Avalonia.Controls;
6 | using DryIoc;
7 | using Stylet.Avalonia;
8 | using Stylet.Avalonia.Primitive;
9 |
10 | namespace Stylet.Samples.DryIoC;
11 |
12 | public class DryIocStyletApplication : StyletApplicationBase
13 | where T: class
14 | {
15 |
16 | ///
17 | /// Gets or sets the StyletApplication's IoC container. This is created after ConfigureIoC has been run.
18 | ///
19 | private readonly IContainer _container;
20 | private readonly List _assemblies;
21 |
22 | protected DryIocStyletApplication()
23 | {
24 | _container = new Container();
25 | _assemblies = new List();
26 | }
27 |
28 | ///
29 | /// Overridden from StyletApplicationBase, this sets up the IoC container
30 | ///
31 | protected sealed override void Configure()
32 | {
33 | var assemblies = this.LoadAssemblies();
34 | this._assemblies.AddRange(assemblies);
35 | this.ConfigureIoC(_container);
36 | this.AutoRegister();
37 | }
38 |
39 | protected virtual List LoadAssemblies()
40 | {
41 | var assembly = Assembly.GetAssembly(this.GetType());
42 | if (assembly is null)
43 | assembly = Assembly.GetExecutingAssembly();
44 | return new List { assembly };
45 | }
46 |
47 | protected override object GetInstance(Type type)
48 | {
49 | return this._container.Resolve(type);
50 | }
51 |
52 | protected override object GetInstance(Type service, string? key)
53 | {
54 | return this._container.Resolve(service, serviceKey: key);
55 | }
56 |
57 | protected override IEnumerable