diff --git a/StartServerWPF.Modules.Main/Fonts/iconfont.ttf b/StartServerWPF.Modules.Main/Fonts/iconfont.ttf new file mode 100644 index 0000000..682c0fb Binary files /dev/null and b/StartServerWPF.Modules.Main/Fonts/iconfont.ttf differ diff --git a/StartServerWPF.Modules.Main/Images/Union.png b/StartServerWPF.Modules.Main/Images/Union.png new file mode 100644 index 0000000..b852019 Binary files /dev/null and b/StartServerWPF.Modules.Main/Images/Union.png differ diff --git a/StartServerWPF.Modules.Main/JsonParser.cs b/StartServerWPF.Modules.Main/JsonParser.cs index 24081cc..01c43cd 100644 --- a/StartServerWPF.Modules.Main/JsonParser.cs +++ b/StartServerWPF.Modules.Main/JsonParser.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System.IO; -using StartServerWPF.Modules.Main.Model; +using StartServerWPF.Modules.Main.Models; namespace StartServerWPF.Modules.Main { diff --git a/StartServerWPF.Modules.Main/MainModule.cs b/StartServerWPF.Modules.Main/MainModule.cs index 3b86a01..3693808 100644 --- a/StartServerWPF.Modules.Main/MainModule.cs +++ b/StartServerWPF.Modules.Main/MainModule.cs @@ -12,12 +12,13 @@ namespace StartServerWPF.Modules.Main { var iRegion= containerProvider.Resolve(); 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" > - + + + + + + + + + + + + + +