mirror of
https://github.com/denglihong2007/CRSim
synced 2026-08-06 17:53:17 +08:00
feat: 站台占用示意图生成器
This commit is contained in:
19
CRSim.PlatformDiagram/CRSim.PlatformDiagram.csproj
Normal file
19
CRSim.PlatformDiagram/CRSim.PlatformDiagram.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0-windows10.0.19041.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="itext" Version="9.3.0" />
|
||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.3.0" />
|
||||
<PackageReference Include="itext.font-asian" Version="9.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CRSim.Core\CRSim.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
246
CRSim.PlatformDiagram/PlatformDiagram.cs
Normal file
246
CRSim.PlatformDiagram/PlatformDiagram.cs
Normal file
@@ -0,0 +1,246 @@
|
||||
using CRSim.Core.Models;
|
||||
using iText.IO.Font;
|
||||
using iText.Kernel.Colors;
|
||||
using iText.Kernel.Font;
|
||||
using iText.Kernel.Geom;
|
||||
using iText.Kernel.Pdf;
|
||||
using iText.Kernel.Pdf.Canvas;
|
||||
using iText.Layout;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Properties;
|
||||
|
||||
namespace CRSim.PlatformDiagram
|
||||
{
|
||||
public class Generator
|
||||
{
|
||||
public static void Generate(Station station, string savePath)
|
||||
{
|
||||
float PageWidth = 5000;
|
||||
float Padding = 40;
|
||||
float HeaderHeight = 16;
|
||||
float PlatformTableVerticalMargin = 9;
|
||||
float PlatformTableHorizontalMargin = 10;
|
||||
float TimelineHeight = 10;
|
||||
float TimelineExtLength = 4;
|
||||
float PlatformHeight = 55;
|
||||
float InfoBarWidth = 50;
|
||||
|
||||
PdfWriter writer = new(savePath);
|
||||
PdfDocument pdf = new(writer);
|
||||
PdfFont font = PdfFontFactory.CreateFont("C:/Windows/Fonts/simsun.ttc,1", PdfEncodings.IDENTITY_H);
|
||||
|
||||
int platformCount = station.Platforms.Count;
|
||||
float pageHeight = (Padding + TimelineHeight + PlatformTableVerticalMargin) * 2 + platformCount * PlatformHeight + HeaderHeight;
|
||||
Document doc = new(pdf, new PageSize(PageWidth, pageHeight)); doc.SetMargins(Padding, Padding, Padding, Padding);
|
||||
var canvas = new PdfCanvas(pdf.AddNewPage());
|
||||
TimeSpan startTime = TimeSpan.FromHours(0);
|
||||
TimeSpan endTime = TimeSpan.FromHours(24);
|
||||
|
||||
#region 时间线
|
||||
int intervalMin = 10;
|
||||
Color lineColor = new DeviceRgb(0xAA, 0xAA, 0x7E);
|
||||
canvas.SetStrokeColor(lineColor);
|
||||
|
||||
// 绘制整条横线
|
||||
canvas.SetLineWidth(1f);
|
||||
var xStart = Padding + InfoBarWidth + PlatformTableHorizontalMargin - TimelineExtLength;
|
||||
var xEnd = PageWidth - Padding;
|
||||
var yTop = pageHeight - Padding - HeaderHeight - TimelineHeight;
|
||||
var yBottom = Padding + TimelineHeight;
|
||||
canvas.MoveTo(xStart, yTop).LineTo(xEnd, yTop).Stroke();
|
||||
canvas.MoveTo(xStart, yBottom).LineTo(xEnd, yBottom).Stroke();
|
||||
|
||||
// 画线和时间文字
|
||||
var xBase = Padding + InfoBarWidth + PlatformTableHorizontalMargin;
|
||||
yTop = pageHeight - Padding - HeaderHeight - TimelineHeight - PlatformTableVerticalMargin;
|
||||
yBottom = Padding + TimelineHeight + PlatformTableVerticalMargin;
|
||||
var PlatformTableLength = PageWidth - Padding * 2 - InfoBarWidth - PlatformTableHorizontalMargin - TimelineExtLength;
|
||||
for (TimeSpan t = startTime; t <= endTime; t += TimeSpan.FromMinutes(intervalMin))
|
||||
{
|
||||
float x = xBase + MapTime(t, startTime, endTime, PlatformTableLength);
|
||||
// 设置竖线样式
|
||||
if (t.Minutes % 60 == 0)
|
||||
{
|
||||
canvas.SetLineWidth(1f);
|
||||
canvas.SetLineDash(0);
|
||||
}
|
||||
else if (t.Minutes % 30 == 0)
|
||||
{
|
||||
canvas.SetLineWidth(0.5f);
|
||||
canvas.SetLineDash(0);
|
||||
}
|
||||
else // 10分钟
|
||||
{
|
||||
canvas.SetLineWidth(0.5f);
|
||||
canvas.SetLineDash(3, 3);
|
||||
}
|
||||
// 竖线从下横线到上横线
|
||||
canvas.MoveTo(x, yBottom).LineTo(x, yTop).Stroke();
|
||||
static void DrawLabel(PdfCanvas canvas, PdfFont font, string text, float x, float y, float width, float height, Color color, bool alignBottom)
|
||||
{
|
||||
// 获取文字度量信息
|
||||
float fontSize = text != "30" ? 14 : 10;
|
||||
float textWidth = font.GetWidth(text, fontSize);
|
||||
float ascent = font.GetAscent(text, fontSize);
|
||||
float descent = font.GetDescent(text, fontSize);
|
||||
float textHeight = ascent - descent;
|
||||
|
||||
// 水平居中
|
||||
float textX = x + (width - textWidth) / 2;
|
||||
|
||||
// 垂直位置
|
||||
float textY;
|
||||
if (alignBottom)
|
||||
{
|
||||
textY = y - descent;
|
||||
}
|
||||
else
|
||||
{
|
||||
textY = y + height - ascent;
|
||||
}
|
||||
// 绘制文字
|
||||
canvas.BeginText();
|
||||
canvas.SetFontAndSize(font, fontSize);
|
||||
canvas.SetFillColor(color);
|
||||
canvas.MoveText(textX, textY);
|
||||
canvas.ShowText(text);
|
||||
canvas.EndText();
|
||||
}
|
||||
if (t.Minutes % 60 == 0) // 整点显示小时
|
||||
{
|
||||
string label = $"{t.Hours:D1}";
|
||||
DrawLabel(canvas, font, label, x - 10, yTop + PlatformTableVerticalMargin + 2, 20, TimelineHeight, lineColor, alignBottom: true);
|
||||
DrawLabel(canvas, font, label, x - 10, yBottom - PlatformTableVerticalMargin - TimelineHeight - 2, 20, TimelineHeight, lineColor, alignBottom: false);
|
||||
}
|
||||
else if (t.Minutes % 30 == 0) // 半点显示“30”
|
||||
{
|
||||
DrawLabel(canvas, font, "30", x - 10, yTop + PlatformTableVerticalMargin + 2, 20, TimelineHeight, lineColor, alignBottom: true);
|
||||
DrawLabel(canvas, font, "30", x - 10, yBottom - PlatformTableVerticalMargin - TimelineHeight - 2, 20, TimelineHeight, lineColor, alignBottom: false);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, float> platformHeights = station.TrainStops
|
||||
.Select(x => x.Platform)
|
||||
.Where(p => p != null)
|
||||
.Distinct()
|
||||
.ToDictionary(p => p!, p => 0f);
|
||||
canvas.MoveTo(xBase, yBottom).LineTo(xEnd - TimelineExtLength, yBottom).Stroke();
|
||||
for (int i = 0; i < platformCount; i++)
|
||||
{
|
||||
string name = station.Platforms[i].Name;
|
||||
if (double.TryParse(name, out double platformNumber))
|
||||
{
|
||||
platformHeights[name] = yBottom + (platformCount - i - 1f) * PlatformHeight;
|
||||
}
|
||||
canvas.SetLineWidth(1f);
|
||||
canvas.MoveTo(xBase, yBottom + (platformCount - i) * PlatformHeight)
|
||||
.LineTo(xEnd - TimelineExtLength, yBottom + (platformCount - i) * PlatformHeight)
|
||||
.Stroke();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 列车
|
||||
foreach (var train in station.TrainStops)
|
||||
{
|
||||
float barHeight = PlatformHeight / 2.5f - 4;
|
||||
TimeSpan fixedDuration = TimeSpan.FromMinutes(2);
|
||||
if (train.Platform is null || !platformHeights.TryGetValue(train.Platform, out var yBottom1))
|
||||
continue;
|
||||
TimeSpan arrival = (TimeSpan)(train.ArrivalTime ?? train.DepartureTime - fixedDuration);
|
||||
TimeSpan departure = (TimeSpan)(train.DepartureTime ?? train.ArrivalTime + fixedDuration);
|
||||
|
||||
var trainColors = new Dictionary<string, string>
|
||||
{
|
||||
{ "G", "FF00BE" }, // pink
|
||||
{ "D", "004C99" }, // deep blue
|
||||
{ "C", "009999" }, // cyan
|
||||
{ "T", "0000FF" }, // blue
|
||||
{ "Z", "804000" }, // brown
|
||||
{ "K", "FF0000" }, // red
|
||||
{ "Y", "FF0000" }, // red
|
||||
{ "L", "008000" }, // dark green
|
||||
{ "default", "008000" } // dark green
|
||||
};
|
||||
string firstChar = train.Number[..1].ToUpper();
|
||||
string colorHex = trainColors.TryGetValue(firstChar, out string? value) ? value : trainColors["default"];
|
||||
var color = new DeviceRgb(
|
||||
Convert.ToInt32(colorHex[..2], 16),
|
||||
Convert.ToInt32(colorHex.Substring(2, 2), 16),
|
||||
Convert.ToInt32(colorHex.Substring(4, 2), 16)
|
||||
);
|
||||
canvas.SetFillColor(color);
|
||||
canvas.SetStrokeColor(color);
|
||||
|
||||
// 检查是否跨零点
|
||||
if (departure < arrival)
|
||||
{
|
||||
float xStart1 = Padding + InfoBarWidth + PlatformTableHorizontalMargin + MapTime(arrival, startTime, endTime, PlatformTableLength);
|
||||
float xEnd1 = Padding + InfoBarWidth + PlatformTableHorizontalMargin + MapTime(TimeSpan.FromHours(24), startTime, endTime, PlatformTableLength);
|
||||
canvas.RoundRectangle(xStart1, yBottom1 + 4, xEnd1 - xStart1, barHeight, 3f);
|
||||
var rect = new Rectangle(xStart1, yBottom1 + 4 + barHeight, 150, PlatformHeight - barHeight - 8);
|
||||
var pdfCanvas = new Canvas(canvas, rect);
|
||||
string timeStr = train.ArrivalTime.HasValue && train.DepartureTime.HasValue
|
||||
? $"{train.ArrivalTime.Value.Minutes} {train.DepartureTime.Value.Minutes}"
|
||||
: train.ArrivalTime?.Minutes.ToString() ?? train.DepartureTime?.Minutes.ToString() ?? "";
|
||||
pdfCanvas.Add(new Paragraph($"{train.Number}\n{train.Origin}->{train.Terminal}\n{timeStr}")
|
||||
.SetFont(font)
|
||||
.SetFontSize(8)
|
||||
.SetMultipliedLeading(1f)
|
||||
.SetMargins(0, 0, 0, 0));
|
||||
canvas.Fill();
|
||||
float xStart2 = Padding + InfoBarWidth + PlatformTableHorizontalMargin + MapTime(TimeSpan.Zero, startTime, endTime, PlatformTableLength);
|
||||
float xEnd2 = Padding + InfoBarWidth + PlatformTableHorizontalMargin + MapTime(departure, startTime, endTime, PlatformTableLength);
|
||||
canvas.RoundRectangle(xStart2, yBottom1 + 4, xEnd2 - xStart2, barHeight, 3f);
|
||||
canvas.Fill();
|
||||
}
|
||||
else
|
||||
{
|
||||
xStart = Padding + InfoBarWidth + PlatformTableHorizontalMargin + MapTime(arrival, startTime, endTime, PlatformTableLength);
|
||||
xEnd = Padding + InfoBarWidth + PlatformTableHorizontalMargin + MapTime(departure, startTime, endTime, PlatformTableLength);
|
||||
canvas.RoundRectangle(xStart, yBottom1 + 4, xEnd - xStart, barHeight, 3f);
|
||||
var rect = new Rectangle(xStart, yBottom1 + 4 + barHeight, 150, PlatformHeight - barHeight - 8);
|
||||
var pdfCanvas = new Canvas(canvas, rect);
|
||||
string timeStr = train.ArrivalTime.HasValue && train.DepartureTime.HasValue
|
||||
? $"{train.ArrivalTime.Value.Minutes} {train.DepartureTime.Value.Minutes}"
|
||||
: train.ArrivalTime?.Minutes.ToString() ?? train.DepartureTime?.Minutes.ToString() ?? "";
|
||||
pdfCanvas.Add(new Paragraph($"{train.Number + (train.ArrivalTime.HasValue ? "" : "*") + (train.DepartureTime.HasValue ? "" : "#")}\n{train.Origin}->{train.Terminal}\n{timeStr}")
|
||||
.SetFont(font)
|
||||
.SetFontSize(8)
|
||||
.SetMultipliedLeading(1f)
|
||||
.SetMargins(0,0,0,0));
|
||||
canvas.Fill();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 基本信息
|
||||
Rectangle rect1 = new(Padding, pageHeight - Padding, 500, HeaderHeight);
|
||||
var layoutCanvas = new Canvas(canvas, rect1);
|
||||
layoutCanvas.Add(new Paragraph($"{station.Name}站台占用示意图")
|
||||
.SetFont(font)
|
||||
.SetFontSize(18)
|
||||
.SetFontColor(ColorConstants.BLUE)
|
||||
.SetMargins(0,0,0,0));
|
||||
foreach(var kvp in platformHeights)
|
||||
{
|
||||
rect1 = new(Padding, kvp.Value + PlatformHeight / 2 - 10, InfoBarWidth, 20);
|
||||
layoutCanvas = new Canvas(canvas, rect1);
|
||||
layoutCanvas.Add(new Paragraph($"{kvp.Key}站台")
|
||||
.SetFont(font)
|
||||
.SetFontSize(14)
|
||||
.SetMargins(0, 0, 0, 0)
|
||||
.SetFontColor(ColorConstants.BLUE)
|
||||
.SetTextAlignment(TextAlignment.CENTER)
|
||||
.SetVerticalAlignment(VerticalAlignment.MIDDLE));
|
||||
}
|
||||
#endregion
|
||||
doc.Close();
|
||||
}
|
||||
static float MapTime(TimeSpan t, TimeSpan start, TimeSpan end, float width)
|
||||
{
|
||||
double totalMinutes = (end - start).TotalMinutes;
|
||||
double posMinutes = (t - start).TotalMinutes;
|
||||
return (float)(posMinutes / totalMinutes * width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CRSim", "CRSim\CRSim.csproj
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CRSim.ScreenSimulator", "CRSim.ScreenSimulator\CRSim.ScreenSimulator.csproj", "{94927020-7AD7-4F6F-A456-F34A8E0BC40A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CRSim.PlatformDiagram", "CRSim.PlatformDiagram\CRSim.PlatformDiagram.csproj", "{895EE8B3-1A15-4CA8-9AFE-246585732AA5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -29,6 +31,10 @@ Global
|
||||
{94927020-7AD7-4F6F-A456-F34A8E0BC40A}.Debug|x64.Build.0 = Debug|x64
|
||||
{94927020-7AD7-4F6F-A456-F34A8E0BC40A}.Release|x64.ActiveCfg = Release|x64
|
||||
{94927020-7AD7-4F6F-A456-F34A8E0BC40A}.Release|x64.Build.0 = Release|x64
|
||||
{895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{895EE8B3-1A15-4CA8-9AFE-246585732AA5}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CRSim.WebsiteSimulator;
|
||||
using CRSim.PlatformDiagram;
|
||||
using CRSim.WebsiteSimulator;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CRSim
|
||||
@@ -43,14 +44,16 @@ namespace CRSim
|
||||
services.AddSingleton<StyleManager>();
|
||||
services.AddSingleton<MainWindow>();
|
||||
services.AddSingleton<StartWindow>();
|
||||
services.AddSingleton<Generator>();
|
||||
services.AddTransient<Simulator>();
|
||||
services.AddTransient<DashboardPageViewModel>();
|
||||
services.AddTransient<StationManagementPageViewModel>();
|
||||
services.AddTransient<TrainNumberManagementPageViewModel>();
|
||||
services.AddTransient<WebsiteSimulatorPageViewModel>();
|
||||
services.AddTransient<Simulator>();
|
||||
services.AddTransient<ScreenSimulatorPageViewModel>();
|
||||
services.AddTransient<PluginManagementPageViewModel>();
|
||||
services.AddTransient<PlatformDiagramPageViewModel>();
|
||||
services.AddTransient<SettingsPageViewModel>();
|
||||
services.AddTransient<PluginManagementPageViewModel>();
|
||||
PluginService.InitializePlugins(context, services, parsedOptions.ExternalPluginPath);
|
||||
})
|
||||
.Build();
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CRSim.Core\CRSim.Core.csproj" />
|
||||
<ProjectReference Include="..\CRSim.PlatformDiagram\CRSim.PlatformDiagram.csproj" />
|
||||
<ProjectReference Include="..\CRSim.ScreenSimulator\CRSim.ScreenSimulator.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -77,6 +78,9 @@
|
||||
<Page Update="Views\DialogContents\PlatformDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\PlatformDiagramPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\WebsiteSimulatorPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
<FontIcon Glyph="" />
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
<NavigationViewItem Content="站台占用图" Tag="PlatformDiagramPage">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph="" />
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
<NavigationViewItem Content="12306" Tag="WebsiteSimulatorPage">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph="" />
|
||||
|
||||
65
CRSim/ViewModels/PlatformDiagramPageViewModel.cs
Normal file
65
CRSim/ViewModels/PlatformDiagramPageViewModel.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using CRSim.PlatformDiagram;
|
||||
|
||||
namespace CRSim.ViewModels;
|
||||
|
||||
public partial class PlatformDiagramPageViewModel(IDialogService _dialogService, IDatabaseService _databaseService, Generator _generator) : ObservableObject
|
||||
{
|
||||
public string PageTitle = "生成站台占用图";
|
||||
public Station? SelectedStation;
|
||||
public List<Station> Stations => _databaseService.GetAllStations();
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsSelected { get; set; } = false;
|
||||
|
||||
[RelayCommand]
|
||||
public void StationSelected(object s)
|
||||
{
|
||||
if(s is Station station)
|
||||
{
|
||||
SelectedStation = station;
|
||||
IsSelected = true;
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async Task Generate()
|
||||
{
|
||||
if(!CheckStation(SelectedStation,out string detail))
|
||||
{
|
||||
await _dialogService.ShowTextAsync("警告", detail);
|
||||
}
|
||||
var path = _dialogService.SaveFile(".pdf", $"{SelectedStation.Name}站台占用图");
|
||||
if(string.IsNullOrEmpty(path) || SelectedStation == null) return;
|
||||
await Task.Run(() => Generator.Generate(SelectedStation, path));
|
||||
}
|
||||
|
||||
public static bool CheckStation(Station station,out string detail)
|
||||
{
|
||||
detail = string.Empty;
|
||||
var trainStops = station.TrainStops;
|
||||
var platformGroups = trainStops
|
||||
.Where(ts => !string.IsNullOrEmpty(ts.Platform) && ts.DepartureTime != null && ts.ArrivalTime != null)
|
||||
.GroupBy(ts => ts.Platform);
|
||||
foreach (var group in platformGroups)
|
||||
{
|
||||
var stops = group.OrderBy(ts => ts.ArrivalTime ?? TimeSpan.Zero).ToList();
|
||||
for (int i = 0; i < stops.Count - 1; i++)
|
||||
{
|
||||
var current = stops[i];
|
||||
var next = stops[i + 1];
|
||||
// 判断时间是否重叠
|
||||
if (current.DepartureTime != null && next.ArrivalTime != null &&
|
||||
current.DepartureTime > next.ArrivalTime)
|
||||
{
|
||||
detail += $"\n站台 {group.Key} 车次 {current.Number} ({current.ArrivalTime:hh\\:mm}-{current.DepartureTime:hh\\:mm}) 与车次 {next.Number} ({next.ArrivalTime:hh\\:mm}-{next.DepartureTime:hh\\:mm}) 时间重叠;";
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!string.IsNullOrEmpty(detail))
|
||||
{
|
||||
detail = $"检查到冲突 {detail.Count('\n')} 个!{detail}\n程序将会继续尝试绘制图像。";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
42
CRSim/Views/PlatformDiagramPage.xaml
Normal file
42
CRSim/Views/PlatformDiagramPage.xaml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Page
|
||||
x:Class="CRSim.Views.PlatformDiagramPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CRSim.Views"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewmodels="using:CRSim.ViewModels"
|
||||
xmlns:winui="using:CommunityToolkit.WinUI"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||
Loaded="Page_Loaded"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=viewmodels:PlatformDiagramPageViewModel}">
|
||||
<Grid x:Name="ContentPagePane" Margin="36,40,0,36">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="{x:Bind ViewModel.PageTitle}" Margin="0,0,0,36"
|
||||
Style="{StaticResource TitleTextBlockStyle}"/>
|
||||
<ScrollViewer Grid.Row="1" Padding="0,0,36,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="操作" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
|
||||
<controls:SettingsCard Header="车站" Description="选择目标车站。" HeaderIcon="{winui:FontIcon Glyph=}">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.Stations}" DisplayMemberPath="Name" Name="StationsComboBox">
|
||||
<i:Interaction.Behaviors>
|
||||
<i:EventTriggerBehavior EventName="SelectionChanged">
|
||||
<i:InvokeCommandAction Command="{x:Bind ViewModel.StationSelectedCommand}" CommandParameter="{x:Bind StationsComboBox.SelectedItem, Mode=OneWay}"/>
|
||||
</i:EventTriggerBehavior>
|
||||
</i:Interaction.Behaviors>
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Margin="0,4,0,0" Header="生成并保存图示" Description="选择位置保存图示。" HeaderIcon="{winui:FontIcon Glyph=}">
|
||||
<Button Content="生成" IsEnabled="{x:Bind ViewModel.IsSelected, Mode=OneWay}" Style="{StaticResource AccentButtonStyle}"
|
||||
Command="{x:Bind ViewModel.GenerateCommand}"/>
|
||||
</controls:SettingsCard>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Page>
|
||||
17
CRSim/Views/PlatformDiagramPage.xaml.cs
Normal file
17
CRSim/Views/PlatformDiagramPage.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace CRSim.Views;
|
||||
|
||||
public sealed partial class PlatformDiagramPage : Page
|
||||
{
|
||||
public PlatformDiagramPageViewModel ViewModel { get; } = App.AppHost.Services.GetService<PlatformDiagramPageViewModel>();
|
||||
|
||||
public PlatformDiagramPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
App.AppHost.Services.GetService<IDialogService>().XamlRoot = this.XamlRoot;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user