Skip to content

Commit 0d13f06

Browse files
committed
防崩溃,AOT修复,文档完善
1 parent 2b22a57 commit 0d13f06

19 files changed

Lines changed: 1061 additions & 666 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,6 @@ coverage/
6767
# dev
6868
AgentHelper/
6969
Task.md
70-
manual/dev
70+
manual/dev
71+
build.ps1
72+
build.sh

Demo/AutoSettingUI.Avalonia.CrossPlatform.Demo/AutoSettingUI.Avalonia.CrossPlatform.Demo/App.axaml.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using Avalonia.Markup.Xaml;
77
using AutoSettingUI.Avalonia.CrossPlatform.Demo.ViewModels;
88
using AutoSettingUI.Avalonia.CrossPlatform.Demo.Views;
9+
using AutoSettingUI.Core.Registry;
10+
using AutoSettingUI.Generated;
911

1012
namespace AutoSettingUI.Avalonia.CrossPlatform.Demo;
1113

@@ -23,13 +25,17 @@ public override void OnFrameworkInitializationCompleted()
2325
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
2426
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
2527
DisableAvaloniaDataAnnotationValidation();
28+
2629
desktop.MainWindow = new MainWindow
2730
{
2831
DataContext = new MainViewModel()
2932
};
3033
}
3134
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
3235
{
36+
var provider = new GeneratedSettingProvider();
37+
AotSettingRegistry.Provider = provider;
38+
AotSettingRegistry.Accessor = provider;
3339
singleViewPlatform.MainView = new MainView
3440
{
3541
DataContext = new MainViewModel()
@@ -51,4 +57,4 @@ private void DisableAvaloniaDataAnnotationValidation()
5157
BindingPlugins.DataValidators.Remove(plugin);
5258
}
5359
}
54-
}
60+
}

Demo/AutoSettingUI.Ursa.Demo/App.axaml.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using Avalonia.Data.Core.Plugins;
55
using System.Linq;
66
using Avalonia.Markup.Xaml;
7+
using AutoSettingUI.Core.Registry;
8+
using AutoSettingUI.Generated;
79
using AutoSettingUI.Ursa.Demo.ViewModels;
810
using AutoSettingUI.Ursa.Demo.Views;
911

@@ -23,6 +25,7 @@ public override void OnFrameworkInitializationCompleted()
2325
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
2426
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
2527
DisableAvaloniaDataAnnotationValidation();
28+
2629
desktop.MainWindow = new MainWindow
2730
{
2831
DataContext = new MainWindowViewModel(),
@@ -44,4 +47,4 @@ private void DisableAvaloniaDataAnnotationValidation()
4447
BindingPlugins.DataValidators.Remove(plugin);
4548
}
4649
}
47-
}
50+
}

Demo/AutoSettingUI.Ursa.Demo/Models/ApplicationSettings.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ public class ExtendedControlsSettings
344344
[TimePicker]
345345
public TimeSpan PreferredTime { get; set; } = DateTime.Now.TimeOfDay;
346346

347-
[Title("Toggle Feature")]
348347
[CheckBox]
349348
public bool EnableAdvancedFeature { get; set; } = true;
350349

README.md

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,77 +30,122 @@ Install the package for your preferred UI framework:
3030
3131
## Quick Start
3232

33-
### 1. Define Your Settings Class
33+
This section shows a minimal end-to-end setup using the current demos as reference. It covers Avalonia, Ursa, and WPF, plus AOT support.
34+
35+
### 1. Add Packages / References
36+
37+
```xml
38+
<!-- Avalonia -->
39+
<PackageReference Include="AutoSettingUI.Avalonia" Version="1.0.0" />
40+
41+
<!-- Ursa (Avalonia with Ursa theme) -->
42+
<PackageReference Include="AutoSettingUI.Ursa" Version="1.0.0" />
43+
44+
<!-- WPF -->
45+
<PackageReference Include="AutoSettingUI.WPF" Version="1.0.0" />
46+
```
47+
48+
If you want AOT support, also reference the generator in your **app** project:
49+
50+
```xml
51+
<ProjectReference Include="..\..\src\AutoSettingUI.Generator\AutoSettingUI.Generator.csproj"
52+
OutputItemType="Analyzer"
53+
ReferenceOutputAssembly="false" />
54+
```
55+
56+
### 2. Define a Settings Model
3457

