feat: 移植了设置界面

This commit is contained in:
denglihong2007
2025-07-13 13:12:04 +08:00
parent c32c42e9a0
commit 63be26ef9e
10 changed files with 299 additions and 23 deletions

View File

@@ -33,6 +33,7 @@
services.AddTransient<DashboardPageViewModel>();
services.AddTransient<StationManagementPageViewModel>();
services.AddTransient<ScreenSimulatorPageViewModel>();
services.AddTransient<SettingsPageViewModel>();
PluginService.InitializePlugins(context, services, parsedOptions.ExternalPluginPath);
})
.Build();

View File

@@ -13,7 +13,7 @@
<Nullable>enable</Nullable>
<WindowsPackageType>None</WindowsPackageType>
<LangVersion>preview</LangVersion>
<Version>2.3.100</Version>
<Version>2.3.101.0</Version>
</PropertyGroup>
<ItemGroup>
<Content Remove="Assets\CRSimIcon.png" />
@@ -82,6 +82,9 @@
<Page Update="Views\ScreenSimulatorPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\SettingsPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\StationManagementPage.xaml">
<SubType>Designer</SubType>
</Page>

View File

@@ -29,6 +29,11 @@ public sealed partial class MainWindow : Window
private void nvSample_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs e)
{
if(e.IsSettingsSelected)
{
contentFrame.Navigate(typeof(Views.SettingsPage));
return;
}
if (nvSample.SelectedItem is NavigationViewItem selectedItem && selectedItem.Tag is string pageTag)
{
var pageType = Type.GetType($"CRSim.Views.{pageTag}");

View File

@@ -7,4 +7,11 @@
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
<Setter Property="BorderThickness" Value="1" />
</Style>
<Style x:Key="SettingsSectionHeaderTextBlockStyle"
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
TargetType="TextBlock">
<Style.Setters>
<Setter Property="Margin" Value="1,30,0,6" />
</Style.Setters>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,124 @@
using System.Reflection;
namespace CRSim.ViewModels
{
public partial class SettingsPageViewModel : ObservableObject
{
[ObservableProperty]
public partial string PageTitle { get; set; } = "设置";
[ObservableProperty]
public partial string AppVersion { get; set; } = "";
private Settings _settings;
private readonly ISettingsService _settingsService;
private readonly IDatabaseService _databaseService;
private readonly IDialogService _dialogService;
#region
[ObservableProperty]
public partial string TimeOffset { get; set; }
[ObservableProperty]
public partial string DepartureCheckInAdvanceDuration { get; set; }
[ObservableProperty]
public partial string PassingCheckInAdvanceDuration { get; set; }
[ObservableProperty]
public partial string StopDisplayUntilDepartureDuration { get; set; }
[ObservableProperty]
public partial string StopDisplayFromArrivalDuration { get; set; }
[ObservableProperty]
public partial string StopCheckInAdvanceDuration { get; set; }
[ObservableProperty]
public partial string MaxPages { get; set; }
[ObservableProperty]
public partial string SwitchPageSeconds { get; set; }
[ObservableProperty]
public partial string UserKey { get; set; }
[ObservableProperty]
public partial bool LoadTodayOnly { get; set; }
[ObservableProperty]
public partial bool ReopenUnclosedScreensOnLoad { get; set; }
#endregion
public SettingsPageViewModel(ISettingsService settingsService, IDatabaseService databaseService, IDialogService dialogService)
{
_settingsService = settingsService;
_databaseService = databaseService;
_dialogService = dialogService;
var version = Assembly.GetExecutingAssembly().GetName().Version;
AppVersion = $"Version {version}";
LoadSettings();
}
private void LoadSettings()
{
_settings = _settingsService.GetSettings();
TimeOffset = _settings.TimeOffset.TotalMinutes.ToString();
DepartureCheckInAdvanceDuration = _settings.DepartureCheckInAdvanceDuration.TotalMinutes.ToString();
PassingCheckInAdvanceDuration = _settings.PassingCheckInAdvanceDuration.TotalMinutes.ToString();
StopDisplayUntilDepartureDuration = _settings.StopDisplayUntilDepartureDuration.TotalMinutes.ToString();
StopDisplayFromArrivalDuration = _settings.StopDisplayFromArrivalDuration.TotalMinutes.ToString();
StopCheckInAdvanceDuration = _settings.StopCheckInAdvanceDuration.TotalMinutes.ToString();
MaxPages = _settings.MaxPages.ToString();
SwitchPageSeconds = _settings.SwitchPageSeconds.ToString();
UserKey = _settings.UserKey;
LoadTodayOnly = _settings.LoadTodayOnly;
ReopenUnclosedScreensOnLoad = _settings.ReopenUnclosedScreensOnLoad;
}
[RelayCommand]
public void Unload()
{
UpdateSettings(TimeOffset, true, value => _settings.TimeOffset = TimeSpan.FromMinutes(value));
UpdateSettings(DepartureCheckInAdvanceDuration, false, value => _settings.DepartureCheckInAdvanceDuration = TimeSpan.FromMinutes(value));
UpdateSettings(PassingCheckInAdvanceDuration, false, value => _settings.PassingCheckInAdvanceDuration = TimeSpan.FromMinutes(value));
UpdateSettings(StopDisplayUntilDepartureDuration, false, value => _settings.StopDisplayUntilDepartureDuration = TimeSpan.FromMinutes(value));
UpdateSettings(StopDisplayFromArrivalDuration, false, value => _settings.StopDisplayFromArrivalDuration = TimeSpan.FromMinutes(value));
UpdateSettings(StopCheckInAdvanceDuration, false, value => _settings.StopCheckInAdvanceDuration = TimeSpan.FromMinutes(value));
UpdateSettings(MaxPages, false, value => _settings.MaxPages = value);
UpdateSettings(SwitchPageSeconds, false, value => _settings.SwitchPageSeconds = value);
_settings.UserKey = UserKey;
_settings.LoadTodayOnly = LoadTodayOnly;
_settings.ReopenUnclosedScreensOnLoad = ReopenUnclosedScreensOnLoad;
_settingsService.SaveSettings();
}
private void UpdateSettings(string input, bool allowNegative, Action<int> updateAction)
{
if (int.TryParse(input, out int value) && (allowNegative || value >= 0))
{
updateAction(value);
}
}
[RelayCommand]
public async Task ClearData()
{
if (!await _dialogService.GetConfirmAsync("该操作将会清空所有数据,请否继续?")) return;
_databaseService.ClearData();
await _databaseService.SaveData();
}
[RelayCommand]
public async Task ExportData()
{
string? path = await _dialogService.SaveFileAsync(".json", "data");
if (string.IsNullOrWhiteSpace(path)) return;
await _databaseService.ExportData(path);
}
[RelayCommand]
public async Task ImportData()
{
string? path = await _dialogService.GetFileAsync([".json"]);
if (string.IsNullOrWhiteSpace(path)) return;
_databaseService.ImportData(path);
await _databaseService.SaveData();
}
}
}

View File

@@ -15,7 +15,6 @@
xmlns:models="using:CRSim.Models"
xmlns:coremodels="using:CRSim.Core.Models"
xmlns:pluginmodels="using:CRSim.Core.Models.Plugin"
Loaded="Page_Loaded"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewmodels:ScreenSimulatorPageViewModel}">
<Page.Resources>
@@ -44,7 +43,7 @@
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{x:Bind ViewModel.SelectedStyle.Manifest.Name,Mode=OneWay}" />
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{x:Bind ViewModel.SelectedStyle.Manifest.Version, Mode=OneWay}"
Opacity="0.7" VerticalAlignment="Bottom" Margin="4,0,0,0"/>
Foreground="{ThemeResource TextFillColorSecondaryBrush}" VerticalAlignment="Bottom" Margin="4,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="作者:" />
@@ -53,7 +52,7 @@
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{x:Bind ViewModel.SelectedStyle.Manifest.Description,Mode=OneWay}"/>
</StackPanel>
</Grid>
<TextBlock Text="主题列表" Style="{StaticResource BodyStrongTextBlockStyle}" Margin="0,0,0,12"/>
<TextBlock Text="主题列表" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<Border Background="{StaticResource CardBackgroundFillColorDefaultBrush}" CornerRadius="8" BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
BorderThickness="1" Margin="0,0,0,24">
<ScrollViewer MaxHeight="400">
@@ -96,12 +95,12 @@
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
<TextBlock Text="当前没有安装任何主题" Margin="0,50" TextAlignment="Center" Opacity="0.7"
<TextBlock Text="当前没有安装任何主题" Margin="0,50" TextAlignment="Center" Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Visibility="{x:Bind ViewModel.StyleInfos.Count,Converter={StaticResource IntToVisibilityConverter},ConverterParameter=true}"/>
</StackPanel>
</ScrollViewer>
</Border>
<TextBlock Text="参数配置" Style="{StaticResource BodyStrongTextBlockStyle}" Margin="0,0,0,12"/>
<TextBlock Text="参数配置" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<StackPanel Spacing="4" Orientation="Vertical" Margin="0,0,0,24">
<controls:SettingsCard Header="车站" Description="使用的车站数据库" HeaderIcon="{winui:FontIcon Glyph=&#xEC08;}"
Visibility="{x:Bind ViewModel.StationNeeded,Converter={StaticResource BoolToVisibilityConverter},Mode=OneWay}">
@@ -152,7 +151,7 @@
<TextBox Text="{x:Bind ViewModel.Text,Mode=TwoWay}" MaxWidth="120"/>
</controls:SettingsCard>
</StackPanel>
<TextBlock Text="参数配置" Style="{StaticResource BodyStrongTextBlockStyle}" Margin="0,0,0,12"/>
<TextBlock Text="参数配置" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<controls:SettingsCard Header="开始模拟" Description="启动一个新的模拟窗口" HeaderIcon="{winui:FontIcon Glyph=&#xE768;}"
IsEnabled="{x:Bind ViewModel.IsStartSimulationAvailable,Mode=OneWay}">
<Button Content="开始模拟" Command="{x:Bind ViewModel.StartSimulationCommand}" Style="{StaticResource AccentButtonStyle}"/>

View File

@@ -9,9 +9,4 @@ public sealed partial class ScreenSimulatorPage : Page
InitializeComponent();
DataContext = ViewModel;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var dialogService = App.AppHost.Services.GetService<IDialogService>()!;
(dialogService as DialogService)?.SetXamlRoot(XamlRoot);
}
}

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="CRSim.Views.SettingsPage"
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:converters="using:CRSim.Converters"
xmlns:converters1="using:CommunityToolkit.WinUI.Converters"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:winui="using:CommunityToolkit.WinUI"
xmlns:viewmodels="using:CRSim.ViewModels"
xmlns:models="using:CRSim.Models"
xmlns:coremodels="using:CRSim.Core.Models"
xmlns:pluginmodels="using:CRSim.Core.Models.Plugin"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewmodels:SettingsPageViewModel}">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="Unloaded">
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.UnloadCommand}" />
</interactivity:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
<Page.Resources>
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<converters:IntToVisibilityConverter x:Key="IntToVisibilityConverter" />
<converters1:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</Page.Resources>
<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,Mode=OneWay}" 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"/>
<StackPanel Spacing="4" Margin="0,0,0,24">
<controls:SettingsCard Header="密钥" Description="用于解锁特定功能" HeaderIcon="{winui:FontIcon Glyph=&#xE8D7;}">
<TextBox Width="168" Text="{x:Bind ViewModel.UserKey, Mode=TwoWay}"/>
</controls:SettingsCard>
</StackPanel>
<TextBlock Text="引导屏模拟" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<StackPanel Spacing="4" Margin="0,0,0,24">
<controls:SettingsCard Header="时间偏移" Description="正值为推后时间,负值为提前时间,单位为分钟" HeaderIcon="{winui:FontIcon Glyph=&#xE823;}">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.TimeOffset, Mode=TwoWay}"/>
</controls:SettingsCard>
<controls:SettingsCard Header="只加载当日车次" Description="不显示明日车次" HeaderIcon="{winui:FontIcon Glyph=&#xEC92;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LoadTodayOnly, Mode=TwoWay}"/>
</controls:SettingsCard>
<controls:SettingsCard Header="屏幕记忆" Description="启动时恢复未关闭的屏幕" HeaderIcon="{winui:FontIcon Glyph=&#xE7A7;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.ReopenUnclosedScreensOnLoad, Mode=TwoWay}"/>
</controls:SettingsCard>
<controls:SettingsCard Header="最大显示页数" Description="翻页屏最大页数" HeaderIcon="{winui:FontIcon Glyph=&#xF57E;}">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.MaxPages, Mode=TwoWay}"/>
</controls:SettingsCard>
<controls:SettingsCard Header="页面切换时长" Description="翻页屏每页停留时长" HeaderIcon="{winui:FontIcon Glyph=&#xE769;}">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.SwitchPageSeconds, Mode=TwoWay}"/>
</controls:SettingsCard>
<controls:SettingsExpander Header="检票" Description="设置检票时长、停检时间等,单位为分钟" HeaderIcon="{winui:FontIcon Glyph=&#xF161;}">
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="始发车提前检票时长">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.DepartureCheckInAdvanceDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Header="过路车提前检票时长">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.PassingCheckInAdvanceDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Header="提前停止检票时长">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.StopCheckInAdvanceDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Header="显示停检至开点前时长">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.StopDisplayUntilDepartureDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Header="终到车显示至到达后时长">
<TextBox MaxWidth="72" Text="{x:Bind ViewModel.StopDisplayFromArrivalDuration, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</StackPanel>
<TextBlock Text="备份与恢复" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<StackPanel Spacing="4" Margin="0,0,0,24">
<controls:SettingsCard Header="导入数据文件" Description="从本地文件加载数据" HeaderIcon="{winui:FontIcon Glyph=&#xE8B6;}">
<Button Command="{x:Bind ViewModel.ImportDataCommand}" Content="导入数据" />
</controls:SettingsCard>
<controls:SettingsCard Header="导出数据文件" Description="保存数据到本地文件" HeaderIcon="{winui:FontIcon Glyph=&#xEDE1;}">
<Button Command="{x:Bind ViewModel.ExportDataCommand}" Content="导出数据" />
</controls:SettingsCard>
<controls:SettingsCard Header="清除所有数据" Description="恢复到安装后状态" HeaderIcon="{winui:FontIcon Glyph=&#xE74D;}">
<Button Command="{x:Bind ViewModel.ClearDataCommand}" Content="清除数据" />
</controls:SettingsCard>
</StackPanel>
<TextBlock Text="关于" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<controls:SettingsExpander Header="CRSim - 国铁信息显示模拟" Description="© 电排骨 2025" HeaderIcon="{winui:BitmapIcon Source=/Assets/CRSimIcon.ico}">
<TextBlock IsTextSelectionEnabled="True" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.AppVersion,Mode=OneWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="克隆项目仓库">
<TextBlock FontFamily="Consolas" Foreground="{ThemeResource TextFillColorSecondaryBrush}" IsTextSelectionEnabled="True"
Text="git clone https://github.com/denglihong2007/CRSim.git" />
</controls:SettingsCard>
<controls:SettingsCard Header="报告漏洞或请求新样式" ActionIcon="{winui:FontIcon Glyph=&#xE8A7;}" Click="Open_Issues" IsClickEnabled="True"/>
<controls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Vertical" Header="项目引用">
<StackPanel Margin="-12,0,0,0" Orientation="Vertical">
<HyperlinkButton Content="WinUI 3" NavigateUri="https://aka.ms/winui" />
<HyperlinkButton Content="Windows Community Toolkit" NavigateUri="https://aka.ms/toolkit/windows" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Vertical" Header="贡献者">
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="wxl0430" NavigateUri="https://github.com/wxl0430" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Vertical" Header="捐赠者">
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="车迷小黄" NavigateUri="https://afdian.com/u/5d5d090a006811f0b49052540025c377" />
</StackPanel>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

