From 1a53091748840565b74be83104bc6058eaf23aee Mon Sep 17 00:00:00 2001 From: LeoYang Date: Tue, 7 Sep 2021 22:57:34 +0800 Subject: [PATCH] Improve the basics of demo project. --- .../Interfaces/IActivatable.cs | 10 ++ .../Interfaces/IActivatableView.cs | 10 ++ .../Wif.Demo.Common/Interfaces/IViewFor.cs | 30 ++++ .../Demos/Wif.Demo.Common/UserControlBase.cs | 42 ++++++ Source/Demos/Wif.Demo/App.xaml | 8 +- Source/Demos/Wif.Demo/App.xaml.cs | 132 +++++++++++++++++- .../Examples/BindingDemo/BindingDemoView.xaml | 70 ++++++++++ .../BindingDemo/BindingDemoView.xaml.cs | 28 ++++ .../BindingDemo/BindingDemoViewModel.cs | 61 ++++++++ .../FileHelperDemo/FileHelperDemoView.xaml | 12 ++ .../FileHelperDemo/FileHelperDemoView.xaml.cs | 37 +++++ .../HostBuilderViewExtensions.cs | 38 +++++ Source/Demos/Wif.Demo/Locator.cs | 22 +++ Source/Demos/Wif.Demo/MainViewModel.cs | 53 +------ Source/Demos/Wif.Demo/MainWindow.xaml | 84 +++-------- Source/Demos/Wif.Demo/MainWindow.xaml.cs | 19 +-- .../Wif.Demo/{ => Properties}/AssemblyInfo.cs | 0 Source/Demos/Wif.Demo/Wif.Demo.csproj | 4 + Source/Wif.sln.licenseheader | 22 +++ 19 files changed, 547 insertions(+), 135 deletions(-) create mode 100644 Source/Demos/Wif.Demo.Common/Interfaces/IActivatable.cs create mode 100644 Source/Demos/Wif.Demo.Common/Interfaces/IActivatableView.cs create mode 100644 Source/Demos/Wif.Demo.Common/Interfaces/IViewFor.cs create mode 100644 Source/Demos/Wif.Demo.Common/UserControlBase.cs create mode 100644 Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml create mode 100644 Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml.cs create mode 100644 Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoViewModel.cs create mode 100644 Source/Demos/Wif.Demo/Examples/FileHelperDemo/FileHelperDemoView.xaml create mode 100644 Source/Demos/Wif.Demo/Examples/FileHelperDemo/FileHelperDemoView.xaml.cs create mode 100644 Source/Demos/Wif.Demo/IocExtensions/HostBuilderViewExtensions.cs create mode 100644 Source/Demos/Wif.Demo/Locator.cs rename Source/Demos/Wif.Demo/{ => Properties}/AssemblyInfo.cs (100%) create mode 100644 Source/Wif.sln.licenseheader diff --git a/Source/Demos/Wif.Demo.Common/Interfaces/IActivatable.cs b/Source/Demos/Wif.Demo.Common/Interfaces/IActivatable.cs new file mode 100644 index 0000000..0c98343 --- /dev/null +++ b/Source/Demos/Wif.Demo.Common/Interfaces/IActivatable.cs @@ -0,0 +1,10 @@ +namespace Wif.Demo.Common.Interfaces +{ + /// + /// Use this Interface when you want to mark a control as recieving View + /// Activation when it doesn't have a backing ViewModel. + /// + public interface IActivatable + { + } +} \ No newline at end of file diff --git a/Source/Demos/Wif.Demo.Common/Interfaces/IActivatableView.cs b/Source/Demos/Wif.Demo.Common/Interfaces/IActivatableView.cs new file mode 100644 index 0000000..3eca411 --- /dev/null +++ b/Source/Demos/Wif.Demo.Common/Interfaces/IActivatableView.cs @@ -0,0 +1,10 @@ +namespace Wif.Demo.Common.Interfaces +{ + /// + /// Use this Interface when you want to mark a control as receiving View + /// Activation when it doesn't have a backing ViewModel. + /// + public interface IActivatableView + { + } +} \ No newline at end of file diff --git a/Source/Demos/Wif.Demo.Common/Interfaces/IViewFor.cs b/Source/Demos/Wif.Demo.Common/Interfaces/IViewFor.cs new file mode 100644 index 0000000..f192988 --- /dev/null +++ b/Source/Demos/Wif.Demo.Common/Interfaces/IViewFor.cs @@ -0,0 +1,30 @@ +namespace Wif.Demo.Common.Interfaces +{ + /// + /// This base class is mostly used by the Framework. Implement + /// instead. + /// + public interface IViewFor : IActivatable + { + /// + /// Gets or sets the View Model associated with the View. + /// + object ViewModel { get; set; } + } + +#pragma warning disable SA1402 // File may only contain a single type + /// + /// Implement this interface on your Views to support Routing and Binding. + /// + /// The type of ViewModel. + public interface IViewFor : IViewFor +#pragma warning restore SA1402 // File may only contain a single type + where T : class + { + /// + /// Gets or sets the ViewModel corresponding to this specific View. This should be + /// a DependencyProperty if you're using XAML. + /// + new T ViewModel { get; set; } + } +} \ No newline at end of file diff --git a/Source/Demos/Wif.Demo.Common/UserControlBase.cs b/Source/Demos/Wif.Demo.Common/UserControlBase.cs new file mode 100644 index 0000000..1e8a6c7 --- /dev/null +++ b/Source/Demos/Wif.Demo.Common/UserControlBase.cs @@ -0,0 +1,42 @@ +using System.Windows; +using System.Windows.Controls; +using Wif.Demo.Common.Interfaces; + +namespace Wif.Demo.Common +{ + public class UserControlBase : UserControl, IViewFor where TViewModel : class + { + /// + /// The view model dependency property. + /// + public static readonly DependencyProperty ViewModelProperty = + DependencyProperty.Register(nameof(ViewModel), typeof(TViewModel), typeof(UserControlBase), new PropertyMetadata(null)); + + /// + /// Gets the binding root view model. + /// + public TViewModel BindingRoot => ViewModel; + + #region IViewFor Members + + /// + /// + /// + public TViewModel ViewModel + { + get => (TViewModel)GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + /// + /// + /// + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (TViewModel)value; + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/Demos/Wif.Demo/App.xaml b/Source/Demos/Wif.Demo/App.xaml index 5fd32a5..e7be608 100644 --- a/Source/Demos/Wif.Demo/App.xaml +++ b/Source/Demos/Wif.Demo/App.xaml @@ -1,9 +1,7 @@  - - - + Exit="App_OnExit" + Startup="App_OnStartup"> + diff --git a/Source/Demos/Wif.Demo/App.xaml.cs b/Source/Demos/Wif.Demo/App.xaml.cs index bf6bbcd..6e95084 100644 --- a/Source/Demos/Wif.Demo/App.xaml.cs +++ b/Source/Demos/Wif.Demo/App.xaml.cs @@ -1,10 +1,17 @@ -using System; +using Microsoft.Extensions.Hosting; +using System; using System.Collections.Generic; using System.Configuration; using System.Data; +using System.Diagnostics; using System.Linq; +using System.Runtime.ExceptionServices; using System.Threading.Tasks; using System.Windows; +using System.Windows.Threading; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Wif.Demo.IocExtensions; namespace Wif.Demo { @@ -13,5 +20,128 @@ namespace Wif.Demo /// public partial class App : Application { + #region Private Fields + + /// + /// 定义程序当前的UI调度器。 + /// + public Dispatcher CurrentUIDispatcher { get; private set; } + + #endregion Private Fields + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public App() + { + InitHostBuilder(); + CurrentUIDispatcher = Current.Dispatcher; + } + + #endregion Constructors + + #region Fields + + /// + /// 定义通用主机字段。 + /// + private IHost _host; + + /// + /// 获取或设置依赖注入的容器。 + /// + public IServiceProvider Container { get; private set; } + + #endregion Fields + + #region Methods + + /// + /// UI线程抛出全局异常事件处理 + /// + /// + /// + [HandleProcessCorruptedStateExceptions] + private void App_OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) + { + try + { + MessageBox.Show($"UI线程全局异常\r\n{e.Exception}", "警告"); + e.Handled = true; + } + catch (Exception ex) + { + MessageBox.Show("应用程序发生不可恢复的异常,将要退出!", "警告"); + } + } + + /// + /// The App_OnExit + /// + /// The sender + /// The e + private async void App_OnExit(object sender, ExitEventArgs e) + { + using (_host) + { + await _host.StopAsync(TimeSpan.FromSeconds(1)); + } + } + + /// + /// The App_OnStartup + /// + /// The sender + /// The e + private async void App_OnStartup(object sender, StartupEventArgs e) + { + // 注册异常事件。 + Current.DispatcherUnhandledException += App_OnDispatcherUnhandledException; + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + + await _host.StartAsync(); + + var mainWindow = _host.Services.GetRequiredService(); + mainWindow.Show(); + } + + /// + /// 非UI线程抛出全局异常事件处理 + /// + /// + /// + [HandleProcessCorruptedStateExceptions] + private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + try + { + if (e.ExceptionObject is not Exception ex) + return; + CurrentUIDispatcher?.InvokeAsync(() => { MessageBox.Show($"非UI线程全局异常\r\n{ex.Message}"); }); + } + catch (Exception ex) + { + CurrentUIDispatcher?.InvokeAsync(() => { MessageBox.Show("应用程序发生不可恢复的异常,将要退出!"); }); + } + } + + /// + /// 创建和配置构建器对象。 + /// + private void InitHostBuilder() + { + // 初始化依赖注入 + _host = new HostBuilder() + .ConfigureView() + .UseEnvironment(Environments.Development) + .Build(); + + Container = _host.Services; + Locator.SetLocator(Container); + } + + #endregion Methods } } diff --git a/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml b/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml new file mode 100644 index 0000000..8a47af7 --- /dev/null +++ b/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml.cs b/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.xaml.cs new file mode 100644 index 0000000..c88f52b --- /dev/null +++ b/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoView.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 Wif.Demo.Examples.BindingDemo +{ + /// + /// BindingDemoView.xaml 的交互逻辑 + /// + public partial class BindingDemoView + { + public BindingDemoView() + { + InitializeComponent(); + } + } +} diff --git a/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoViewModel.cs b/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoViewModel.cs new file mode 100644 index 0000000..61747ad --- /dev/null +++ b/Source/Demos/Wif.Demo/Examples/BindingDemo/BindingDemoViewModel.cs @@ -0,0 +1,61 @@ +using System.Collections.ObjectModel; +using Frontier.Wif.Core.ComponentModel; +using Wif.Demo.Common; + +namespace Wif.Demo.Examples.BindingDemo +{ + public class BindingDemoViewModel: ViewModelBase + { + #region Fields + + /// + /// Defines the _mobilePhoneCollection + /// + private ObservableCollection _mobilePhoneCollection = new ObservableCollection(); + + #endregion + + #region Properties + + /// + /// Gets or sets the MobilePhoneCollection + /// + public ObservableCollection MobilePhoneCollection + { + get => _mobilePhoneCollection; + set => _mobilePhoneCollection = value; + } + + #endregion + + public BindingDemoViewModel() + { + var model = MobilePhoneSingletonModel.Instance; + model.Brand = Brand.Apple; + model.NumberOfCPUCore = NumberOfCPUCore.Quad; + model.RAM = RAM._4GB; + model.ROM = ROM._64GB; + model.ScreenResolution = ScreenResolution.FHD; + model.ScreenSize = 5.2f; + MobilePhoneCollection.Add(model); + + model = MobilePhoneSingletonModel.Instance; + model.Brand = Brand.Apple; + model.NumberOfCPUCore = NumberOfCPUCore.Quad; + model.RAM = RAM._4GB; + model.ROM = ROM._64GB; + model.ScreenResolution = ScreenResolution.FHD; + model.ScreenSize = 5.2f; + MobilePhoneCollection.Add(model); + + model = MobilePhoneSingletonModel.Instance; + model.Brand = Brand.Apple; + model.NumberOfCPUCore = NumberOfCPUCore.Quad; + model.RAM = RAM._4GB; + model.ROM = ROM._64GB; + model.ScreenResolution = ScreenResolution.FHD; + model.ScreenSize = 5.2f; + MobilePhoneCollection.Add(model); + } + } +} \ No newline at end of file diff --git a/Source/Demos/Wif.Demo/Examples/FileHelperDemo/FileHelperDemoView.xaml b/Source/Demos/Wif.Demo/Examples/FileHelperDemo/FileHelperDemoView.xaml new file mode 100644 index 0000000..8e36276 --- /dev/null +++ b/Source/Demos/Wif.Demo/Examples/FileHelperDemo/FileHelperDemoView.xaml @@ -0,0 +1,12 @@ + + +