Merge pull request #273 from denglihong2007/dev

release: 3.1.1.0 [skip cliff]
This commit is contained in:
denglihong2007
2025-10-18 23:09:37 +08:00
committed by GitHub
17 changed files with 186 additions and 69 deletions

View File

@@ -0,0 +1,9 @@
namespace CRSim.Core.Abstractions
{
public interface IApi
{
string Name { get; }
string BaseApi { get; }
string UpdateApi { get; }
}
}

View File

@@ -0,0 +1,15 @@
namespace CRSim.Core.Abstractions
{
/// <summary>
/// 定义 API 客户端工厂的合约,用于创建 IApi 实例。
/// </summary>
public interface IApiFactory
{
/// <summary>
/// 根据客户端类型名称和基础 URL 创建 IApi 实例。
/// </summary>
/// <param name="clientName">客户端的唯一名称。</param>
/// <returns>返回具体的 IApi 实现。</returns>
IApi CreateApi(string clientName);
}
}

View File

@@ -1,5 +1,5 @@
using CRSim.Core.Converters;
using System.Text.Json.Serialization;
using CRSim.Core.Abstractions;
using CRSim.Core.Services;
namespace CRSim.Core.Models
{
@@ -18,8 +18,9 @@ namespace CRSim.Core.Models
/// 直到终到后多久停止显示
/// </summary>
public TimeSpan StopDisplayFromArrivalDuration { get; set; } = TimeSpan.FromMinutes(10);
public TimeSpan StopCheckInAdvanceDuration { get; set; } = TimeSpan.FromMinutes(2);
public string ApiUri { get; set; } = "http://47.122.74.193:25565";
public IApi Api { get; set; } = new ApiFactory().CreateApi("镜像站");
public int MaxPages { get; set; } = 3;
public int SwitchPageSeconds { get; set; } = 20;
public string UserKey { get; set; } = "";

View File

@@ -0,0 +1,34 @@
using CRSim.Core.Abstractions;
namespace CRSim.Core.Services
{
/// <summary>
/// IApiFactory 的具体实现,负责根据配置实例化正确的 IApi 客户端。
/// </summary>
public class ApiFactory : IApiFactory
{
public IApi CreateApi(string clientName)
{
clientName ??= string.Empty;
return clientName switch
{
"镜像站" => new MirrorApi(),
"官方站" => new OfficialApi(),
_ => new OfficialApi()
};
}
}
public class OfficialApi : IApi
{
public string Name => "官方站";
public string BaseApi => "https://47.122.74.193:25565/";
public string UpdateApi => "https://api.github.com/repos/denglihong2007/CRSim/releases/latest";
}
public class MirrorApi : IApi
{
public string Name => "镜像站";
public string BaseApi => "https://crsim.com.cn/api";
public string UpdateApi => "https://crsim.com.cn/api/version";
}
}

View File

@@ -13,12 +13,12 @@ using Downloader;
namespace CRSim.Core.Services;
public class PluginService : IPluginService
public class PluginService(INetworkService networkService, ISettingsService settingsService) : IPluginService
{
public static readonly string PluginManifestFileName = "manifest.json";
public static readonly string StyleInfoFileName = "style.json";
private string IndexUrl => $"{_settings.ApiUri}/GetFile?fileName=plugins.json";
private string IndexUrl => $"{_settings.Api.BaseApi}/GetFile?fileName=plugins.json";
public static void InitializePlugins(HostBuilderContext context, IServiceCollection services,string externalPluginPath)
{
@@ -121,16 +121,11 @@ public class PluginService : IPluginService
}
}
}
private readonly Models.Settings _settings;
private readonly INetworkService _networkService;
public PluginService(INetworkService networkService,ISettingsService settingsService)
{
_networkService = networkService;
_settings = settingsService.GetSettings();
}
private readonly Settings _settings = settingsService.GetSettings();
public async Task LoadOnlinePluginsAsync()
{
var pluginManifests = await _networkService.GetOnlinePluginsAsync(IndexUrl);
var pluginManifests = await networkService.GetOnlinePluginsAsync(IndexUrl);
IPluginService.OnlinePluginsInternal.Clear();
foreach (var Manifest in pluginManifests ?? [])
{
@@ -138,7 +133,7 @@ public class PluginService : IPluginService
var info = new PluginInfo
{
Manifest = Manifest,
RealIconPath = $"{_settings.ApiUri}/GetFile?fileName=icons/{Manifest.Id}.png",
RealIconPath = $"{_settings.Api.BaseApi}/GetFile?fileName=icons/{Manifest.Id}.png",
LoadStatus = localInfo?.LoadStatus ?? PluginLoadStatus.NotLoaded,
PluginFolderPath = localInfo?.PluginFolderPath ?? string.Empty,
};
@@ -150,7 +145,7 @@ public class PluginService : IPluginService
public async Task InstallPluginOnlineAsync(PluginInfo plugin)
{
var id = plugin.Manifest.Id;
var packageUrl = $"{_settings.ApiUri}/GetFile?fileName=plugins/{id}{IPluginService.PluginPackageExtension}";
var packageUrl = $"{_settings.Api.BaseApi}/GetFile?fileName=plugins/{id}{IPluginService.PluginPackageExtension}";
var tempDir = Path.Combine(AppPaths.TempPath, "Plugins", Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);
var packagePath = Path.Combine(tempDir, $"{id}{IPluginService.PluginPackageExtension}");

View File

@@ -1,7 +1,6 @@
using CRSim.Core.Abstractions;
using CRSim.Core.Models;
using Microsoft.Win32;
using System.Text.Json;
namespace CRSim.Core.Services
{
@@ -12,7 +11,7 @@ namespace CRSim.Core.Services
public void SaveSettings()
{
_key.SetValue("SwitchPageSeconds", _settings.SwitchPageSeconds);
_key.SetValue("ApiUri", _settings.ApiUri);
_key.SetValue("Api", _settings.Api.Name);
_key.SetValue("MaxPages", _settings.MaxPages);
_key.SetValue("StopCheckInAdvanceDuration", (int)_settings.StopCheckInAdvanceDuration.TotalMinutes);
_key.SetValue("StopDisplayUntilDepartureDuration", (int)_settings.StopDisplayUntilDepartureDuration.TotalMinutes);
@@ -36,7 +35,7 @@ namespace CRSim.Core.Services
{
_settings = new Settings();
if (_key.GetValue("SwitchPageSeconds") != null) _settings.SwitchPageSeconds = (int)_key.GetValue("SwitchPageSeconds");
if (_key.GetValue("ApiUri") != null) _settings.ApiUri = (string)_key.GetValue("ApiUri");
_settings.Api = new ApiFactory().CreateApi((string)_key.GetValue("Api"));
if (_key.GetValue("MaxPages") != null) _settings.MaxPages = (int)_key.GetValue("MaxPages");
if (_key.GetValue("StopCheckInAdvanceDuration") != null) _settings.StopCheckInAdvanceDuration = TimeSpan.FromMinutes((int)_key.GetValue("StopCheckInAdvanceDuration"));
if (_key.GetValue("StopDisplayUntilDepartureDuration") != null) _settings.StopDisplayUntilDepartureDuration = TimeSpan.FromMinutes((int)_key.GetValue("StopDisplayUntilDepartureDuration"));

View File

@@ -8,14 +8,14 @@ using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
using System.Reflection;
namespace CRSim.PlatformDiagram
{
public class Generator
{
public static void Generate(Station station, string savePath)
{
float PageWidth = 5000;
public static void Generate(Station station, string savePath, float pageWidth)
{
float Padding = 40;
float HeaderHeight = 16;
float PlatformTableVerticalMargin = 9;
@@ -31,7 +31,7 @@ namespace CRSim.PlatformDiagram
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);
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);
@@ -44,7 +44,7 @@ namespace CRSim.PlatformDiagram
// 绘制整条横线
canvas.SetLineWidth(1f);
var xStart = Padding + InfoBarWidth + PlatformTableHorizontalMargin - TimelineExtLength;
var xEnd = PageWidth - Padding;
var xEnd = pageWidth - Padding;
var yTop = pageHeight - Padding - HeaderHeight - TimelineHeight;
var yBottom = Padding + TimelineHeight;
canvas.MoveTo(xStart, yTop).LineTo(xEnd, yTop).Stroke();
@@ -54,7 +54,7 @@ namespace CRSim.PlatformDiagram
var xBase = Padding + InfoBarWidth + PlatformTableHorizontalMargin;
yTop = pageHeight - Padding - HeaderHeight - TimelineHeight - PlatformTableVerticalMargin;
yBottom = Padding + TimelineHeight + PlatformTableVerticalMargin;
var PlatformTableLength = PageWidth - Padding * 2 - InfoBarWidth - PlatformTableHorizontalMargin - TimelineExtLength;
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);
@@ -221,7 +221,19 @@ namespace CRSim.PlatformDiagram
.SetFontSize(18)
.SetFontColor(ColorConstants.BLUE)
.SetMargins(0,0,0,0));
foreach(var kvp in platformHeights)
string text = $"使用 CRSim v{Assembly.GetExecutingAssembly().GetName().Version} 绘制";
float fontSize = 12f;
var para = new Paragraph(text)
.SetFont(font)
.SetFontSize(fontSize)
.SetFontColor(ColorConstants.BLUE)
.SetMargins(0, 0, 0, 0);
rect1 = new(pageWidth - Padding - font.GetWidth(text, fontSize), pageHeight - Padding, 500, HeaderHeight);
layoutCanvas = new Canvas(canvas, rect1);
layoutCanvas.Add(para);
foreach (var kvp in platformHeights)
{
rect1 = new(Padding, kvp.Value + PlatformHeight / 2 - 10, InfoBarWidth, 20);
layoutCanvas = new Canvas(canvas, rect1);

View File

@@ -1,6 +1,4 @@
using System.Windows;
namespace CRSim.ViewModels;
namespace CRSim.ViewModels;
public partial class DashboardPageViewModel : ObservableObject
{
[ObservableProperty]
@@ -17,12 +15,7 @@ public partial class DashboardPageViewModel : ObservableObject
}
private async void InitializeAsync()
{
var url = _settingsService.GetSettings().ApiUri.Contains("47")
? "https://api.github.com/repos/denglihong2007/CRSim/releases/latest"
: "https://crsim.com.cn/api/version";
var updateInfo = await _networkService.GetUpdateAsync(url);
var updateInfo = await _networkService.GetUpdateAsync(_settingsService.GetSettings().Api.UpdateApi);
if (updateInfo is not null && updateInfo.Name != Assembly.GetExecutingAssembly().GetName().Version.ToString())
{
UpdateMessage = $"有新版本 {updateInfo.Name} 可用,请前往“设置”下载安装更新!";

View File

@@ -9,7 +9,10 @@ public partial class PlatformDiagramPageViewModel(IDialogService _dialogService,
public List<Station> Stations => _databaseService.GetAllStations();
[ObservableProperty]
public partial bool IsSelected { get; set; } = false;
public partial bool Validated { get; set; } = false;
[ObservableProperty]
public partial int PageWidth { get; set; } = 5000;
[RelayCommand]
public void StationSelected(object s)
@@ -17,10 +20,14 @@ public partial class PlatformDiagramPageViewModel(IDialogService _dialogService,
if(s is Station station)
{
SelectedStation = station;
IsSelected = true;
}
Validate();
}
[RelayCommand]
public void Validate()
{
Validated = SelectedStation != null && PageWidth > 0;
}
[RelayCommand]
public async Task Generate()
{
@@ -30,7 +37,7 @@ public partial class PlatformDiagramPageViewModel(IDialogService _dialogService,
}
var path = _dialogService.SaveFile(".pdf", $"{SelectedStation.Name}站台占用图");
if(string.IsNullOrEmpty(path) || SelectedStation == null) return;
await Task.Run(() => Generator.Generate(SelectedStation, path));
await Task.Run(() => Generator.Generate(SelectedStation, path,PageWidth));
}
public static bool CheckStation(Station station,out string detail)

View File

@@ -13,10 +13,10 @@ namespace CRSim.ViewModels
[ObservableProperty]
public partial string AppVersion { get; set; } = "";
public ObservableCollection<InfoItem> Apis { get; } =
public ObservableCollection<IApi> Apis { get; } =
[
new InfoItem { Title = "官方源", Detail = "http://47.122.74.193:25565" },
new InfoItem { Title = "镜像站源", Detail = "https://crsim.com.cn/api" },
new ApiFactory().CreateApi("官方站"),
new ApiFactory().CreateApi("镜像站"),
];
private Settings _settings;
private readonly ISettingsService _settingsService;
@@ -50,7 +50,7 @@ namespace CRSim.ViewModels
public partial string SwitchPageSeconds { get; set; }
[ObservableProperty]
public partial InfoItem ApiUri { get; set; }
public partial IApi Api { get; set; }
[ObservableProperty]
public partial string UserKey { get; set; }
@@ -81,7 +81,7 @@ namespace CRSim.ViewModels
StopDisplayUntilDepartureDuration = _settings.StopDisplayUntilDepartureDuration.TotalMinutes.ToString();
StopDisplayFromArrivalDuration = _settings.StopDisplayFromArrivalDuration.TotalMinutes.ToString();
StopCheckInAdvanceDuration = _settings.StopCheckInAdvanceDuration.TotalMinutes.ToString();
ApiUri = Apis.Where(x => x.Detail == _settings.ApiUri).FirstOrDefault();
Api = Apis.First(x => x.Name == _settings.Api.Name);
MaxPages = _settings.MaxPages.ToString();
SwitchPageSeconds = _settings.SwitchPageSeconds.ToString();
UserKey = _settings.UserKey;
@@ -102,7 +102,7 @@ namespace CRSim.ViewModels
_settings.UserKey = UserKey;
_settings.LoadTodayOnly = LoadTodayOnly;
_settings.ReopenUnclosedScreensOnLoad = ReopenUnclosedScreensOnLoad;
_settings.ApiUri = ApiUri.Detail;
_settings.Api = Api;
_settingsService.SaveSettings();
}
private static void UpdateSettings(string input, bool allowNegative, Action<int> updateAction)
@@ -123,9 +123,7 @@ namespace CRSim.ViewModels
[RelayCommand]
public async Task CheckUpdate()
{
var update = ApiUri.Title == "官方源" ?
await _networkService.GetUpdateAsync("https://api.github.com/repos/denglihong2007/CRSim/releases/latest") :
await _networkService.GetUpdateAsync("https://crsim.com.cn/api/version");
var update = await _networkService.GetUpdateAsync(Api.UpdateApi);
if (update is null)
{
await _dialogService.ShowMessageAsync("错误", "检查更新失败。");
@@ -169,7 +167,7 @@ namespace CRSim.ViewModels
}
var programDirectory = AppDomain.CurrentDomain.BaseDirectory;
var appExePath = Process.GetCurrentProcess().MainModule.FileName;
var appExePath = Environment.ProcessPath;
var appName = Path.GetFileName(appExePath);
string batchScript = $@"
@echo off
@@ -197,7 +195,7 @@ namespace CRSim.ViewModels
}
catch (Exception e)
{
await _dialogService.ShowTextAsync("错误", "更新失败。\n" + e);
await _dialogService.ShowTextAsync("错误", "更新失败。若使用“官方站”,可尝试更换到“镜像站”。\n" + e);
UpdateProgress = 0;
return;
}

View File

@@ -1,4 +1,5 @@
using CRSim.Converters;
using CRSim.Core.Models.Plugin;
using System.Text.RegularExpressions;
namespace CRSim.ViewModels;
@@ -11,10 +12,14 @@ public partial class StationManagementPageViewModel : ObservableObject
public partial string PageTitle { get; set; } = "车站管理";
[ObservableProperty]
public partial bool IsSelected { get; set; } = false;
public partial string SearchText { get; set; } = "";
[ObservableProperty]
public partial List<string> StationNames { get; set; } = [];
public partial bool IsSelected { get; set; } = false;
public List<string> StationNames { get; set; } = [];
public List<string> FilteredStationNames => [.. StationNames.Where(x => x.Contains(SearchText))];
[ObservableProperty]
public partial Station SelectedStation { get; set; } = new();
@@ -74,6 +79,7 @@ public partial class StationManagementPageViewModel : ObservableObject
{
var stationsList = _databaseService.GetAllStations();
StationNames = [.. stationsList.Select(s => s.Name)];
OnPropertyChanged(nameof(FilteredStationNames));
}
[RelayCommand]
public void StationSelected(object args)
@@ -826,4 +832,9 @@ public partial class StationManagementPageViewModel : ObservableObject
return false;
}
[RelayCommand]
public void Search()
{
OnPropertyChanged(nameof(FilteredStationNames));
}
}

View File

@@ -5,9 +5,15 @@ public partial class TrainNumberManagementPageViewModel : ObservableObject
[ObservableProperty]
public partial string PageTitle { get; set; } = "车次管理";
[ObservableProperty]
public partial string SearchText { get; set; } = "";
[ObservableProperty]
public partial bool IsSelected { get; set; } = false;
public ObservableCollection<TrainNumber> TrainNumbers { get; set; } = [];
public List<TrainNumber> TrainNumbers { get; set; } = [];
public List<TrainNumber> FilteredTrainNumbers => [.. TrainNumbers.Where(x => x.Number.Contains(SearchText))];
[ObservableProperty]
public partial TrainNumber SelectedTrainNumber { get; set; } = new();
@@ -72,6 +78,7 @@ public partial class TrainNumberManagementPageViewModel : ObservableObject
{
TrainNumbers.Add(t);
}
OnPropertyChanged(nameof(FilteredTrainNumbers));
}
[RelayCommand]
@@ -827,4 +834,10 @@ public partial class TrainNumberManagementPageViewModel : ObservableObject
return TimeSpan.FromMinutes(Math.Round(time.TotalMinutes));
return default;
}
[RelayCommand]
public void Search()
{
OnPropertyChanged(nameof(FilteredTrainNumbers));
}
}

View File

@@ -22,18 +22,30 @@
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" Orientation="Vertical" Margin="0,0,0,24">
<controls:SettingsCard Header="车站" Description="选择目标车站。" HeaderIcon="{winui:FontIcon Glyph=&#xE825;}">
<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 Header="页宽" Description="生成的 PDF 页面宽度。" HeaderIcon="{winui:FontIcon Glyph=&#xEF6B;}">
<NumberBox Value="{x:Bind ViewModel.PageWidth, Mode=TwoWay}" Width="120">
<i:Interaction.Behaviors>
<i:EventTriggerBehavior EventName="ValueChanged">
<i:InvokeCommandAction Command="{x:Bind ViewModel.ValidateCommand}"/>
</i:EventTriggerBehavior>
</i:Interaction.Behaviors>
</NumberBox>
</controls:SettingsCard>
</StackPanel>
<TextBlock Text="操作" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
<controls:SettingsCard Header="车站" Description="选择目标车站。" HeaderIcon="{winui:FontIcon Glyph=&#xE825;}">
<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=&#xE74E;}">
<Button Content="生成" IsEnabled="{x:Bind ViewModel.IsSelected, Mode=OneWay}" Style="{StaticResource AccentButtonStyle}"
<Button Content="生成" IsEnabled="{x:Bind ViewModel.Validated, Mode=OneWay}" Style="{StaticResource AccentButtonStyle}"
Command="{x:Bind ViewModel.GenerateCommand}"/>
</controls:SettingsCard>
</StackPanel>

View File

@@ -43,8 +43,8 @@
<TextBox Width="168" Text="{x:Bind ViewModel.UserKey, Mode=TwoWay}"/>
</controls:SettingsCard>
<controls:SettingsCard Header="API 地址" Description="适用于插件市场与软件更新" HeaderIcon="{winui:FontIcon Glyph=&#xE943;}">
<ComboBox ItemsSource="{x:Bind ViewModel.Apis}" SelectedItem="{x:Bind ViewModel.ApiUri,Mode=TwoWay}"
DisplayMemberPath="Title" Width="168"/>
<ComboBox ItemsSource="{x:Bind ViewModel.Apis}" SelectedItem="{x:Bind ViewModel.Api,Mode=TwoWay}"
DisplayMemberPath="Name" Width="168"/>
</controls:SettingsCard>
<controls:SettingsCard Header="应用更新" Description="检查软件更新" HeaderIcon="{winui:FontIcon Glyph=&#xECC5;}">
<Button Style="{StaticResource AccentButtonStyle}" Content="检查更新" Command="{x:Bind ViewModel.CheckUpdateCommand}" />

View File

@@ -46,6 +46,7 @@
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
@@ -57,8 +58,16 @@
<AppBarButton Label="从模拟广播系统导入" Command="{x:Bind ViewModel.ImportFrom7DCommand}" />
</CommandBar.SecondaryCommands>
</CommandBar>
<Border Grid.Row="1" Style="{StaticResource ListViewBorder}">
<ListView x:Name="StationsList" ItemsSource="{x:Bind ViewModel.StationNames,Mode=OneWay}" SelectionMode="Single">
<AutoSuggestBox Grid.Row="1" PlaceholderText="搜索车站" QueryIcon="Find" Text="{x:Bind ViewModel.SearchText,Mode=TwoWay}"
Margin="0,0,0,8" HorizontalAlignment="Stretch">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="TextChanged">
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.SearchCommand}" />
</interactivity:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AutoSuggestBox>
<Border Grid.Row="2" Style="{StaticResource ListViewBorder}">
<ListView x:Name="StationsList" ItemsSource="{x:Bind ViewModel.FilteredStationNames,Mode=OneWay}" SelectionMode="Single">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="SelectionChanged">
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.StationSelectedCommand}" />

View File

@@ -36,6 +36,7 @@
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
@@ -60,8 +61,16 @@
</CommandBar.SecondaryCommands>
</CommandBar>
<ProgressBar Grid.Row="1" Value="{x:Bind ViewModel.ProgressValue,Mode=OneWay}" Visibility="{x:Bind ViewModel.ProgressValue,Mode=OneWay,Converter={StaticResource IntToVisibilityConverter},ConverterParameter=false}"/>
<Border Grid.Row="2" Style="{StaticResource ListViewBorder}">
<ListView x:Name="TrainNumbersList" ItemsSource="{x:Bind ViewModel.TrainNumbers,Mode=OneWay}" SelectionMode="Single">
<AutoSuggestBox Grid.Row="2" PlaceholderText="搜索车次" QueryIcon="Find" Text="{x:Bind ViewModel.SearchText,Mode=TwoWay}"
Margin="0,0,0,8" HorizontalAlignment="Stretch">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="TextChanged">
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.SearchCommand}" />
</interactivity:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AutoSuggestBox>
<Border Grid.Row="3" Style="{StaticResource ListViewBorder}">
<ListView x:Name="TrainNumbersList" ItemsSource="{x:Bind ViewModel.FilteredTrainNumbers,Mode=OneWay}" SelectionMode="Single">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="SelectionChanged">
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.TrainNumberSelectedCommand}" />

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.1.0.0</Version>
<Version>3.1.1.0</Version>
<Authors>电排骨</Authors>
<RepositoryUrl>https://github.com/denglihong2007/CRSim</RepositoryUrl>
</PropertyGroup>