返回提交历史
Modified
SpaceEngineersBlueprintEditor/App.xaml.cs
+13
-1
Added
SpaceEngineersBlueprintEditor/Implements/Services/MessageService.cs
+125
-0
Modified
SpaceEngineersBlueprintEditor/Implements/Services/NavigationService.cs
+5
-5
Modified
SpaceEngineersBlueprintEditor/Implements/Services/NavigationViewService.cs
+5
-5
Modified
SpaceEngineersBlueprintEditor/Interface/Services/IMessageService.cs
+15
-2
Modified
SpaceEngineersBlueprintEditor/SpaceEngineersBlueprintEditor.csproj
+6
-0
Modified
SpaceEngineersBlueprintEditor/Strings/en-us/Resources.resw
+4
-0
Modified
SpaceEngineersBlueprintEditor/Utilities/BlueprintsManager.cs
+1
-1
Modified
SpaceEngineersBlueprintEditor/ViewModels/AppShellPageViewModel.cs
+1
-0
Modified
SpaceEngineersBlueprintEditor/ViewModels/BlueprintEditPageViewModel.cs
+1
-15
Modified
SpaceEngineersBlueprintEditor/ViewModels/BlueprintsViewPageViewModel.cs
+42
-18
Added
SpaceEngineersBlueprintEditor/ViewModels/MainPageViewModel.cs
+40
-0
Modified
SpaceEngineersBlueprintEditor/Views/AppShellPage.xaml
+12
-1
Modified
SpaceEngineersBlueprintEditor/Views/AppShellPage.xaml.cs
+36
-1
Modified
SpaceEngineersBlueprintEditor/Views/BlueprintEditPage.xaml
+1
-34
Modified
SpaceEngineersBlueprintEditor/Views/BlueprintEditPage.xaml.cs
+0
-8
Modified
SpaceEngineersBlueprintEditor/Views/BlueprintsViewPage.xaml
+27
-4
Modified
SpaceEngineersBlueprintEditor/Views/BlueprintsViewPage.xaml.cs
+10
-0
Added
SpaceEngineersBlueprintEditor/Views/MainPage.xaml
+50
-0
Added
SpaceEngineersBlueprintEditor/Views/MainPage.xaml.cs
+27
-0
SpaceEngineersModDev/SpaceEngineersBlueprintEditorInWinUI
完善全局消息显示
7bc730a
代码差异
20 个文件
+421
-95
@@ -1,4 +1,5 @@
1
using SpaceEngineersBlueprintEditor.Utilities;
1
using SpaceEngineersBlueprintEditor.Interface.Services;
2
using SpaceEngineersBlueprintEditor.Utilities;
2
3
using SpaceEngineersBlueprintEditor.Views;
3
4
4
5
namespace SpaceEngineersBlueprintEditor;
@@ -13,10 +14,21 @@ public partial class App : Application
13
14
{
14
15
this.InitializeComponent();
15
16
PageManager.RegisterPage(typeof(AppShellPage));
17
PageManager.RegisterPage(typeof(MainPage));
16
18
PageManager.RegisterPage(typeof(BlueprintEditPage));
17
19
PageManager.RegisterPage(typeof(BlueprintsViewPage));
18
20
PageManager.RegisterPage(typeof(SettingPage));
19
21
Task.Run(BlueprintsManager.LoadBlueprintsAsync);
22
UnhandledException += App_UnhandledException;
23
}
24
25
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
26
{
27
if (GlobalServiceManager.GetService<IMessageService>() is IMessageService messageService)
28
{
29
messageService.ShowMessage(e.Message, "错误:", InfoBarSeverity.Error);
30
e.Handled = true;
31
}
20
32
}
21
33
22
34
/// <summary>
@@ -0,0 +1,125 @@
1
using Microsoft.UI.Dispatching;
2
using SpaceEngineersBlueprintEditor.Interface.Services;
3
using System.Collections.ObjectModel;
4
using System.Diagnostics.CodeAnalysis;
5
using XFEExtension.NetCore.StringExtension;
6
7
namespace SpaceEngineersBlueprintEditor.Implements.Services;
8
9
class MessageService : GlobalServiceBase, IMessageService
10
{
11
private StackPanel? messageStackPanel;
12
private DispatcherQueue? _dispatcherQueue;
13
private readonly Dictionary<string, InfoBar> messageStack = [];
14
15
public ReadOnlyDictionary<string, InfoBar> MessageStack => new(messageStack);
16
17
public InfoBar? GetMessage(string messageId) => messageStack.TryGetValue(messageId, out InfoBar? value) ? value : null;
18
19
[MemberNotNull(nameof(messageStackPanel), nameof(_dispatcherQueue))]
20
public void Initialize(StackPanel stackPanel, DispatcherQueue dispatcherQueue)
21
{
22
messageStackPanel = stackPanel;
23
_dispatcherQueue = dispatcherQueue;
24
}
25
26
public bool RemoveMessage(string messageId)
27
{
28
if (messageStackPanel is not null && messageStack.TryGetValue(messageId, out InfoBar? value))
29
{
30
messageStackPanel.Children.Remove(value);
31
return true;
32
}
33
return false;
34
}
35
36
public bool ShowMessage(string message, string title = "", object? content = null, InfoBarSeverity severity = InfoBarSeverity.Informational, double time = 5, bool canClose = true, string buttonText = "", Action<object, RoutedEventArgs>? callBackAction = null, string messageId = "")
37
{
38
return _dispatcherQueue is not null && _dispatcherQueue.TryEnqueue(() =>
39
{
40
ShowMessage(ConstructInfoBar(message, title, content, severity, canClose, buttonText, callBackAction), time, messageId);
41
});
42
}
43
44
public bool ShowMessage(InfoBar infoBar, double time = -1, string messageId = "")
45
{
46
if (messageId.IsNullOrEmpty())
47
messageId = Guid.NewGuid().ToString();
48
if (messageStack.TryAdd(messageId, infoBar) && messageStackPanel is not null)
49
{
50
infoBar.Closed += InfoBar_Closed;
51
StartTimeCounter(infoBar, time);
52
messageStackPanel.Children.Add(infoBar);
53
return true;
54
}
55
return false;
56
}
57
58
private void InfoBar_Closed(InfoBar sender, InfoBarClosedEventArgs args)
59
{
60
string messageId = "";
61
foreach (var entry in messageStack)
62
if (entry.Value == sender)
63
messageId = entry.Key;
64
if (messageStack.ContainsKey(messageId))
65
{
66
messageStackPanel?.Children.Remove(sender);
67
messageStack.Remove(messageId);
68
}
69
}
70
71
public bool ShowMessageWithId(string messageId, string message, string title = "", InfoBarSeverity severity = InfoBarSeverity.Informational, double time = 5) => ShowMessage(message, title, null, severity, time, true, "", null, messageId);
72
73
public void Clear()
74
{
75
foreach (var entry in messageStack)
76
RemoveMessage(entry.Key);
77
}
78
79
private void StartTimeCounter(InfoBar infoBar, double time) => Task.Run(async () =>
80
{
81
await Task.Delay(TimeSpan.FromSeconds(time));
82
string messageId = "";
83
foreach (var entry in messageStack)
84
if (entry.Value == infoBar)
85
messageId = entry.Key;
86
_dispatcherQueue?.TryEnqueue(() =>
87
{
88
if (messageStack.ContainsKey(messageId))
89
{
90
messageStackPanel?.Children.Remove(infoBar);
91
messageStack.Remove(messageId);
92
}
93
});
94
});
95
96
private static InfoBar ConstructInfoBar(string message, string title, object? content, InfoBarSeverity severity, bool canClose, string buttonText, Action<object, RoutedEventArgs>? callBackAction)
97
{
98
var infoBar = new InfoBar()
99
{
100
Message = message,
101
Title = title,
102
IsOpen = true,
103
Severity = severity,
104
IsClosable = canClose
105
};
106
if (content is not null)
107
infoBar.Content = content;
108
if (buttonText is not null && callBackAction is not null)
109
{
110
var actionButton = new Button
111
{
112
Content = buttonText
113
};
114
actionButton.Click += (sender, e) => callBackAction.Invoke(sender, e);
115
infoBar.ActionButton = actionButton;
116
}
117
return infoBar;
118
}
119
120
public bool ShowMessage(string message, string title = "") => ShowMessage(message, title, InfoBarSeverity.Informational);
121
122
public bool ShowMessage(string message, string title, InfoBarSeverity severity) => ShowMessageWithId("", message, title, severity);
123
124
public bool ShowButtonMessage(string message, string title, string buttonText, Action<object, RoutedEventArgs> callBackAction, InfoBarSeverity severity = InfoBarSeverity.Informational, bool canClose = true) => ShowMessage(message, title, null, severity, -1, true, buttonText, callBackAction, "");
125
}
@@ -10,7 +10,7 @@ internal class NavigationService : GlobalServiceBase, INavigationService
10
10
private Frame? frame;
11
11
private readonly List<(Page, object?)> navigationStack = [];
12
12
public bool CanGoBack => navigationStack.Count > 1;
13
public bool CanGoForward => Frame is not null && Frame.CanGoForward;
13
public bool CanGoForward => frame is not null && frame.CanGoForward;
14
14
public Frame? Frame { get => frame; set => frame = value; }
15
15
16
16
public List<(Page, object?)> NavigationStack => navigationStack;
@@ -19,11 +19,11 @@ internal class NavigationService : GlobalServiceBase, INavigationService
19
19
20
20
public void GoBack() => NavigateTo(navigationStack[^2].Item1.GetType(), navigationStack[^2].Item2, true);
21
21
22
public void GoForward() => Frame?.GoForward();
22
public void GoForward() => frame?.GoForward();
23
23
24
24
public void NavigateTo(Type type, object? parameter = null, bool goBack = false)
25
25
{
26
if (Frame is not null && (navigationStack.Count == 0 || navigationStack.Last().Item1.GetType() != type || parameter is not null && navigationStack.Last().Item2 != parameter))
26
if (frame is not null && (navigationStack.Count == 0 || navigationStack.Last().Item1.GetType() != type || parameter is not null && navigationStack.Last().Item2 != parameter))
27
27
{
28
28
if (!PageManager.CurrentPages.TryGetValue(type.FullName!, out var currentPage))
29
29
{
@@ -51,8 +51,8 @@ internal class NavigationService : GlobalServiceBase, INavigationService
51
51
slideUpAnimation.InsertKeyFrame(1f, new Vector3(0, 0, 0), compositor.CreateCubicBezierEasingFunction(new Vector2(0.1f, 0.0f), new Vector2(0.0f, 1f)));
52
52
slideUpAnimation.Duration = TimeSpan.FromSeconds(0.3);
53
53
pageCompositor.StartAnimation("Offset", slideUpAnimation);
54
Frame.Content = currentPage;
55
Navigated?.Invoke(Frame, type);
54
frame.Content = currentPage;
55
Navigated?.Invoke(frame, type);
56
56
}
57
57
}
58
58
@@ -7,7 +7,7 @@ namespace SpaceEngineersBlueprintEditor.Implements.Services;
7
7
internal class NavigationViewService : GlobalServiceBase, INavigationViewService
8
8
{
9
9
private NavigationView? navigationView;
10
private readonly INavigationService navigationService = new NavigationService();
10
private readonly NavigationService navigationService = new();
11
11
public INavigationService NavigationService => navigationService;
12
12
13
13
public object? SelectedItem => navigationView?.SelectedItem;
@@ -40,11 +40,11 @@ internal class NavigationViewService : GlobalServiceBase, INavigationViewService
40
40
NavigateTo(targetUrl, args.InvokedItemContainer.GetValue(NavigationAddition.NavigateParameterProperty) is string parameter ? parameter : null);
41
41
}
42
42
43
public void NavigateTo<T>(object? parameter = null) where T : Page => NavigationService.NavigateTo<T>(parameter);
43
public void NavigateTo<T>(object? parameter = null) where T : Page => navigationService.NavigateTo<T>(parameter);
44
44
45
public void NavigateTo(Type type, object? parameter = null, bool goBack = false) => NavigationService.NavigateTo(type, parameter, goBack);
45
public void NavigateTo(Type type, object? parameter = null, bool goBack = false) => navigationService.NavigateTo(type, parameter, goBack);
46
46
47
public void NavigateTo(string pageName, object? parameter = null) => NavigationService.NavigateTo(pageName, parameter);
47
public void NavigateTo(string pageName, object? parameter = null) => navigationService.NavigateTo(pageName, parameter);
48
48
49
49
public NavigationViewItem? GetSelectedItem(Type type) => navigationView is null ? null : GetSelectedItem(navigationView.MenuItems, navigationView.FooterMenuItems, type);
50
50
private NavigationViewItem? GetSelectedItem(IEnumerable<object> menuItems, IEnumerable<object> footerMenuItems, Type pageType)
@@ -60,7 +60,7 @@ internal class NavigationViewService : GlobalServiceBase, INavigationViewService
60
60
{
61
61
if (item.GetNavigateTo() is string pageName && pageName == pageType.FullName)
62
62
{
63
var parameter = NavigationService.NavigationStack.Last().Item2;
63
var parameter = navigationService.NavigationStack.Last().Item2;
64
64
var itemParameter = item.GetNavigationParameter();
65
65
if (parameter is string && Equals(parameter, itemParameter) || parameter == itemParameter)
66
66
return item;
@@ -1,6 +1,19 @@
1
namespace SpaceEngineersBlueprintEditor.Interface.Services;
1
using Microsoft.UI.Dispatching;
2
using System.Collections.ObjectModel;
3
4
namespace SpaceEngineersBlueprintEditor.Interface.Services;
2
5
3
6
public interface IMessageService : IGlobalService
4
7
{
5
void SendMessage(string message);
8
ReadOnlyDictionary<string, InfoBar> MessageStack { get; }
9
bool ShowMessage(string message, string title = "");
10
bool ShowMessage(string message, string title, InfoBarSeverity severity);
11
bool ShowButtonMessage(string message, string title, string buttonText, Action<object, RoutedEventArgs> callBackAction, InfoBarSeverity severity = InfoBarSeverity.Informational, bool canClose = true);
12
bool ShowMessage(string message, string title = "", object? content = null, InfoBarSeverity severity = InfoBarSeverity.Informational, double time = 5, bool canClose = true, string buttonText = "", Action<object, RoutedEventArgs>? callBackAction = null, string messageId = "");
13
bool ShowMessageWithId(string messageId, string message, string title = "", InfoBarSeverity severity = InfoBarSeverity.Informational, double time = 5);
14
bool ShowMessage(InfoBar infoBar, double time = -1, string messageId = "");
15
InfoBar? GetMessage(string messageId);
16
bool RemoveMessage(string messageId);
17
void Clear();
18
void Initialize(StackPanel stackPanel, DispatcherQueue dispatcherQueue);
6
19
}
@@ -33,6 +33,7 @@
33
33
<None Remove="Views\AppShellPage.xaml" />
34
34
<None Remove="Views\BlueprintEditPage.xaml" />
35
35
<None Remove="Views\BlueprintsViewPage.xaml" />
36
<None Remove="Views\MainPage.xaml" />
36
37
<None Remove="Views\SettingPage.xaml" />
37
38
</ItemGroup>
38
39
<ItemGroup>
@@ -94,6 +95,11 @@
94
95
<Folder Include="Profiles\CurrentVersionProfiles\" />
95
96
<Folder Include="Profiles\SynProfiles\" />
96
97
</ItemGroup>
98
<ItemGroup>
99
<Page Update="Views\MainPage.xaml">
100
<Generator>MSBuild:Compile</Generator>
101
</Page>
102
</ItemGroup>
97
103
98
104
<!--
99
105
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
@@ -133,6 +133,10 @@
133
133
<value>Setting</value>
134
134
<comment>设置</comment>
135
135
</data>
136
<data name="AppShell_ShellItem_MainPage.Content" xml:space="preserve">
137
<value>Home</value>
138
<comment>主页</comment>
139
</data>
136
140
<data name="AppShell_ShellItem_ViewWorkshopBlueprints.Content" xml:space="preserve">
137
141
<value>Workshop Blueprints</value>
138
142
<comment>工坊蓝图</comment>
@@ -1,4 +1,4 @@
1
using Microsoft.UI.Xaml.Media.Imaging;
1
using SpaceEngineersBlueprintEditor.Interface.Services;
2
2
using SpaceEngineersBlueprintEditor.Model;
3
3
using XFEExtension.NetCore.FileExtension;
4
4
@@ -11,6 +11,7 @@ public partial class AppShellPageViewModel : ViewModelBase
11
11
[ObservableProperty]
12
12
bool canGoBack;
13
13
public INavigationViewService NavigationViewService { get; set; } = new NavigationViewService();
14
public IMessageService MessageService { get; set; } = new MessageService();
14
15
15
16
public AppShellPageViewModel() => NavigationViewService.NavigationService.Navigated += NavigationService_Navigated;
16
17
@@ -1,33 +1,19 @@
1
using CommunityToolkit.Mvvm.Input;
2
using SpaceEngineersBlueprintEditor.Implements.Services;
1
using SpaceEngineersBlueprintEditor.Implements.Services;
3
2
using SpaceEngineersBlueprintEditor.Interface.Services;
4
using SpaceEngineersBlueprintEditor.Utilities;
5
using SpaceEngineersBlueprintEditor.Views;
6
3
7
4
namespace SpaceEngineersBlueprintEditor.ViewModels;
8
5
9
6
public partial class BlueprintEditPageViewModel : ViewModelBase
10
7
{
11
private INavigationService? navigationService = GlobalServiceManager.GetService<INavigationService>();
12
public IFileDropService FileDropService { get; set; } = new BlueprintDropService();
13
8
public INavigationParameterService NavigationParameterService { get; set; } = new NavigationParameterService();
14
9
15
10
public BlueprintEditPageViewModel()
16
11
{
17
12
NavigationParameterService.ParameterChange += NavigationParameterService_ParameterChange;
18
FileDropService.Drop += FileDropService_Drop;
19
13
}
20
14
21
15
private void NavigationParameterService_ParameterChange(object? sender, object? e)
22
16
{
23
17
24
18
}
25
26
private void FileDropService_Drop(object? sender, (string, DragEventArgs) e)
27
{
28
29
}
30
31
[RelayCommand]
32
void ViewBlueprintsList() => navigationService?.NavigateTo<BlueprintsViewPage>("Local");
33
19
}
@@ -1,4 +1,6 @@
1
using SpaceEngineersBlueprintEditor.Implements.Services;
1
using CommunityToolkit.Mvvm.ComponentModel;
2
using CommunityToolkit.Mvvm.Input;
3
using SpaceEngineersBlueprintEditor.Implements.Services;
2
4
using SpaceEngineersBlueprintEditor.Interface.Services;
3
5
using SpaceEngineersBlueprintEditor.Model;
4
6
using SpaceEngineersBlueprintEditor.Utilities;
@@ -8,6 +10,10 @@ namespace SpaceEngineersBlueprintEditor.ViewModels;
8
10
9
11
public partial class BlueprintsViewPageViewModel : ViewModelBase
10
12
{
13
private string currentParameter = "";
14
private IMessageService? messageService = GlobalServiceManager.GetService<IMessageService>();
15
[ObservableProperty]
16
private string searchText = "";
11
17
public INavigationParameterService NavigationParameterService { get; set; } = new NavigationParameterService();
12
18
public ObservableCollection<BlueprintInfoViewData> BlueprintInfoViewDataList { get; set; } = [];
13
19
@@ -16,6 +22,24 @@ public partial class BlueprintsViewPageViewModel : ViewModelBase
16
22
NavigationParameterService.ParameterChange += NavigationParameterService_ParameterChange;
17
23
}
18
24
25
partial void OnSearchTextChanged(string value)
26
{
27
BlueprintInfoViewDataList.Clear();
28
LoadBlueprints(SearchBlueprints(currentParameter, value).ToList());
29
}
30
31
private static IEnumerable<BlueprintInfo> SearchBlueprints(string searchMode, string blueprintName) => GetCurrentBlueprints(searchMode).Where(blueprint => blueprint.Name.Contains(blueprintName));
32
33
private static List<BlueprintInfo> GetCurrentBlueprints(string currentLocation) => currentLocation switch
34
{
35
"Local" => BlueprintsManager.LocalBlueprints,
36
"Cloud" => BlueprintsManager.CloudBlueprints,
37
"Workshop" => BlueprintsManager.WorkshopBlueprints,
38
_ => throw new NotImplementedException()
39
};
40
41
private void LoadCurrentBlueprints() => LoadBlueprints(GetCurrentBlueprints(currentParameter));
42
19
43
private void LoadBlueprints(List<BlueprintInfo> blueprintInfoList)
20
44
{
21
45
foreach (var info in blueprintInfoList)
@@ -25,22 +49,22 @@ public partial class BlueprintsViewPageViewModel : ViewModelBase
25
49
private void NavigationParameterService_ParameterChange(object? sender, object? e)
26
50
{
27
51
if (e is string parameter)
28
switch (parameter)
29
{
30
case "Local":
31
BlueprintInfoViewDataList.Clear();
32
LoadBlueprints(BlueprintsManager.LocalBlueprints);
33
break;
34
case "Cloud":
35
BlueprintInfoViewDataList.Clear();
36
LoadBlueprints(BlueprintsManager.CloudBlueprints);
37
break;
38
case "Workshop":
39
BlueprintInfoViewDataList.Clear();
40
LoadBlueprints(BlueprintsManager.WorkshopBlueprints);
41
break;
42
default:
43
break;
44
}
52
{
53
currentParameter = parameter;
54
BlueprintInfoViewDataList.Clear();
55
LoadCurrentBlueprints();
56
}
57
}
58
59
60
[RelayCommand]
61
async Task RefreshBlueprints()
62
{
63
await BlueprintsManager.LoadBlueprintsAsync();
64
if (SearchText == string.Empty)
65
LoadCurrentBlueprints();
66
else
67
OnSearchTextChanged(SearchText);
68
messageService?.ShowMessage("刷新成功", "完成", InfoBarSeverity.Success);
45
69
}
46
70
}
@@ -0,0 +1,40 @@
1
using CommunityToolkit.Mvvm.Input;
2
using SpaceEngineersBlueprintEditor.Implements.Services;
3
using SpaceEngineersBlueprintEditor.Interface.Services;
4
using SpaceEngineersBlueprintEditor.Utilities;
5
using SpaceEngineersBlueprintEditor.Views;
6
using System.Diagnostics;
7
using Windows.Storage.Pickers;
8
9
namespace SpaceEngineersBlueprintEditor.ViewModels;
10
11
public partial class MainPageViewModel : ViewModelBase
12
{
13
private INavigationService? navigationService = GlobalServiceManager.GetService<INavigationService>();
14
public IFileDropService FileDropService { get; set; } = new BlueprintDropService();
15
16
public MainPageViewModel()
17
{
18
FileDropService.Drop += FileDropService_Drop;
19
}
20
21
private void FileDropService_Drop(object? sender, (string, DragEventArgs) e)
22
{
23
24
}
25
26
[RelayCommand]
27
void ViewBlueprintsList() => navigationService?.NavigateTo<BlueprintsViewPage>("Local");
28
29
[RelayCommand]
30
async Task OpenBlueprintInFolder()
31
{
32
var openPicker = new FileOpenPicker();
33
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow));
34
openPicker.ViewMode = PickerViewMode.List;
35
openPicker.FileTypeFilter.Add(".sbc");
36
var file = await openPicker.PickSingleFileAsync();
37
if (file is not null)
38
Debug.WriteLine(file.Path);
39
}
40
}