feat: 集成化的窗口管理器

This commit is contained in:
denglihong2007
2025-08-02 20:29:19 +08:00
parent c0ce1bd31e
commit e69be43249
11 changed files with 175 additions and 75 deletions

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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<PluginInfo> 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<PluginInfo> StyleInfos => [.. IPluginService.LoadedPlugins.Where(x => x.Manifest.Type == "ScreenStyle" && x.LoadStatus == PluginLoadStatus.Loaded)];
public static IServiceProvider ServiceProvider { get; set; }
public ObservableCollection<SimulatorWindow> 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);

View File

@@ -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<bool> DataLoaded = new();
[ObservableProperty]
@@ -24,6 +25,8 @@ namespace CRSim.ScreenSimulator.ViewModels
private string _thisPlatform;
[ObservableProperty]
private string _thisTicketCheck;
[ObservableProperty]
private Uri _video;
public ObservableCollection<TrainInfo> ScreenA { get; private set; } = [];
public ObservableCollection<TrainInfo> ScreenB { get; private set; } = [];
public System.Windows.Threading.Dispatcher UIDispatcher { get; set; }

View File

@@ -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<TrainInfo> TrainInfos { get; set; } = [];
public MetroPlatformScreenViewModel(ITimeService timeService, ISettingsService settingsService)

View File

@@ -12,7 +12,8 @@
ResizeMode="NoResize"
WindowStyle="None"
AllowsTransparency="True"
MouseDown="Window_MouseDown">
MouseDown="Window_MouseDown"
Closed="Window_Closed">
<StackPanel Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
@@ -28,7 +29,7 @@
<TextBlock x:Name="SpeedText" Text="1x" FontSize="22" VerticalAlignment="Center" Margin="6,0"/>
<TextBlock Text="&#xF8AD;" FontFamily="Segoe MDL2 Assets" FontSize="20" VerticalAlignment="Center" MouseLeftButtonDown="IncreaseSpeed"/>
<TextBlock Text="&#xE711;" FontFamily="Segoe MDL2 Assets" FontSize="20"
VerticalAlignment="Center" Margin="12,0,2,0" MouseLeftButtonDown="Close"/>
VerticalAlignment="Center" Margin="12,0,2,0" MouseLeftButtonDown="CloseWindow"/>
</StackPanel>
</Border>
</Grid>

View File

@@ -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();
});
}
}
}