diff --git a/CRSim.ScreenSimulator/Abstractions/IScreenViewModel.cs b/CRSim.ScreenSimulator/Abstractions/IScreenViewModel.cs new file mode 100644 index 0000000..9f3f22d --- /dev/null +++ b/CRSim.ScreenSimulator/Abstractions/IScreenViewModel.cs @@ -0,0 +1,16 @@ +using CRSim.Core.Abstractions; +using CRSim.Core.Models; +using System.Windows.Threading; + +namespace CRSim.ScreenSimulator.Abstractions +{ + public interface IScreenViewModel + { + ITimeService TimeService { get; } + Dispatcher UIDispatcher { get; set; } + void LoadData(Station station, string ticketCheck, string platform); + string? Text { get; set; } + Uri Video { get; set; } + int Location { get; set; } + } +} diff --git a/CRSim.ScreenSimulator/Models/ScreenInfo.cs b/CRSim.ScreenSimulator/Models/ScreenInfo.cs deleted file mode 100644 index c8ee4ec..0000000 --- a/CRSim.ScreenSimulator/Models/ScreenInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace CRSim.ScreenSimulator.Models -{ - public class ScreenInfo - { - public required Guid SessionID { get; set; } - public required string SelectedStyle { get; set; } - public string? Text { get; set; } - public string? Video { get; set; } - public string? SelectedStationName { get; set; } - public string? SelectedTicketCheck { get; set; } - public string? SelectedPlatformName { get; set; } - public int? SelectedLoaction { get; set; } - } -} diff --git a/CRSim.ScreenSimulator/Models/Session.cs b/CRSim.ScreenSimulator/Models/Session.cs new file mode 100644 index 0000000..1543667 --- /dev/null +++ b/CRSim.ScreenSimulator/Models/Session.cs @@ -0,0 +1,17 @@ +using CRSim.Core.Models; + +namespace CRSim.ScreenSimulator.Models +{ + public class Session + { + public required Guid ID { get; set; } + public required string StyleName { get; set; } + public required DateTime SimulateTime { get; set; } + public string? Text { get; set; } + public Uri? Video { get; set; } + public Station? Station { get; set; } + public string? TicketCheck { get; set; } + public string? PlatformName { get; set; } + public int? Loaction { get; set; } + } +} diff --git a/CRSim.ScreenSimulator/StyleManager.cs b/CRSim.ScreenSimulator/StyleManager.cs index dcbf217..a20c05e 100644 --- a/CRSim.ScreenSimulator/StyleManager.cs +++ b/CRSim.ScreenSimulator/StyleManager.cs @@ -1,50 +1,63 @@ using CRSim.Core.Abstractions; using CRSim.Core.Enums; -using CRSim.Core.Models; using CRSim.Core.Models.Plugin; +using CRSim.ScreenSimulator.Abstractions; +using CRSim.ScreenSimulator.Models; using CRSim.ScreenSimulator.Views; -using System.Windows; +using System.Collections.ObjectModel; +using System.Collections.Specialized; using System.Windows.Controls; +using Windows.System; + namespace CRSim.ScreenSimulator { public class StyleManager { - public static List StyleInfos => [.. IPluginService.LoadedPlugins.Where(x => x.Manifest.Type == "ScreenStyle" && x.LoadStatus == PluginLoadStatus.Loaded)]; - public static IServiceProvider ServiceProvider; - private static IDatabaseService _databaseService; - public StyleManager(IServiceProvider serviceProvider,IDatabaseService databaseService) + public List StyleInfos => [.. IPluginService.LoadedPlugins.Where(x => x.Manifest.Type == "ScreenStyle" && x.LoadStatus == PluginLoadStatus.Loaded)]; + + public static IServiceProvider ServiceProvider { get; set; } + + public ObservableCollection ActiveWindows { get; set; } = []; + + public DispatcherQueue DispatcherQueue { get; set; } = DispatcherQueue.GetForCurrentThread(); + + public StyleManager(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; - _databaseService = databaseService; } - public static void ShowWindow(Type page, Station station, string ticketCheck, string platform,string? text,int location,string? video,DateTime dateTime) + public void ShowWindow(Type page, Session session) { Thread thread = new(() => { Page viewInstance = (Page)ServiceProvider.GetService(page); - var viewModel = ((dynamic)viewInstance).ViewModel; + if (viewInstance.DataContext is IScreenViewModel viewModel) + { + var timeService = viewModel.TimeService; + timeService.SimulateTime = session.SimulateTime; + timeService.Start(); - var timeService = ((ITimeService)viewModel.TimeService); - timeService.SimulateTime = dateTime; - timeService.Start(); - - viewModel.UIDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher; - if (text != null) - { - viewModel.Text = text; + viewModel.UIDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher; + if (session.Text != null) + { + viewModel.Text = session.Text; + } + if (session.Loaction != null && session.Loaction != 0) + { + viewModel.Location = session.Loaction.Value; + } + if (session.Video != null) + { + viewModel.Video = session.Video; + } + viewModel.LoadData(session.Station, session.TicketCheck, session.PlatformName); + var win = new SimulatorWindow(viewInstance, timeService, this, session); + DispatcherQueue.TryEnqueue(() => + { + ActiveWindows.Add(win); + }); + win.Show(); + System.Windows.Threading.Dispatcher.Run(); } - if (location != 0) - { - viewModel.Location = location; - } - if (video != null) - { - viewModel.Video = video; - } - viewModel.LoadData(station, ticketCheck, platform); - var win = new SimulatorWindow(viewInstance, timeService); - win.Show(); - System.Windows.Threading.Dispatcher.Run(); }); thread.SetApartmentState(ApartmentState.STA); diff --git a/CRSim.ScreenSimulator/ViewModels/ScreenViewModel.cs b/CRSim.ScreenSimulator/ViewModels/BaseScreenViewModel.cs similarity index 97% rename from CRSim.ScreenSimulator/ViewModels/ScreenViewModel.cs rename to CRSim.ScreenSimulator/ViewModels/BaseScreenViewModel.cs index 470d6b8..9e5d0ed 100644 --- a/CRSim.ScreenSimulator/ViewModels/ScreenViewModel.cs +++ b/CRSim.ScreenSimulator/ViewModels/BaseScreenViewModel.cs @@ -4,12 +4,13 @@ using CRSim.ScreenSimulator.Models; using System.Windows; using System.Collections.ObjectModel; using CRSim.Core.Abstractions; +using CRSim.ScreenSimulator.Abstractions; namespace CRSim.ScreenSimulator.ViewModels { - public partial class BaseScreenViewModel : ObservableObject + public partial class BaseScreenViewModel : ObservableObject,IScreenViewModel { - public readonly ITimeService TimeService; + public ITimeService TimeService { get; set; } public readonly Settings _settings; public readonly TaskCompletionSource DataLoaded = new(); [ObservableProperty] @@ -24,6 +25,8 @@ namespace CRSim.ScreenSimulator.ViewModels private string _thisPlatform; [ObservableProperty] private string _thisTicketCheck; + [ObservableProperty] + private Uri _video; public ObservableCollection ScreenA { get; private set; } = []; public ObservableCollection ScreenB { get; private set; } = []; public System.Windows.Threading.Dispatcher UIDispatcher { get; set; } diff --git a/CRSim.ScreenSimulator/ViewModels/MetroPlatformScreenViewModel.cs b/CRSim.ScreenSimulator/ViewModels/MetroPlatformScreenViewModel.cs index 1f4d7ef..20c6f24 100644 --- a/CRSim.ScreenSimulator/ViewModels/MetroPlatformScreenViewModel.cs +++ b/CRSim.ScreenSimulator/ViewModels/MetroPlatformScreenViewModel.cs @@ -1,13 +1,14 @@ using CommunityToolkit.Mvvm.ComponentModel; using CRSim.Core.Abstractions; using CRSim.Core.Models; +using CRSim.ScreenSimulator.Abstractions; using CRSim.ScreenSimulator.Models; namespace CRSim.ScreenSimulator.ViewModels { - public partial class MetroPlatformScreenViewModel : ObservableObject + public partial class MetroPlatformScreenViewModel : ObservableObject, IScreenViewModel { - public readonly ITimeService TimeService; + public ITimeService TimeService { get; set; } public readonly Settings _settings; [ObservableProperty] private DateTime _currentTime = new(); @@ -19,6 +20,8 @@ namespace CRSim.ScreenSimulator.ViewModels private string _text; [ObservableProperty] private Uri _video; + [ObservableProperty] + public int _location; public System.Windows.Threading.Dispatcher UIDispatcher { get; set; } public List TrainInfos { get; set; } = []; public MetroPlatformScreenViewModel(ITimeService timeService, ISettingsService settingsService) diff --git a/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml b/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml index 9f46159..a717ee4 100644 --- a/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml +++ b/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml @@ -12,7 +12,8 @@ ResizeMode="NoResize" WindowStyle="None" AllowsTransparency="True" - MouseDown="Window_MouseDown"> + MouseDown="Window_MouseDown" + Closed="Window_Closed"> @@ -28,7 +29,7 @@ + VerticalAlignment="Center" Margin="12,0,2,0" MouseLeftButtonDown="CloseWindow"/> diff --git a/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml.cs b/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml.cs index 52e66d2..8c09ecd 100644 --- a/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml.cs +++ b/CRSim.ScreenSimulator/Views/SimulatorWindow.xaml.cs @@ -1,5 +1,6 @@ -using CRSim.Core.Abstractions; -using CRSim.ScreenSimulator.Converters; +using CommunityToolkit.Mvvm.Input; +using CRSim.Core.Abstractions; +using CRSim.ScreenSimulator.Models; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -10,13 +11,16 @@ namespace CRSim.ScreenSimulator.Views public partial class SimulatorWindow : Window { private readonly ITimeService _timeService; - - public SimulatorWindow(Page page,ITimeService timeService) + private readonly StyleManager _styleManager; + public Session Session { get; } + public SimulatorWindow(Page page,ITimeService timeService,StyleManager styleManager,Session session) { + Session = session; InitializeComponent(); RenderOptions.SetEdgeMode(this, EdgeMode.Aliased); contentFrame.Content = page; _timeService = timeService; + _styleManager = styleManager; foreach (var resource in page.Resources.Values) { if (resource is IHasTimeService needsTime) @@ -48,9 +52,31 @@ namespace CRSim.ScreenSimulator.Views } } - private void Close(object sender, MouseButtonEventArgs e) + private void Window_Closed(object sender, EventArgs e) { - Close(); + _styleManager.DispatcherQueue.TryEnqueue(() => + { + _styleManager.ActiveWindows.Remove(this); + }); + } + + public void FoucsWindow(object o,object s) + { + Dispatcher.Invoke(() => + { + WindowState = WindowState.Normal; + Activate(); + Topmost = true; + Topmost = false; + Focus(); + }); + } + public void CloseWindow(object o, object s) + { + Dispatcher.Invoke(() => + { + Close(); + }); } } } diff --git a/CRSim/ViewModels/DashboardPageViewModel.cs b/CRSim/ViewModels/DashboardPageViewModel.cs index 8ace8e3..65f345c 100644 --- a/CRSim/ViewModels/DashboardPageViewModel.cs +++ b/CRSim/ViewModels/DashboardPageViewModel.cs @@ -1,9 +1,11 @@ -namespace CRSim.ViewModels; +using System.Windows; + +namespace CRSim.ViewModels; public partial class DashboardPageViewModel : ObservableObject { - - [RelayCommand] - private void AddItem() + public StyleManager StyleManager { get; } + public DashboardPageViewModel(StyleManager styleManager) { + StyleManager = styleManager; } } \ No newline at end of file diff --git a/CRSim/ViewModels/ScreenSimulatorPageViewModel.cs b/CRSim/ViewModels/ScreenSimulatorPageViewModel.cs index 84e176b..620d8fe 100644 --- a/CRSim/ViewModels/ScreenSimulatorPageViewModel.cs +++ b/CRSim/ViewModels/ScreenSimulatorPageViewModel.cs @@ -1,11 +1,13 @@ using CRSim.Core.Models.Plugin; +using CRSim.ScreenSimulator.Models; namespace CRSim.ViewModels; -public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvider, IDatabaseService databaseService) : ObservableObject +public partial class ScreenSimulatorPageViewModel(IEnumerable plugins, IDatabaseService databaseService, StyleManager styleManager) : ObservableObject { public string PageTitle = "引导屏模拟"; - public List StyleInfos => StyleManager.StyleInfos; + public List StyleInfos => styleManager.StyleInfos; + [ObservableProperty] public partial PluginInfo SelectedStyle { get; set; } @@ -30,6 +32,7 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid public ObservableCollection TicketChecks { get; private set; } = []; public ObservableCollection Platforms { get; private set; } = []; public ObservableCollection Locations { get; private set; } = []; + [ObservableProperty] public partial string Text { get; set; } @@ -46,7 +49,8 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid [ObservableProperty] public partial bool IsStartSimulationAvailable { get; private set; } = false; - private PluginBase SelectedStylePlugin => serviceProvider.GetServices().Where(x => x.Info == SelectedStyle).FirstOrDefault(); + + private PluginBase SelectedStylePlugin => plugins.Where(x => x.Info == SelectedStyle).FirstOrDefault(); public DateTimeOffset SelectedDate = DateTime.Today; @@ -135,16 +139,22 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid //Video = Path; } [RelayCommand] - public async Task StartSimulation() + public void StartSimulation() { - StyleManager.ShowWindow(SelectedStylePlugin.View, - databaseService.GetStationByName(SelectedStationName), - TicketCheckNeeded ? SelectedTicketCheck : string.Empty, - PlatformNeeded ? SelectedPlatformName : string.Empty, - (TextNeeded && Text != string.Empty) ? Text : null, - (LocationNeeded && SelectedLoaction != 0) ? SelectedLoaction : 0, - (VideoNeeded && Video != string.Empty) ? Video : null, - SelectedDate.Add(SelectedTime).DateTime); + // 构建 Session 对象 + var session = new Session + { + ID = Guid.NewGuid(), + StyleName = SelectedStyle.Manifest.Name, + SimulateTime = SelectedDate.Add(SelectedTime).DateTime, + Text = (TextNeeded && !string.IsNullOrWhiteSpace(Text)) ? Text : null, + Video = (VideoNeeded && !string.IsNullOrWhiteSpace(Video)) ? new Uri(Video) : null, + Station = StationNeeded ? databaseService.GetStationByName(SelectedStationName) : null, + TicketCheck = TicketCheckNeeded ? SelectedTicketCheck : string.Empty, + PlatformName = PlatformNeeded ? SelectedPlatformName : string.Empty, + Loaction = (LocationNeeded && SelectedLoaction != 0) ? SelectedLoaction : 0 + }; + styleManager.ShowWindow(SelectedStylePlugin.View, session); } private void CheckCanStart() diff --git a/CRSim/Views/DashboardPage.xaml b/CRSim/Views/DashboardPage.xaml index 75cbee8..9098e92 100644 --- a/CRSim/Views/DashboardPage.xaml +++ b/CRSim/Views/DashboardPage.xaml @@ -4,11 +4,34 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:CRSim.Views" + xmlns:winui="using:CommunityToolkit.WinUI" + xmlns:screensim="using:CRSim.ScreenSimulator.Views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> - - - - + + + + + + + + + + + + + + + +