View File

@@ -0,0 +1,18 @@
using System.Diagnostics;
namespace CRSim.Views;
public sealed partial class SettingsPage : Page
{
public SettingsPageViewModel ViewModel { get; } = App.AppHost.Services.GetService<SettingsPageViewModel>();
public SettingsPage()
{
InitializeComponent();
DataContext = ViewModel;
}
private void Open_Issues(object sender, RoutedEventArgs e)
{
Process.Start(new ProcessStartInfo("https://github.com/denglihong2007/CRSim/issues/new") { UseShellExecute = true });
}
}

View File

@@ -72,7 +72,7 @@
<FontIcon Glyph="{x:Bind IconGlyph,Mode=OneWay}" FontSize="20" Margin="0,0,12,0"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{x:Bind Title,Mode=OneWay}" Style="{StaticResource BodyStrongTextBlockStyle}" Margin="0,0,0,4"/>
<TextBlock Text="{x:Bind Detail,Mode=OneWay}" Style="{StaticResource CaptionTextBlockStyle}" Opacity="0.7"/>
<TextBlock Text="{x:Bind Detail,Mode=OneWay}" Style="{StaticResource CaptionTextBlockStyle}" Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
@@ -197,16 +197,16 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="车次" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="1" Text="长度" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="2" Text="到时" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="3" Text="发时" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="4" Text="候车区" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="5" Text="检票口" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="6" Text="站台" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="7" Text="地标" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="8" Text="始发站" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="9" Text="终到站" Opacity="0.7" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="0" Text="车次" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="1" Text="长度" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="2" Text="到时" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="3" Text="发时" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="4" Text="候车区" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="5" Text="检票口" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="6" Text="站台" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="7" Text="地标" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="8" Text="始发站" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
<TextBlock Grid.Column="9" Text="终到站" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}" />
</Grid>
</ListView.Header>
<ListView.ItemTemplate>