3558
```csharp
3659
using AutoSettingUI.Core.Attributes;
60+
using AutoSettingUI.Avalonia.Attributes; // or AutoSettingUI.Ursa.Attributes
3761
38-
[SettingUI(Category = "General", Order = 0)]
39-
[MainHeader("Application Settings")]
40-
public class AppSettings
62+
[SettingUI]
63+
public sealed class AppSettings
4164
{
42-
[Title("App Name")]
43-
public string Name { get; set; } = "My App";
65+
[Title("Volume")]
66+
[ControlBinding(typeof(Avalonia.Controls.Slider), "Value", nameof(CreateVolume))]
67+
public double Volume { get; set; } = 50;
4468

45-
[Title("Enable Dark Mode")]
46-
public bool DarkMode { get; set; }
69+
public Avalonia.Controls.Slider CreateVolume()
70+
=> new Avalonia.Controls.Slider { Minimum = 0, Maximum = 100, Value = 50 };
4771

48-
[Title("Volume"), Range(0, 100)]
49-
public int Volume { get; set; } = 50;
72+
[Title("Enable Feature")]
73+
[CheckBox]
74+
public bool EnableFeature { get; set; } = true;
5075

51-
[Title("Language")]
52-
[ItemsSource(typeof(AppSettings), nameof(AvailableLanguages))]
53-
public string Language { get; set; } = "en-US";
76+
[Title("Font Size")]
77+
[NumericUpDown(Minimum = 8, Maximum = 32, Increment = 1)]
78+
public int FontSize { get; set; } = 14;
5479

55-
public static string[] AvailableLanguages => ["en-US", "zh-CN", "ja-JP"];
80+
[Title("Tags")]
81+
public System.Collections.ObjectModel.ObservableCollection<string> Tags { get; set; }
82+
= new() { "Important", "Work" };
5683
}
5784
```
5885

59-
### 2. Add the Panel to Your UI
86+
### 3. Bind the Panel
6087

61-
#### Avalonia
88+
Avalonia:
6289

6390
```xml
6491
<Window xmlns:auto="clr-namespace:AutoSettingUI.Avalonia.Controls;assembly=AutoSettingUI.Avalonia">
65-
<auto:AvaloniaAutoSettingPanel
66-
Title="Settings"
67-
Targets="{Binding SettingsList}"
68-
ShowNavigation="True" />
92+
<auto:AvaloniaAutoSettingPanel Targets="{Binding Targets}" />
6993
</Window>
7094
```
7195

72-
#### Ursa
96+
Ursa:
7397

7498
```xml
7599
<Window xmlns:ursa="clr-namespace:AutoSettingUI.Ursa.Controls;assembly=AutoSettingUI.Ursa">
76-
<ursa:UrsaAutoSettingPanel
77-
Title="Settings"
78-
Targets="{Binding SettingsList}"
79-
UseCardBorderTheme="True" />
100+
<ursa:UrsaAutoSettingPanel Targets="{Binding Targets}" />
80101
</Window>
81102
```
82103

83-
#### WPF
104+
WPF:
84105

85106
```xml
86107
<Window xmlns:auto="clr-namespace:AutoSettingUI.WPF.Controls;assembly=AutoSettingUI.WPF">
87-
<auto:WpfAutoSettingPanel
88-
Title="Settings"
89-
Targets="{Binding SettingsList}"
90-
ShowNavigation="True" />
108+
<auto:WpfAutoSettingPanel Targets="{Binding Targets}" />
91109
</Window>
92110
```
93111

94-
### 3. AOT Support (Optional)
112+
ViewModel:
113+
114+
```csharp
115+
public class MainViewModel
116+
{
117+
public IEnumerable<object> Targets { get; } = new object[]
118+
{
119+
new AppSettings()
120+
};
121+
}
122+
```
123+
124+
### 4. AOT Support (Optional)
95125

