From 8cc06bb9bd92b29b1268b35a70a5d8e84495c746 Mon Sep 17 00:00:00 2001 From: mzhifa Date: Wed, 19 Jul 2023 10:42:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8F=B3=E4=BE=A7=E8=8F=9C?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Fonts/iconfont.ttf | Bin 0 -> 7740 bytes StartServerWPF.Modules.Main/Images/Union.png | Bin 0 -> 779 bytes StartServerWPF.Modules.Main/JsonParser.cs | 2 +- StartServerWPF.Modules.Main/MainModule.cs | 3 +- .../{Model => Models}/ApmsConfig.cs | 2 +- .../{Model => Models}/CSMessage.cs | 2 +- .../Models/MenuItemModel.cs | 69 +++++++++ .../{Model => Models}/SystemConfig.cs | 2 +- .../{Model => Models}/UserMessage.cs | 2 +- .../{Model => Models}/VpnInfo.cs | 2 +- .../StartServerWPF.Modules.Main.csproj | 4 + .../Styles/BaseResources.xaml | 4 + .../ViewModels/MainViewModel.cs | 7 +- .../ViewModels/SetParamDialogViewModel.cs | 2 +- .../ViewModels/TreeMenuViewModel.cs | 94 ++++++++++++ .../Views/TreeMenuView.xaml | 140 ++++++++++++++++++ .../Views/TreeMenuView.xaml.cs | 28 ++++ .../WebsocketClient.cs | 2 +- StartServerWPF/App.xaml | 3 +- StartServerWPF/App.xaml.cs | 112 +++++++++++++- StartServerWPF/Views/MainWindow.xaml | 15 +- 21 files changed, 479 insertions(+), 16 deletions(-) create mode 100644 StartServerWPF.Modules.Main/Fonts/iconfont.ttf create mode 100644 StartServerWPF.Modules.Main/Images/Union.png rename StartServerWPF.Modules.Main/{Model => Models}/ApmsConfig.cs (91%) rename StartServerWPF.Modules.Main/{Model => Models}/CSMessage.cs (92%) create mode 100644 StartServerWPF.Modules.Main/Models/MenuItemModel.cs rename StartServerWPF.Modules.Main/{Model => Models}/SystemConfig.cs (96%) rename StartServerWPF.Modules.Main/{Model => Models}/UserMessage.cs (97%) rename StartServerWPF.Modules.Main/{Model => Models}/VpnInfo.cs (96%) create mode 100644 StartServerWPF.Modules.Main/Styles/BaseResources.xaml create mode 100644 StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs create mode 100644 StartServerWPF.Modules.Main/Views/TreeMenuView.xaml create mode 100644 StartServerWPF.Modules.Main/Views/TreeMenuView.xaml.cs diff --git a/StartServerWPF.Modules.Main/Fonts/iconfont.ttf b/StartServerWPF.Modules.Main/Fonts/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..682c0fb8e44153228414035a9b9f7a5703b30e76 GIT binary patch literal 7740 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 iRegion.RegisterViewWithRegion("MainContentRegion", typeof(MainView)); + iRegion.RegisterViewWithRegion("LeftMenuTreeRegion", typeof(TreeMenuView)); } public void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton(); - containerRegistry.RegisterDialog(); + containerRegistry.RegisterDialog(); } } } \ No newline at end of file diff --git a/StartServerWPF.Modules.Main/Model/ApmsConfig.cs b/StartServerWPF.Modules.Main/Models/ApmsConfig.cs similarity index 91% rename from StartServerWPF.Modules.Main/Model/ApmsConfig.cs rename to StartServerWPF.Modules.Main/Models/ApmsConfig.cs index 19b3672..51169d1 100644 --- a/StartServerWPF.Modules.Main/Model/ApmsConfig.cs +++ b/StartServerWPF.Modules.Main/Models/ApmsConfig.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StartServerWPF.Modules.Main.Model +namespace StartServerWPF.Modules.Main.Models { public class ApmsConfig { diff --git a/StartServerWPF.Modules.Main/Model/CSMessage.cs b/StartServerWPF.Modules.Main/Models/CSMessage.cs similarity index 92% rename from StartServerWPF.Modules.Main/Model/CSMessage.cs rename to StartServerWPF.Modules.Main/Models/CSMessage.cs index 95e1131..29ca62d 100644 --- a/StartServerWPF.Modules.Main/Model/CSMessage.cs +++ b/StartServerWPF.Modules.Main/Models/CSMessage.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace StartServerWPF.Modules.Main.Model +namespace StartServerWPF.Modules.Main.Models { class CSMessage { diff --git a/StartServerWPF.Modules.Main/Models/MenuItemModel.cs b/StartServerWPF.Modules.Main/Models/MenuItemModel.cs new file mode 100644 index 0000000..762e332 --- /dev/null +++ b/StartServerWPF.Modules.Main/Models/MenuItemModel.cs @@ -0,0 +1,69 @@ +using Prism.Commands; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace StartServerWPF.Modules.Main.Models +{ + public class MenuItemModel : BindableBase + { + public string MenuIcon { get; set; } + public string MenuHeader { get; set; } + public string TargetView { get; set; } + private bool _isExpanded; + + public bool IsExpanded + { + get { return _isExpanded; } + set { SetProperty(ref _isExpanded, value); } + } + + private ObservableCollection _children; + public ObservableCollection Children + { + get { return _children; } + set { SetProperty(ref _children, value); } + } + + private ICommand _openViewCommand; + + public ICommand OpenViewCommand + { + get + { + if (_openViewCommand == null) + _openViewCommand = new DelegateCommand((model) => + { + if ((model.Children == null || model.Children.Count == 0) && + !string.IsNullOrEmpty(model.TargetView)) + _regionManager.RequestNavigate("MainContentRegion", model.TargetView); + else + IsExpanded = !IsExpanded; + }); + return _openViewCommand; + } + } + + IRegionManager _regionManager = null; + public MenuItemModel(IRegionManager regionManager) + { + _regionManager = regionManager; + } + + private bool _isSelected; + public bool IsSelected + { + get => _isSelected; + set + { + SetProperty(ref _isSelected, value); + } + } + } +} diff --git a/StartServerWPF.Modules.Main/Model/SystemConfig.cs b/StartServerWPF.Modules.Main/Models/SystemConfig.cs similarity index 96% rename from StartServerWPF.Modules.Main/Model/SystemConfig.cs rename to StartServerWPF.Modules.Main/Models/SystemConfig.cs index f102354..d9b625a 100644 --- a/StartServerWPF.Modules.Main/Model/SystemConfig.cs +++ b/StartServerWPF.Modules.Main/Models/SystemConfig.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StartServerWPF.Modules.Main.Model +namespace StartServerWPF.Modules.Main.Models { public class SystemConfig { diff --git a/StartServerWPF.Modules.Main/Model/UserMessage.cs b/StartServerWPF.Modules.Main/Models/UserMessage.cs similarity index 97% rename from StartServerWPF.Modules.Main/Model/UserMessage.cs rename to StartServerWPF.Modules.Main/Models/UserMessage.cs index 47e97df..40b127c 100644 --- a/StartServerWPF.Modules.Main/Model/UserMessage.cs +++ b/StartServerWPF.Modules.Main/Models/UserMessage.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace StartServerWPF.Modules.Main.Model +namespace StartServerWPF.Modules.Main.Models { public class CSUserSigin { diff --git a/StartServerWPF.Modules.Main/Model/VpnInfo.cs b/StartServerWPF.Modules.Main/Models/VpnInfo.cs similarity index 96% rename from StartServerWPF.Modules.Main/Model/VpnInfo.cs rename to StartServerWPF.Modules.Main/Models/VpnInfo.cs index 627078b..5166a94 100644 --- a/StartServerWPF.Modules.Main/Model/VpnInfo.cs +++ b/StartServerWPF.Modules.Main/Models/VpnInfo.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StartServerWPF.Modules.Main.Model +namespace StartServerWPF.Modules.Main.Models { /// /// VPN信息类 diff --git a/StartServerWPF.Modules.Main/StartServerWPF.Modules.Main.csproj b/StartServerWPF.Modules.Main/StartServerWPF.Modules.Main.csproj index 7f89eba..e74526c 100644 --- a/StartServerWPF.Modules.Main/StartServerWPF.Modules.Main.csproj +++ b/StartServerWPF.Modules.Main/StartServerWPF.Modules.Main.csproj @@ -5,7 +5,9 @@ True + + @@ -21,6 +23,8 @@ + + \ No newline at end of file diff --git a/StartServerWPF.Modules.Main/Styles/BaseResources.xaml b/StartServerWPF.Modules.Main/Styles/BaseResources.xaml new file mode 100644 index 0000000..761e695 --- /dev/null +++ b/StartServerWPF.Modules.Main/Styles/BaseResources.xaml @@ -0,0 +1,4 @@ + + pack://application:,,,/StartServerWPF.Modules.Main;component/Fonts/#iconfont + \ No newline at end of file diff --git a/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs b/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs index 0364b54..c0e63cb 100644 --- a/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs +++ b/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs @@ -14,7 +14,7 @@ using System.Threading.Tasks; using System.Windows.Controls; using System.Windows; using System.Collections.ObjectModel; -using StartServerWPF.Modules.Main.Model; +using StartServerWPF.Modules.Main.Models; using System.Windows.Media; using System.Timers; using System.Windows.Threading; @@ -295,8 +295,7 @@ namespace StartServerWPF.Modules.Main.ViewModels DialogParameters param = new DialogParameters(); param.Add("type", 1);// 编辑 param.Add("model", sc); - param.Add("moniTime", MoniStartTime); - + param.Add("moniTime", MoniStartTime); _dialogService.ShowDialog( "SetParamDialog", param, @@ -306,7 +305,7 @@ namespace StartServerWPF.Modules.Main.ViewModels { MessageBox.Show("数据已保存", "提示"); } - })); + })); } private void DisplayLog() diff --git a/StartServerWPF.Modules.Main/ViewModels/SetParamDialogViewModel.cs b/StartServerWPF.Modules.Main/ViewModels/SetParamDialogViewModel.cs index e796609..cb51d02 100644 --- a/StartServerWPF.Modules.Main/ViewModels/SetParamDialogViewModel.cs +++ b/StartServerWPF.Modules.Main/ViewModels/SetParamDialogViewModel.cs @@ -1,7 +1,7 @@ using Prism.Commands; using Prism.Mvvm; using Prism.Services.Dialogs; -using StartServerWPF.Modules.Main.Model; +using StartServerWPF.Modules.Main.Models; using System; using System.Collections.Generic; using System.Linq; diff --git a/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs b/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs new file mode 100644 index 0000000..6bdba61 --- /dev/null +++ b/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs @@ -0,0 +1,94 @@ +using Prism.Commands; +using Prism.Events; +using Prism.Ioc; +using Prism.Mvvm; +using Prism.Regions; +using Prism.Services.Dialogs; +using StartServerWPF.Modules.Main.Models; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace StartServerWPF.Modules.Main.ViewModels +{ + public class TreeMenuViewModel : BindableBase + { + private ObservableCollection _menus; + public ObservableCollection Menus { get => _menus; set => SetProperty(ref _menus, value); } + + // private List origMenus = null; + + private IRegionManager _regionManager = null; + private readonly IDialogService _dialogService; + + public TreeMenuViewModel(IContainerProvider containerProvider, IRegionManager regionManager, IEventAggregator ea, IDialogService dialogService) + { + _regionManager = regionManager; + this._dialogService = dialogService; + //var global = containerProvider.Resolve();// 注册一个单例 + // ea.GetEvent().Subscribe(OnLogin, ThreadOption.UIThread); + } + + #region 事件 + + public DelegateCommand AboutCommand => new(()=> + { + DialogParameters param=new DialogParameters(); + _dialogService.ShowDialog( + "AboutDialogView", + param, + new Action(result => + { + if (result != null && result.Result == ButtonResult.OK) + { + MessageBox.Show("数据已保存", "提示"); + } + })); + }); + #endregion + + + + //private void OnLogin(LoginPayload loginPayload) + //{ + // Menus = new ObservableCollection(); + // if (!loginPayload.IsLogingIn) // + // { + // //登录完成更新措菜单 + // if (GlobalEntity.CurrentUserInfo != null) + // { + // origMenus = GlobalEntity.CurrentUserInfo.Menus; + // this.FillMenus(Menus, 0); + // } + // } + //} + ///递归 + /// + private void FillMenus(ObservableCollection menus, int parentId) + { + // var sub = origMenus.Where(m => m.ParentId == parentId).OrderBy(o => o.Index); + + //if (sub.Count() > 0) + //{ + // foreach (var item in sub) + // { + // MenuItemModel mm = new MenuItemModel(_regionManager) + // { + // MenuHeader = item.MenuHeader, + // MenuIcon = item.MenuIcon, + // TargetView = item.TargetView + // }; + // menus.Add(mm); + + // FillMenus(mm.Children = new ObservableCollection(), item.MenuId); + // } + //} + } + + } +} diff --git a/StartServerWPF.Modules.Main/Views/TreeMenuView.xaml b/StartServerWPF.Modules.Main/Views/TreeMenuView.xaml new file mode 100644 index 0000000..71e4894 --- /dev/null +++ b/StartServerWPF.Modules.Main/Views/TreeMenuView.xaml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StartServerWPF.Modules.Main/Views/TreeMenuView.xaml.cs b/StartServerWPF.Modules.Main/Views/TreeMenuView.xaml.cs new file mode 100644 index 0000000..df726f5 --- /dev/null +++ b/StartServerWPF.Modules.Main/Views/TreeMenuView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace StartServerWPF.Modules.Main.Views +{ + /// + /// TreeMenuView.xaml 的交互逻辑 + /// + public partial class TreeMenuView : UserControl + { + public TreeMenuView() + { + InitializeComponent(); + } + } +} diff --git a/StartServerWPF.Modules.Main/WebsocketClient.cs b/StartServerWPF.Modules.Main/WebsocketClient.cs index 913d08c..7fbb8c2 100644 --- a/StartServerWPF.Modules.Main/WebsocketClient.cs +++ b/StartServerWPF.Modules.Main/WebsocketClient.cs @@ -1,4 +1,4 @@ -using StartServerWPF.Modules.Main.Model; +using StartServerWPF.Modules.Main.Models; using SuperSocket.ClientEngine; using System; using System.Collections.Generic; diff --git a/StartServerWPF/App.xaml b/StartServerWPF/App.xaml index 83840bf..c2ae6a9 100644 --- a/StartServerWPF/App.xaml +++ b/StartServerWPF/App.xaml @@ -2,7 +2,8 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StartServerWPF" - xmlns:prism="http://prismlibrary.com/" > + xmlns:prism="http://prismlibrary.com/" + DispatcherUnhandledException="App_DispatcherUnhandledException" > diff --git a/StartServerWPF/App.xaml.cs b/StartServerWPF/App.xaml.cs index e9b5678..ba2d42a 100644 --- a/StartServerWPF/App.xaml.cs +++ b/StartServerWPF/App.xaml.cs @@ -1,8 +1,15 @@ -using Prism.Ioc; +using Microsoft.VisualBasic.Logging; +using Prism.Ioc; using Prism.Modularity; using StartServerWPF.Modules.Main; using StartServerWPF.Views; +using System.Collections; +using System.Net.NetworkInformation; +using System.Text; +using System; +using System.Threading.Tasks; using System.Windows; +using System.Windows.Threading; namespace StartServerWPF { @@ -11,6 +18,12 @@ namespace StartServerWPF /// public partial class App { + + public App() + { + System.AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; + } protected override Window CreateShell() { return Container.Resolve(); @@ -26,5 +39,102 @@ namespace StartServerWPF moduleCatalog.AddModule(); base.ConfigureModuleCatalog(moduleCatalog); } + + + static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + try + { + System.Exception error = (System.Exception)e.ExceptionObject; + StringBuilder stringBuilder = ExtractAllStackTrace(error); + + + } + catch(Exception ex) + { + } + } + + /// + /// UI线程未捕获异常处理事件(UI主线程) + /// + /// + /// + void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) + { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder = ExtractAllStackTrace(e.Exception); + //if (e.Exception.InnerException != null) + //{ + // stringBuilder.AppendFormat("\n\r {0}", e.Exception.InnerException); + // stringBuilder.AppendFormat("\n\r {0}", e.Exception.InnerException.StackTrace); + //} + //stringBuilder.AppendFormat("\n\r {0}", e.Exception.StackTrace); + //string errmsg; + //if (e.Exception is XamlParseException && e.Exception.InnerException != null) + //{ + // errmsg = e.Exception.InnerException.Message; + //} + //else + //{ + // errmsg = e.Exception.Message; + //} + + e.Handled = true; + } + + //Task线程内未捕获异常处理事件 + private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) + { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder = ExtractAllStackTrace(e.Exception); + //Exception ex = e.Exception; + //string msg = String.Format("{0}\n\n{1},{2}", ex.Message, ex.StackTrace, ex.InnerException.StackTrace); + // new Log.GetLogger("APP.xmal").Log.Error("App.TaskScheduler_UnobservedTaskException()" + stringBuilder.ToString()); + + // WriteError(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff:ffffff") + ": " + stringBuilder.ToString()); + //App.Current.Dispatcher.Invoke(() => + //{ + // //MessageBoxResult messageBox = MessageBox.Show(msg, "提示", MessageBoxButton.OK); + // IsClickBtn? value = IsClickBtn.cancel; + // value = LoadError.Show(msg); + // if (value == IsClickBtn.yes) + // { + + // } + // // ViewModel.LoadViaViewModel.LoadingViewModel.ExitProcess(0); + //}); + } + + /// + /// 提取异常及其内部异常堆栈跟踪 + /// + /// 提取的异常 + /// 最后提取的堆栈跟踪(对于递归), String.Empty or null + /// 提取的堆栈数(对于递归) + /// Syste.String + private static StringBuilder ExtractAllStackTrace(Exception exception, StringBuilder lastStackTrace = null, int exCount = 1) + { + var ex = exception; + //修复最后一个堆栈跟踪参数 + lastStackTrace = lastStackTrace ?? new StringBuilder(); + //添加异常的堆栈跟踪 + lastStackTrace.Append($"count:{exCount}: {ex.Message}{ex.StackTrace}\n\r"); + if (exception.Data.Count > 0) + { + lastStackTrace.Append("Data:"); + foreach (var item in exception.Data) + { + var entry = (DictionaryEntry)item; + lastStackTrace.Append($"{entry.Key}: {exception.Data[entry.Key]}\n\r"); + } + } + //递归添加内部异常 + if ((ex = ex.InnerException) != null) + return ExtractAllStackTrace(ex, lastStackTrace, ++exCount); + return lastStackTrace; + } } } diff --git a/StartServerWPF/Views/MainWindow.xaml b/StartServerWPF/Views/MainWindow.xaml index 55eeda0..518f19a 100644 --- a/StartServerWPF/Views/MainWindow.xaml +++ b/StartServerWPF/Views/MainWindow.xaml @@ -5,6 +5,19 @@ prism:ViewModelLocator.AutoWireViewModel="True" Closing="Window_Closing" Title="{Binding Title}" Height="500" Width="900" > - + + + + + + + + + + + + + +