mirror of
https://github.com/denglihong2007/CRSim
synced 2026-08-04 16:26:24 +08:00
删除残余文件
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,459 +0,0 @@
|
||||
[
|
||||
{
|
||||
"UniqueId": "ChengduDong.SecondaryScreen",
|
||||
"Title": "成都东站次要看板",
|
||||
"Region": "成都",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "ChengduDong.PrimaryTicketCheckScreen",
|
||||
"Title": "成都东站检票口主要看板",
|
||||
"Region": "成都",
|
||||
"Author": "电排骨",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "ChengduDong.PillarTicketCheckScreen",
|
||||
"Title": "成都东站检票口立柱看板",
|
||||
"Region": "成都",
|
||||
"Author": "电排骨",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Fuzhou.TicketCheckScreen",
|
||||
"Title": "福州站检票口看板",
|
||||
"Region": "福州",
|
||||
"Author": "电排骨",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "FuzhouNan.TicketCheckScreen",
|
||||
"Title": "福州南站检票口看板",
|
||||
"Region": "福州",
|
||||
"Author": "电排骨",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "BeijingXi.PrimaryScreen",
|
||||
"Title": "北京西站主要看板",
|
||||
"Region": "北京",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Harbin.PrimaryScreen",
|
||||
"Title": "哈尔滨站主要看板",
|
||||
"Region": "哈尔滨",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "ChengduMetro.PlatformScreen",
|
||||
"Title": "成都地铁站台看板",
|
||||
"Region": "成都",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text",
|
||||
"Video",
|
||||
"Platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "XuzhouMetro.PlatformScreen",
|
||||
"Title": "徐州地铁站台看板",
|
||||
"Region": "徐州",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text",
|
||||
"Video",
|
||||
"Platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "TianjinMetro.PlatformScreen",
|
||||
"Title": "天津地铁站台看板",
|
||||
"Region": "天津",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text",
|
||||
"Video",
|
||||
"Platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Guangyuan.PrimaryScreen",
|
||||
"Title": "广元站主要看板",
|
||||
"Region": "广元",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "ChengduShuangliuAirport.SecondaryScreen",
|
||||
"Title": "成都双流机场次要看板",
|
||||
"Region": "成都",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "KunmingChangshuiAirport.PrimaryScreen",
|
||||
"Title": "昆明长水机场主要看板",
|
||||
"Region": "昆明",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Shanghai.OutsideScreen",
|
||||
"Title": "上海站站外看板",
|
||||
"Region": "上海",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Hanzhong.PlatformScreen",
|
||||
"Title": "汉中站站台看板",
|
||||
"Region": "汉中",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Tianjin.PlatformScreen",
|
||||
"Title": "天津站站台看板",
|
||||
"Region": "天津",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Mianyang.PlatformScreen",
|
||||
"Title": "绵阳站站台看板",
|
||||
"Region": "绵阳",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Zibo.PrimaryScreen",
|
||||
"Title": "淄博站主要看板",
|
||||
"Region": "淄博",
|
||||
"Author": "wxl0430",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Zibo.SecondaryScreen",
|
||||
"Title": "淄博站次要看板",
|
||||
"Region": "淄博",
|
||||
"Author": "wxl0430",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Zibo.TicketCheckScreen",
|
||||
"Title": "淄博站检票口看板",
|
||||
"Region": "淄博",
|
||||
"Author": "wxl0430",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Zibo.PlatformScreen",
|
||||
"Title": "淄博站站台看板",
|
||||
"Region": "淄博",
|
||||
"Author": "wxl0430",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Zibo.ConcourseBridgeScreen",
|
||||
"Title": "淄博站廊桥看板",
|
||||
"Region": "淄博",
|
||||
"Author": "wxl0430",
|
||||
"Type": "走廊出发屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Zibo.ExitScreen",
|
||||
"Title": "淄博站出站口看板",
|
||||
"Region": "淄博",
|
||||
"Author": "wxl0430",
|
||||
"Type": "出站口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Jinanxi.SmallScreen",
|
||||
"Title": "济南西站小屏看板",
|
||||
"Region": "济南",
|
||||
"Author": "wxl0430",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "GuangdongIntercity.SecondaryScreen",
|
||||
"Title": "广东城际次要看板",
|
||||
"Region": "广东",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Ankang.ExitScreen",
|
||||
"Title": "安康站出站口看板",
|
||||
"Region": "安康",
|
||||
"Author": "电排骨",
|
||||
"Type": "出站口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Niuzhou.PrimaryScreen",
|
||||
"Title": "柳州站主要看板",
|
||||
"Region": "柳州",
|
||||
"Author": "电排骨",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Beijing.ArrivalScreen",
|
||||
"Title": "北京站地道到达看板",
|
||||
"Region": "北京",
|
||||
"Author": "wxl0430",
|
||||
"Type": "走廊到达屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "DaqingDong.ConcourseBridgeScreen",
|
||||
"Title": "大庆东站廊桥看板",
|
||||
"Region": "大庆",
|
||||
"Author": "wxl0430",
|
||||
"Type": "走廊出发屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "DaqingDong.PlatformScreen",
|
||||
"Title": "大庆东站站台看板",
|
||||
"Region": "大庆",
|
||||
"Author": "wxl0430",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "HarbinXi.PlatformScreen",
|
||||
"Title": "哈尔滨西站站台看板",
|
||||
"Region": "哈尔滨",
|
||||
"Author": "wxl0430",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "BeijingNan.PrimaryScreen",
|
||||
"Title": "北京南站主要看板",
|
||||
"Region": "北京",
|
||||
"Author": "wxl0430",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "BeijingNan.TicketCheckScreen",
|
||||
"Title": "北京南站检票口看板",
|
||||
"Region": "北京",
|
||||
"Author": "wxl0430",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "BeijingNan.PrimaryPlatformScreen",
|
||||
"Title": "北京南站站台主要看板",
|
||||
"Region": "北京",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "BeijingNan.SecondaryPlatformScreen",
|
||||
"Title": "北京南站站台次要看板",
|
||||
"Region": "北京",
|
||||
"Author": "wxl0430",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "ShenyangBei.PlatformScreen",
|
||||
"Title": "沈阳北站站台看板",
|
||||
"Region": "沈阳",
|
||||
"Author": "电排骨",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "DezhouDong.PrimaryScreen",
|
||||
"Title": "德州东站主要看板",
|
||||
"Region": "德州",
|
||||
"Author": "wxl0430",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "DezhouDong.TicketCheckScreen",
|
||||
"Title": "德州东站检票口看板",
|
||||
"Region": "德州",
|
||||
"Author": "wxl0430",
|
||||
"Type": "检票口屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"TicketCheck"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Yakeshi.PlatformScreen",
|
||||
"Title": "牙克石站站台看板",
|
||||
"Region": "牙克石",
|
||||
"Author": "wxl0430",
|
||||
"Type": "站台屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Platform",
|
||||
"Location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"UniqueId": "Hailaer.PrimaryScreen",
|
||||
"Title": "海拉尔站主要看板",
|
||||
"Region": "海拉尔",
|
||||
"Author": "wxl0430",
|
||||
"Type": "车站大屏",
|
||||
"Parameters": [
|
||||
"Station",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,16 +0,0 @@
|
||||
using CRSim.Core.Models;
|
||||
using CRSim.Core.Services;
|
||||
namespace CRSim.ScreenSimulator.ViewModels.Hailaer
|
||||
{
|
||||
public class PrimaryScreenViewModel : ScreenViewModel
|
||||
{
|
||||
public PrimaryScreenViewModel(ITimeService timeService, ISettingsService settingsService)
|
||||
: base(timeService, settingsService)
|
||||
{
|
||||
ItemsPerPage = 6;
|
||||
ScreenCount = 2;
|
||||
Text = $" 开车前{settingsService.GetSettings().StopCheckInAdvanceDuration.TotalMinutes}分钟停止检票";;
|
||||
StationType = StationType.Departure;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using CRSim.Core.Services;
|
||||
namespace CRSim.ScreenSimulator.ViewModels.Yakeshi
|
||||
{
|
||||
public class PlatformScreenViewModel : ScreenViewModel
|
||||
{
|
||||
public PlatformScreenViewModel(ITimeService timeService, ISettingsService settingsService)
|
||||
: base(timeService, settingsService)
|
||||
{
|
||||
Text = $"上下车不要拥挤,小心列车与站台之间的缝隙,看管好老人和同行的儿童";
|
||||
ItemsPerPage = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,300 +0,0 @@
|
||||
<views:BaseScreenView x:Class="CRSim.ScreenSimulator.Views.Hailaer.PrimaryScreenView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:CRSim.ScreenSimulator.Views.Hailaer"
|
||||
mc:Ignorable="d" Background="#434446"
|
||||
xmlns:views="clr-namespace:CRSim.ScreenSimulator.Views"
|
||||
xmlns:converters="clr-namespace:CRSim.ScreenSimulator.Converters"
|
||||
xmlns:converters1="clr-namespace:CRSim.Shared.Converters;assembly=CRSim.Shared">
|
||||
<views:BaseScreenView.Resources>
|
||||
<converters1:ListToStringConverter x:Key="ListToStringConverter" Separator="" />
|
||||
<converters1:EmptyToVisibilityConverter x:Key="EmptyToVisibilityConverter" />
|
||||
<converters1:DateTimeToStringConverter x:Key="DateTimeToStringConverter" Format="HH:mm" />
|
||||
<converters1:DateTimeToStringConverter x:Key="DateTimeToStringTimeConverter" Format="yyyy/M/d HH:mm:ss" />
|
||||
<converters:TrainStateConverter x:Key="TrainStateConverter" WaitingText="正在候车"/>
|
||||
<converters:TrainStateColorConverter x:Key="TrainStateColorConverter" WaitingColor="#f9fdd8"/>
|
||||
<converters:LandmarkToStringConverter x:Key="LandmarkToStringConverter"/>
|
||||
<converters:NumberToStringConverter x:Key="NumberToStringConverter"/>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
</Style>
|
||||
<Style x:Key="CommonTextBlockStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#f9fdd8"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style x:Key="CommonRowStyle" TargetType="DataGridRow">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=AlternationIndex}" Value="0">
|
||||
<Setter Property="Background" Value="#434446"/>
|
||||
<Setter Property="Foreground" Value="#f9fdd8"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="CommonHeaderStyle" TargetType="TextBlock">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<SolidColorBrush Color="#434446"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Foreground">
|
||||
<Setter.Value>
|
||||
<SolidColorBrush Color="#f2203a"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="FontSize" Value="17"/>
|
||||
</Style>
|
||||
</views:BaseScreenView.Resources>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<views:BaseDataGrid ItemsSource="{Binding ScreenA}" FontFamily="DengXian"
|
||||
RowHeight="28" RowStyle="{StaticResource CommonRowStyle}" FontWeight="SemiBold" AlternationCount="1">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding TrainNumber}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="车次" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding Origin}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="始发站" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Terminal}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="终到站" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding ArrivalTime, Converter={StaticResource DateTimeToStringConverter}}" MinWidth="45">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="到点" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}">
|
||||
<Setter Property="Visibility" Value="{Binding TrainNumber,Converter={StaticResource EmptyToVisibilityConverter}}"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding DepartureTime, Converter={StaticResource DateTimeToStringConverter}}" MinWidth="45">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="开点" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}">
|
||||
<Setter Property="Visibility" Value="{Binding TrainNumber,Converter={StaticResource EmptyToVisibilityConverter}}"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding WaitingArea}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="候车室" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn MinWidth="60">
|
||||
<DataGridTextColumn.Binding>
|
||||
<MultiBinding Mode="OneWay" Converter="{StaticResource TrainStateConverter}">
|
||||
<Binding Path="ArrivalTime" />
|
||||
<Binding Path="DepartureTime" />
|
||||
<Binding Path="State" />
|
||||
</MultiBinding>
|
||||
</DataGridTextColumn.Binding>
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="状态" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}">
|
||||
<Setter Property="Foreground">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource TrainStateColorConverter}">
|
||||
<Binding Path="ArrivalTime" />
|
||||
<Binding Path="DepartureTime" />
|
||||
<Binding Path="State" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</views:BaseDataGrid>
|
||||
|
||||
<views:BaseDataGrid ItemsSource="{Binding ScreenB}" FontFamily="DengXian"
|
||||
RowHeight="28" RowStyle="{StaticResource CommonRowStyle}" FontWeight="SemiBold" AlternationCount="1" Margin="10,0,0,0">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding TrainNumber}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="车次" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding Origin}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="始发站" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Terminal}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="终到站" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding ArrivalTime, Converter={StaticResource DateTimeToStringConverter}}" MinWidth="45">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="到点" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}">
|
||||
<Setter Property="Visibility" Value="{Binding TrainNumber,Converter={StaticResource EmptyToVisibilityConverter}}"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding DepartureTime, Converter={StaticResource DateTimeToStringConverter}}" MinWidth="45">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="开点" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}">
|
||||
<Setter Property="Visibility" Value="{Binding TrainNumber,Converter={StaticResource EmptyToVisibilityConverter}}"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Binding="{Binding WaitingArea}" MinWidth="50">
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="候车室" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}"/>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn MinWidth="60">
|
||||
<DataGridTextColumn.Binding>
|
||||
<MultiBinding Mode="OneWay" Converter="{StaticResource TrainStateConverter}">
|
||||
<Binding Path="ArrivalTime" />
|
||||
<Binding Path="DepartureTime" />
|
||||
<Binding Path="State" />
|
||||
</MultiBinding>
|
||||
</DataGridTextColumn.Binding>
|
||||
<DataGridTextColumn.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=ActualWidth}">
|
||||
<TextBlock Text="状态" Style="{StaticResource CommonHeaderStyle}" Padding="0,6,0,0" Height="30"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTextColumn.HeaderTemplate>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource CommonTextBlockStyle}">
|
||||
<Setter Property="Foreground">
|
||||
<Setter.Value>
|
||||
<MultiBinding Converter="{StaticResource TrainStateColorConverter}">
|
||||
<Binding Path="ArrivalTime" />
|
||||
<Binding Path="DepartureTime" />
|
||||
<Binding Path="State" />
|
||||
</MultiBinding>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</views:BaseDataGrid>
|
||||
</StackPanel>
|
||||
<Grid Background="#434446" HorizontalAlignment="Stretch" Height="25">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding Text}" Foreground="#f2203a" Margin="30,2" FontFamily="微软雅黑" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding CurrentTime,Converter={StaticResource DateTimeToStringTimeConverter}}" Foreground="#f2203a" Margin="30,2" FontFamily="微软雅黑" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</views:BaseScreenView>
|
||||
@@ -1,14 +0,0 @@
|
||||
using CRSim.ScreenSimulator.ViewModels.Hailaer;
|
||||
namespace CRSim.ScreenSimulator.Views.Hailaer
|
||||
{
|
||||
public partial class PrimaryScreenView : BaseScreenView
|
||||
{
|
||||
public PrimaryScreenViewModel ViewModel { get; }
|
||||
public PrimaryScreenView(PrimaryScreenViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = viewModel;
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
<views:BaseScreenView x:Class="CRSim.ScreenSimulator.Views.Yakeshi.PlatformScreenView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:pp="https://www.cnblogs.com/pumbaa"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:CRSim.ScreenSimulator.Views.Yakeshi"
|
||||
mc:Ignorable="d"
|
||||
xmlns:converters="clr-namespace:CRSim.ScreenSimulator.Converters"
|
||||
xmlns:converters1="clr-namespace:CRSim.Shared.Converters;assembly=CRSim.Shared"
|
||||
FontFamily="黑体" FontSize="28" FontWeight="Bold" Background="#000000"
|
||||
xmlns:views="clr-namespace:CRSim.ScreenSimulator.Views">
|
||||
<Window.Resources>
|
||||
<converters1:DateTimeToStringConverter x:Key="DateTimeToStringConverter" Format="HH:mm" />
|
||||
<converters:LocationToStringConverter x:Key="LocationToStringConverter" DisplayMode="least" HyphenText="-" />
|
||||
<converters1:EmptyToVisibilityConverter x:Key="EmptyToVisibilityConverter" />
|
||||
</Window.Resources>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Grid Background="#000000" MinWidth="600">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Margin="0,3,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ScreenA[0].TrainNumber}" Foreground="#d23139" Margin="15,0,0,0" FontSize="26"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding ScreenA[0].Origin}" Foreground="#d23139" FontSize="26" Margin="30,0,0,0"/>
|
||||
<TextBlock Grid.Column="3" Text="—" Foreground="#d23139" FontSize="26"/>
|
||||
<TextBlock Grid.Column="4" Text="{Binding ScreenA[0].Terminal}" Foreground="#d23139" FontSize="26"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Margin="0,3,0,3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ScreenA[0].DepartureTime,Converter={StaticResource DateTimeToStringConverter}}" Foreground="#d23139" FontSize="26"/>
|
||||
<TextBlock Grid.Column="2" Text="开" Foreground="#d23139" FontSize="26"/>
|
||||
<TextBlock Grid.Column="3" Text="{Binding ThisPlatform}" Foreground="#d23139" FontSize="26" Margin="30,0,0,0"/>
|
||||
<TextBlock Grid.Column="4" Text="站台" Foreground="#d23139" FontSize="26" Margin="0,0,5,0"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="1" TextAlignment="Center" Foreground="#d23139" FontSize="26">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Mode="OneWay" Converter="{StaticResource LocationToStringConverter}">
|
||||
<Binding Path="ScreenA[0].Length" />
|
||||
<Binding Path="Location" />
|
||||
<Binding Source="left" />
|
||||
<Binding Source="closed" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
<TextBlock Grid.Column="2" TextAlignment="Center" Foreground="#d23139" FontSize="26" Text="车"/>
|
||||
<TextBlock Grid.Column="4" TextAlignment="Center" Foreground="#d23139" FontSize="26">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Mode="OneWay" Converter="{StaticResource LocationToStringConverter}">
|
||||
<Binding Path="ScreenA[0].Length" />
|
||||
<Binding Path="Location" />
|
||||
<Binding Source="right" />
|
||||
<Binding Source="noclosed" />
|
||||
<Binding Source="车" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<pp:RunningText Grid.Row="3" Speed="20" Foreground="#d23139" Text="{Binding Text}" FontSize="26" FontWeight="Normal"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</views:BaseScreenView>
|
||||
@@ -1,16 +0,0 @@
|
||||
using CRSim.ScreenSimulator.ViewModels.Yakeshi;
|
||||
|
||||
namespace CRSim.ScreenSimulator.Views.Yakeshi
|
||||
{
|
||||
public partial class PlatformScreenView : BaseScreenView
|
||||
{
|
||||
public PlatformScreenViewModel ViewModel { get; }
|
||||
public PlatformScreenView(PlatformScreenViewModel viewModel)
|
||||
{
|
||||
|
||||
InitializeComponent();
|
||||
ViewModel = viewModel;
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,9 @@
|
||||
<Content Update="Assets\CRSimIcon.ico">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\CRSimIcon.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\HomeHeaderTiles\GalleryHeaderImage.jpg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -1,373 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CRSim
|
||||
{
|
||||
public class UpdateChecker
|
||||
{
|
||||
private const string ApiUrl = "https://crsim.com.cn/api/version";
|
||||
private readonly HttpClient _httpClient = new HttpClient();
|
||||
private ProgressWindow _progressWindow;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
public async Task CheckForUpdates()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ExecuteOnUIThread(async () =>
|
||||
{
|
||||
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
var latestVersionInfo = await GetLatestVersionInfo();
|
||||
|
||||
if (latestVersionInfo != null && latestVersionInfo.ver != currentVersion)
|
||||
{
|
||||
var result = ShowQuestion($"有新版本可用,当前版本:{currentVersion}\n最新版本: {latestVersionInfo.ver}\n\n更新日志:\n{latestVersionInfo.log}\n\n是否更新?(点击更新后请等待,程序将自动重启,时间与下载速度有关)");
|
||||
|
||||
if (result)
|
||||
{
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
ShowProgressWindow("准备下载更新...");
|
||||
|
||||
try
|
||||
{
|
||||
await DownloadAndInitiateUpdate(latestVersionInfo, _cancellationTokenSource.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
ShowMessage("更新已取消");
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseProgressWindow();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CloseProgressWindow();
|
||||
ShowError($"更新检查失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<VersionInfo> GetLatestVersionInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.GetAsync(ApiUrl);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<VersionInfo>(json);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowError($"调用API失败: {ex.Message}");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task DownloadAndInitiateUpdate(VersionInfo versionInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tempFilePath = await DownloadFileWithProgress(versionInfo.download_file, cancellationToken);
|
||||
|
||||
var isValid = await Task.Run(() => ValidateFile(tempFilePath, versionInfo.file_md5, versionInfo.file_sha256));
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
var forceUpdate = ShowQuestion("md5和sha256验证失败,可能遭到网络劫持,是否强制更新?");
|
||||
if (!forceUpdate)
|
||||
{
|
||||
File.Delete(tempFilePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var programDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
var appExePath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var appName = Path.GetFileName(appExePath);
|
||||
string batchScript = $@"
|
||||
@echo off
|
||||
taskkill /F /IM ""{appName}"" >nul 2>&1
|
||||
timeout /t 2 >nul
|
||||
cd /d ""{programDirectory}""
|
||||
powershell -Command ""Expand-Archive -Path '{tempFilePath}' -DestinationPath '{programDirectory}' -Force""
|
||||
del /f /q ""{tempFilePath}""
|
||||
start """" ""{appExePath}""
|
||||
exit /b 0
|
||||
";
|
||||
|
||||
string batchFilePath = Path.Combine(Path.GetTempPath(), "CRSimUpdate.bat");
|
||||
File.WriteAllText(batchFilePath, batchScript);
|
||||
|
||||
try
|
||||
{
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/c \"{batchFilePath}\"",
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
Process.Start(processInfo);
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowError($"启动更新脚本进程失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowError($"更新失败: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> DownloadFileWithProgress(string downloadUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
var tempFile = Path.GetTempFileName() + ".zip";
|
||||
|
||||
try
|
||||
{
|
||||
using var response = await _httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var contentLength = response.Content.Headers.ContentLength;
|
||||
UpdateProgress("开始下载更新文件...", 0);
|
||||
|
||||
using var stream = await response.Content.ReadAsStreamAsync(cancellationToken);
|
||||
using var fileStream = new FileStream(tempFile, FileMode.Create);
|
||||
|
||||
var buffer = new byte[8192];
|
||||
var totalBytesRead = 0L;
|
||||
var lastUpdateBytes = 0L;
|
||||
var updateIntervalBytes = contentLength.HasValue ? Math.Max(1024 * 1024, contentLength.Value / 100) : 1024 * 1024;
|
||||
int bytesRead;
|
||||
|
||||
UpdateProgress($"准备下载: {GetSizeString(contentLength ?? 0)}", 0);
|
||||
|
||||
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
|
||||
{
|
||||
await fileStream.WriteAsync(buffer, 0, bytesRead, cancellationToken);
|
||||
totalBytesRead += bytesRead;
|
||||
|
||||
if (totalBytesRead - lastUpdateBytes >= updateIntervalBytes || totalBytesRead == contentLength)
|
||||
{
|
||||
if (contentLength.HasValue)
|
||||
{
|
||||
var progressPercentage = (int)((totalBytesRead * 100) / contentLength.Value);
|
||||
UpdateProgress($"下载中: {progressPercentage}%", progressPercentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateProgress($"下载中: {GetSizeString(totalBytesRead)}", 0);
|
||||
}
|
||||
|
||||
lastUpdateBytes = totalBytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateProgress("下载完成,准备更新...", 100);
|
||||
return tempFile;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (File.Exists(tempFile))
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (File.Exists(tempFile))
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
|
||||
ShowError($"下载文件失败: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetSizeString(long bytes)
|
||||
{
|
||||
if (bytes < 1024) return $"{bytes} B";
|
||||
if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB";
|
||||
return $"{bytes / (1024.0 * 1024):F1} MB";
|
||||
}
|
||||
|
||||
private bool ValidateFile(string filePath, string expectedMd5, string expectedSha256)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var md5 = MD5.Create();
|
||||
using var sha256 = SHA256.Create();
|
||||
using var stream = File.OpenRead(filePath);
|
||||
|
||||
var actualMd5 = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
|
||||
stream.Position = 0;
|
||||
var actualSha256 = BitConverter.ToString(sha256.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
|
||||
|
||||
return actualMd5 == expectedMd5 && actualSha256 == expectedSha256;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowProgressWindow(string message)
|
||||
{
|
||||
ExecuteOnUIThread(() =>
|
||||
{
|
||||
_progressWindow = new ProgressWindow { Owner = Application.Current.MainWindow };
|
||||
_progressWindow.UpdateStatus(message);
|
||||
_progressWindow.Show();
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateProgress(string message, int progress)
|
||||
{
|
||||
ExecuteOnUIThread(() =>
|
||||
{
|
||||
if (_progressWindow != null && _progressWindow.IsVisible)
|
||||
{
|
||||
_progressWindow.UpdateStatus(message);
|
||||
_progressWindow.UpdateProgress(progress);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void CloseProgressWindow()
|
||||
{
|
||||
ExecuteOnUIThread(() =>
|
||||
{
|
||||
_progressWindow?.Close();
|
||||
_progressWindow = null;
|
||||
});
|
||||
}
|
||||
|
||||
private Task ExecuteOnUIThread(Action action)
|
||||
{
|
||||
if (Application.Current == null)
|
||||
{
|
||||
action();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
action();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Application.Current.Dispatcher.InvokeAsync(action).Task;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowMessage(string message)
|
||||
{
|
||||
ExecuteOnUIThread(() =>
|
||||
{
|
||||
MessageBox.Show(message, "CRSim", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowError(string message)
|
||||
{
|
||||
ExecuteOnUIThread(() =>
|
||||
{
|
||||
MessageBox.Show(message, "CRSim - Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
});
|
||||
}
|
||||
|
||||
private bool ShowQuestion(string message)
|
||||
{
|
||||
var result = false;
|
||||
|
||||
ExecuteOnUIThread(() =>
|
||||
{
|
||||
result = MessageBox.Show(message, "CRSim", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes;
|
||||
}).Wait();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProgressWindow : Window
|
||||
{
|
||||
private readonly TextBlock _statusText;
|
||||
private readonly ProgressBar _progressBar;
|
||||
|
||||
public ProgressWindow()
|
||||
{
|
||||
Title = "更新进度";
|
||||
Width = 400;
|
||||
Height = 150;
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
ResizeMode = ResizeMode.NoResize;
|
||||
ShowInTaskbar = false;
|
||||
|
||||
var stackPanel = new StackPanel { Margin = new Thickness(10) };
|
||||
|
||||
_statusText = new TextBlock
|
||||
{
|
||||
Text = "准备中...",
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Margin = new Thickness(0, 10, 0, 20)
|
||||
};
|
||||
|
||||
_progressBar = new ProgressBar
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 100,
|
||||
Value = 0,
|
||||
Height = 20
|
||||
};
|
||||
|
||||
stackPanel.Children.Add(_statusText);
|
||||
stackPanel.Children.Add(_progressBar);
|
||||
|
||||
Content = stackPanel;
|
||||
}
|
||||
|
||||
public void UpdateStatus(string message)
|
||||
{
|
||||
_statusText.Text = message;
|
||||
}
|
||||
|
||||
public void UpdateProgress(int value)
|
||||
{
|
||||
_progressBar.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class VersionInfo
|
||||
{
|
||||
public string status_code { get; set; }
|
||||
public string message { get; set; }
|
||||
public string ver { get; set; }
|
||||
public string download_file { get; set; }
|
||||
public string file_md5 { get; set; }
|
||||
public string file_sha256 { get; set; }
|
||||
public string log { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,273 +0,0 @@
|
||||
using CRSim.Core.Models;
|
||||
|
||||
namespace CRSim.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// UserInputDialog.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class TrainStopDialog : Window
|
||||
{
|
||||
public class ticketCheck
|
||||
{
|
||||
public string TicketCheck { get; set; }
|
||||
public bool Checked { get; set; } = false;
|
||||
}
|
||||
|
||||
public ObservableCollection<string> Landmarks { get; set; } = ["无", "红色", "绿色", "褐色", "蓝色", "紫色", "黄色", "橙色"];
|
||||
|
||||
public TrainStop GeneratedTrainStop;
|
||||
|
||||
public ObservableCollection<ticketCheck> TicketChecksList { get; set; } = [];
|
||||
|
||||
public ObservableCollection<string> Platforms { get; set; } = [];
|
||||
|
||||
public TrainStopDialog(List<string> ticketChecks,List<string> platforms)
|
||||
{
|
||||
DataContext = this;
|
||||
WindowChrome.SetWindowChrome(
|
||||
this,
|
||||
new WindowChrome
|
||||
{
|
||||
CaptionHeight = 50,
|
||||
CornerRadius = default,
|
||||
GlassFrameThickness = new Thickness(-1),
|
||||
ResizeBorderThickness = ResizeMode == ResizeMode.NoResize ? default : new Thickness(4),
|
||||
UseAeroCaptionButtons = true
|
||||
}
|
||||
);
|
||||
InitializeComponent();
|
||||
IntermediateStation.IsChecked = true;
|
||||
LengthTextBox.Text = "16";
|
||||
TicketChecksList.Clear();
|
||||
foreach (string s in ticketChecks)
|
||||
{
|
||||
TicketChecksList.Add(new ticketCheck()
|
||||
{
|
||||
TicketCheck = s,
|
||||
Checked = false
|
||||
});
|
||||
}
|
||||
foreach (string s in platforms)
|
||||
{
|
||||
Platforms.Add(s);
|
||||
}
|
||||
ValidateInput();
|
||||
}
|
||||
|
||||
public TrainStopDialog(List<string> ticketChecks, List<string> platforms, TrainStop trainStop)
|
||||
{
|
||||
DataContext = this;
|
||||
WindowChrome.SetWindowChrome(
|
||||
this,
|
||||
new WindowChrome
|
||||
{
|
||||
CaptionHeight = 50,
|
||||
CornerRadius = default,
|
||||
GlassFrameThickness = new Thickness(-1),
|
||||
ResizeBorderThickness = ResizeMode == ResizeMode.NoResize ? default : new Thickness(4),
|
||||
UseAeroCaptionButtons = true
|
||||
}
|
||||
);
|
||||
InitializeComponent();
|
||||
NumberTextBox.IsEnabled = false;
|
||||
NumberTextBox.Text = trainStop.Number;
|
||||
ArrivalTextBox.Text = trainStop.Terminal;
|
||||
DepartureTextBox.Text = trainStop.Origin;
|
||||
LengthTextBox.Text = trainStop.Length.ToString();
|
||||
StationKindPanel.IsEnabled = false;
|
||||
if (trainStop.ArrivalTime != null)
|
||||
{
|
||||
StartHour.Text = trainStop.ArrivalTime.Value.Hours.ToString();
|
||||
StartMinute.Text = trainStop.ArrivalTime.Value.Minutes.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
StartingStation.IsChecked = true;
|
||||
}
|
||||
if (trainStop.DepartureTime != null)
|
||||
{
|
||||
EndHour.Text = trainStop.DepartureTime.Value.Hours.ToString();
|
||||
EndMinute.Text = trainStop.DepartureTime.Value.Minutes.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
FinalStation.IsChecked = true;
|
||||
}
|
||||
if(!StartingStation.IsChecked.Value && !FinalStation.IsChecked.Value)
|
||||
{
|
||||
IntermediateStation.IsChecked = true;
|
||||
}
|
||||
TicketChecksList.Clear();
|
||||
foreach (string s in ticketChecks)
|
||||
{
|
||||
TicketChecksList.Add(new ticketCheck()
|
||||
{
|
||||
TicketCheck = s,
|
||||
Checked = trainStop.TicketChecks.Contains(s)
|
||||
});
|
||||
}
|
||||
foreach (string s in platforms)
|
||||
{
|
||||
Platforms.Add(s);
|
||||
}
|
||||
PlatformComboBox.SelectedIndex = Platforms.IndexOf(trainStop.Platform);
|
||||
LandmarkComboBox.SelectedIndex = trainStop.Landmark == null ? 0 : Landmarks.IndexOf(trainStop.Landmark);
|
||||
ValidateInput();
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
GeneratedTrainStop = new TrainStop
|
||||
{
|
||||
Number = NumberTextBox.Text,
|
||||
Terminal = ArrivalTextBox.Text,
|
||||
Origin = DepartureTextBox.Text,
|
||||
ArrivalTime = StartHour.IsEnabled ? TimeSpan.Parse($"{StartHour.Text}:{StartMinute.Text}") : null,
|
||||
DepartureTime = EndHour.IsEnabled ? TimeSpan.Parse($"{EndHour.Text}:{EndMinute.Text}") : null,
|
||||
WaitingArea = TicketChecksList.Where(x => x.Checked).FirstOrDefault()?.TicketCheck.Split(" - ")[0] ?? string.Empty,
|
||||
TicketChecks = [.. TicketChecksList.Where(x => x.Checked).Select(x => x.TicketCheck.Split(" - ")[1])],
|
||||
Platform = (string)PlatformComboBox.SelectedItem,
|
||||
Length = int.Parse(LengthTextBox.Text),
|
||||
Landmark = (string)LandmarkComboBox.SelectedItem == "无" ? null : (string)LandmarkComboBox.SelectedItem,
|
||||
};
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void CancelButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void StartHour_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
if (StartHour.Text.Length == 2) StartMinute.Focus();
|
||||
}
|
||||
|
||||
private void StartMinute_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
if (StartMinute.Text.Length == 2) EndHour.Focus();
|
||||
}
|
||||
|
||||
private void EndHour_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
if (EndHour.Text.Length == 2) EndMinute.Focus();
|
||||
}
|
||||
|
||||
private void EndMinute_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
if (EndMinute.Text.Length == 2) AccentButton.Focus();
|
||||
}
|
||||
|
||||
private void CheckBox_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
}
|
||||
|
||||
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
}
|
||||
|
||||
private static bool ValidateTime(string input, int maxValue)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(input) && int.TryParse(input, null, out int time))
|
||||
{
|
||||
return 0 <= time && time < maxValue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ValidateInput()
|
||||
{
|
||||
// 检查四个文本框是否非空
|
||||
bool areTextBoxesFilled =
|
||||
(!StartHour.IsEnabled || ValidateTime(StartHour.Text, 24)) &&
|
||||
(!StartMinute.IsEnabled || ValidateTime(StartMinute.Text, 60)) &&
|
||||
(!EndHour.IsEnabled || ValidateTime(EndHour.Text, 24)) &&
|
||||
(!EndMinute.IsEnabled || ValidateTime(EndMinute.Text, 60));
|
||||
|
||||
AccentButton.IsEnabled =
|
||||
(!TicketChecksCheckList.IsEnabled ||
|
||||
(TicketChecksList.Any(x => x.Checked) && TicketChecksList.Where(x=>x.Checked).Select(x=>x.TicketCheck.Split(" - ")[0]).Distinct().Count() <= 1)) &&
|
||||
areTextBoxesFilled &&
|
||||
!string.IsNullOrWhiteSpace(NumberTextBox.Text) &&
|
||||
!string.IsNullOrWhiteSpace(ArrivalTextBox.Text) &&
|
||||
!string.IsNullOrWhiteSpace(DepartureTextBox.Text) &&
|
||||
int.TryParse(LengthTextBox.Text, out int i) && i > 0 &&
|
||||
PlatformComboBox.SelectedItem != null;
|
||||
}
|
||||
|
||||
private T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
|
||||
{
|
||||
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
|
||||
if (child is T t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
else
|
||||
{
|
||||
T childOfChild = FindVisualChild<T>(child);
|
||||
if (childOfChild != null)
|
||||
return childOfChild;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void StartingStation_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (StartHour == null) return;
|
||||
StartHour.IsEnabled = false;
|
||||
StartMinute.IsEnabled = false;
|
||||
EndHour.IsEnabled = true;
|
||||
EndMinute.IsEnabled = true;
|
||||
TicketChecksCheckList.IsEnabled = true;
|
||||
}
|
||||
|
||||
private void IntermediateStation_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (StartHour == null) return;
|
||||
StartHour.IsEnabled = true;
|
||||
StartMinute.IsEnabled = true;
|
||||
EndHour.IsEnabled = true;
|
||||
EndMinute.IsEnabled = true;
|
||||
TicketChecksCheckList.IsEnabled = true;
|
||||
}
|
||||
|
||||
private void FinalStation_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (StartHour == null) return;
|
||||
StartHour.IsEnabled = true;
|
||||
StartMinute.IsEnabled = true;
|
||||
EndHour.IsEnabled = false;
|
||||
EndMinute.IsEnabled = false;
|
||||
TicketChecksCheckList.IsEnabled = false;
|
||||
}
|
||||
|
||||
private void TicketChecksCheckList_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
|
||||
{
|
||||
RoutedEvent = UIElement.MouseWheelEvent,
|
||||
Source = sender
|
||||
};
|
||||
TicketChecksCheckList.RaiseEvent(eventArg);
|
||||
}
|
||||
|
||||
private void NumberTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
ValidateInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user