96-
For Native AOT or trimming support, use the generated provider:
126+
For Native AOT or trimming, make sure the generator is referenced by the **app** project. In most cases the generated provider is picked up automatically. If you want to force it (or you see fallback-to-TextBox in AOT), do:
97127

98128
```csharp
99-
// The source generator creates this class automatically
100-
panel.DescriptorProvider = new AutoSettingUI.Generated.GeneratedSettingProvider();
101-
panel.PropertyAccessor = new AutoSettingUI.Generated.GeneratedSettingProvider();
129+
using AutoSettingUI.Core.Registry;
130+
using AutoSettingUI.Generated;
131+
132+
var provider = new GeneratedSettingProvider();
133+
AotSettingRegistry.Provider = provider;
134+
AotSettingRegistry.Accessor = provider;
135+
```
136+
137+
### 5. Publish AOT (Example)
138+
139+
```bash
140+
# Ursa demo
141+
pwsh ./publish-demo.ps1 -Framework Avalonia -Mode AOT
102142
```
103143

144+
### Notes
145+
146+
- Use `EmitCompilerGeneratedFiles=true` if you want to inspect generated code.
147+
- `CollectionEditor(AllowEditItems = false)` can make collection rows read-only.
148+
104149
## Extended Controls
105150

106151
AutoSettingUI provides extended control attributes for specialized inputs:

README.zh-CN.md

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,77 +30,122 @@
3030
3131
## 快速上手
3232

33-
### 1. 定义设置类
33+
这部分基于 demo 的最小端到端使用示例,覆盖 Avalonia、Ursa、WPF,并包含 AOT 支持。
34+
35+
### 1. 添加包 / 引用
36+
37+
```xml
38+
<!-- Avalonia -->
39+
<PackageReference Include="AutoSettingUI.Avalonia" Version="1.0.0" />
40+
41+
<!-- Ursa (带 Ursa 主题的 Avalonia) -->
42+
<PackageReference Include="AutoSettingUI.Ursa" Version="1.0.0" />
43+
44+
<!-- WPF -->
45+
<PackageReference Include="AutoSettingUI.WPF" Version="1.0.0" />
46+
```
47+
48+
如需 AOT 支持,请在 **应用项目** 中额外引用源代码生成器:
49+
50+
```xml
51+
<ProjectReference Include="..\..\src\AutoSettingUI.Generator\AutoSettingUI.Generator.csproj"
52+
OutputItemType="Analyzer"
53+
ReferenceOutputAssembly="false" />
54+
```
55+
56+
### 2. 定义设置模型
3457

3558
```csharp
3659
using AutoSettingUI.Core.Attributes;
60+
using AutoSettingUI.Avalonia.Attributes; // 或 AutoSettingUI.Ursa.Attributes
3761
38-
[SettingUI(Category = "通用", Order = 0)]
39-
[MainHeader("应用设置")]
40-
public class AppSettings
62+
[SettingUI]
63+
public sealed class AppSettings
4164
{
42-
[Title("应用名称")]
43-
public string Name { get; set; } = "我的应用";
65+
[Title("Volume")]
66+
[ControlBinding(typeof(Avalonia.Controls.Slider), "Value", nameof(CreateVolume))]
67+
public double Volume { get; set; } = 50;
4468

45-
[Title("启用深色模式")]
46-
public bool DarkMode { get; set; }
69+
public Avalonia.Controls.Slider CreateVolume()
70+
=> new Avalonia.Controls.Slider { Minimum = 0, Maximum = 100, Value = 50 };
4771

48-
[Title("音量"), Range(0, 100)]
49-
public int Volume { get; set; } = 50;
72+
[Title("Enable Feature")]
73+
[CheckBox]
74+
public bool EnableFeature { get; set; } = true;
5075

51-
[Title("语言")]
52-
[ItemsSource(typeof(AppSettings), nameof(AvailableLanguages))]
53-
public string Language { get; set; } = "zh-CN";
76+
[Title("Font Size")]
77+
[NumericUpDown(Minimum = 8, Maximum = 32, Increment = 1)]
78+
public int FontSize { get; set; } = 14;
5479

55-
public static string[] AvailableLanguages => ["zh-CN", "en-US", "ja-JP"];
80+
[Title("Tags")]
81+
public System.Collections.ObjectModel.ObservableCollection<string> Tags { get; set; }
82+
= new() { "Important", "Work" };
5683
}
5784
```
5885

59-
### 2. 在界面中添加面板
86+
### 3. 绑定面板
6087

61-
#### Avalonia
88+
Avalonia:
6289

6390
```xml
6491
<Window xmlns:auto="clr-namespace:AutoSettingUI.Avalonia.Controls;assembly=AutoSettingUI.Avalonia">
65-
<auto:AvaloniaAutoSettingPanel
66-
Title="设置"
67-
Targets="{Binding SettingsList}"
68-
ShowNavigation="True" />
92+
<auto:AvaloniaAutoSettingPanel Targets="{Binding Targets}" />
6993
</Window>
7094
```
7195

72-
#### Ursa
96+
Ursa:
7397

7498
```xml
7599
<Window xmlns:ursa="clr-namespace:AutoSettingUI.Ursa.Controls;assembly=AutoSettingUI.Ursa">
76-
<ursa:UrsaAutoSettingPanel
77-
Title="设置"
78-
Targets="{Binding SettingsList}"
79-
UseCardBorderTheme="True" />
100+
<ursa:UrsaAutoSettingPanel Targets="{Binding Targets}" />
80101
</Window>
81102
```
82103

83-
#### WPF
104+
WPF:
84105

85106
```xml
86107
<Window xmlns:auto="clr-namespace:AutoSettingUI.WPF.Controls;assembly=AutoSettingUI.WPF">
87-
<auto:WpfAutoSettingPanel
88-
Title="设置"
89-
Targets="{Binding SettingsList}"
90-
ShowNavigation="True" />
108+
<auto:WpfAutoSettingPanel Targets="{Binding Targets}" />
91109
</Window>
92110
```
93111

94-
### 3. AOT 支持(可选)
112+
ViewModel:
113+
114+
```csharp
115+
public class MainViewModel
116+
{
117+
public IEnumerable<object> Targets { get; } = new object[]
118+
{
119+
new AppSettings()
120+
};
121+
}
122+
```
123+
124+
### 4. AOT 支持(可选)
95125

96-
如需支持 Native AOT 或裁剪发布,使用源生成器生成的提供者
126+
如需 Native AOT 或裁剪发布,请确保生成器在 **应用项目** 中被引用。多数情况下会自动使用生成的 Provider。如果 AOT 下出现回退为 TextBox,可以手动指定
97127

98128
```csharp
99-
// 源生成器会自动创建此类
100-
panel.DescriptorProvider = new AutoSettingUI.Generated.GeneratedSettingProvider();
101-
panel.PropertyAccessor = new AutoSettingUI.Generated.GeneratedSettingProvider();
129+
using AutoSettingUI.Core.Registry;
130+
using AutoSettingUI.Generated;
131+
132+
var provider = new GeneratedSettingProvider();
133+
AotSettingRegistry.Provider = provider;
134+
AotSettingRegistry.Accessor = provider;
135+
```
136+
137+
### 5. 发布 AOT(示例)
138+
139+
```bash
140+
# Ursa demo
141+
pwsh ./publish-demo.ps1 -Framework Avalonia -Mode AOT
102142
```
103143

144+
### 说明
145+
146+
- 需要查看生成代码时,可启用 `EmitCompilerGeneratedFiles=true`
147+
- `CollectionEditor(AllowEditItems = false)` 可将集合行设为只读。
148+
104149
## 扩展控件
105150

106151
AutoSettingUI 提供了多种扩展控件特性,用于特殊输入场景:

0 commit comments

Comments
 (0)