mirror of
https://github.com/denglihong2007/CRSim
synced 2026-08-11 04:05:36 +08:00
chore: 一些杂乱的更改
This commit is contained in:
@@ -10,6 +10,8 @@ public abstract class PluginBase
|
||||
/// </summary>
|
||||
public PluginInfo Info { get; internal set; } = null!;
|
||||
|
||||
public abstract Type ViewModel { get; }
|
||||
public abstract Type View { get; }
|
||||
/// <summary>
|
||||
/// 初始化插件。一般在这个方法中完成插件的各项服务的注册。
|
||||
/// </summary>
|
||||
|
||||
@@ -5,16 +5,13 @@
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TrimMode>partial</TrimMode>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="Downloader" Version="4.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.6" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.7" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CRSim.Core.Models
|
||||
{
|
||||
@@ -7,4 +8,12 @@ namespace CRSim.Core.Models
|
||||
public partial class JsonContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(List<PluginManifest>))]
|
||||
[JsonSerializable(typeof(StyleInfo))]
|
||||
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
|
||||
public partial class JsonContextWithCamelCase : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.Core.Enums;
|
||||
using Downloader;
|
||||
|
||||
namespace CRSim.Core.Models.Plugin;
|
||||
public partial class PluginInfo : ObservableRecipient
|
||||
{
|
||||
public DownloadService? DownloadService;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _downloadProgress = 0;
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CRSim.Core.Models.Plugin;
|
||||
namespace CRSim.Core.Models.Plugin;
|
||||
|
||||
/// <summary>
|
||||
/// 插件元数据
|
||||
@@ -12,54 +9,45 @@ public class PluginManifest
|
||||
/// 入口程序集。加载插件时,将在此入口程序集中搜索插件类。
|
||||
/// </summary>
|
||||
/// <example>MyPlugin.dll</example>
|
||||
[JsonPropertyName("entranceAssembly")]
|
||||
public string EntranceAssembly { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 插件显示名称。
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 插件ID。
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public string Id { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 插件自述。
|
||||
/// </summary>
|
||||
[JsonPropertyName("description")]
|
||||
public string Description { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 项目 Url
|
||||
/// </summary>
|
||||
[JsonPropertyName("url")]
|
||||
public string? Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 插件版本
|
||||
/// </summary>
|
||||
[JsonPropertyName("version")]
|
||||
public string Version { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 插件目标 CRSim 版本
|
||||
/// </summary>
|
||||
[JsonPropertyName("apiVersion")]
|
||||
public string ApiVersion { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 插件作者
|
||||
/// </summary>
|
||||
[JsonPropertyName("author")]
|
||||
public string Author { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 插件类型
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; } = "";
|
||||
}
|
||||
@@ -4,8 +4,8 @@ namespace CRSim.Core.Models
|
||||
{
|
||||
public class StyleInfo
|
||||
{
|
||||
public required string[] Parameters;
|
||||
public required string Type;
|
||||
public required string Region;
|
||||
public string[] Parameters { get; set; } = [];
|
||||
public string Type { get; set; } = "";
|
||||
public string Region { get; set; } = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace CRSim.Core.Services
|
||||
{
|
||||
var client = new HttpClient();
|
||||
var response = client.GetStringAsync(url).Result;
|
||||
return JsonSerializer.Deserialize<List<PluginManifest>>(response);
|
||||
return JsonSerializer.Deserialize(response, JsonContextWithCamelCase.Default.ListPluginManifest);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -4,32 +4,29 @@ using CRSim.Core.Enums;
|
||||
using CRSim.Core.Models;
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using CRSim.Core.Utils;
|
||||
using Downloader;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using Windows.System;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
namespace CRSim.Core.Services;
|
||||
|
||||
public class PluginService : IPluginService
|
||||
{
|
||||
public static readonly string PluginManifestFileName = "manifest.yml";
|
||||
public static readonly string PluginManifestFileName = "manifest.json";
|
||||
public static readonly string StyleInfoFileName = "style.json";
|
||||
|
||||
private string IndexUrl => $"{_settings.ApiUri}/GetFile?fileName=plugins.json";
|
||||
|
||||
public static void InitializePlugins(HostBuilderContext context, IServiceCollection services,string externalPluginPath)
|
||||
{
|
||||
if(!Directory.Exists(AppPaths.PluginsRootPath))
|
||||
Console.WriteLine("开始加载插件");
|
||||
if (!Directory.Exists(AppPaths.PluginsRootPath))
|
||||
{
|
||||
Directory.CreateDirectory(AppPaths.PluginsRootPath);
|
||||
}
|
||||
var deserializer = new DeserializerBuilder()
|
||||
.IgnoreUnmatchedProperties()
|
||||
.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
||||
.Build();
|
||||
|
||||
var pluginDirs = Directory.EnumerateDirectories(AppPaths.PluginsRootPath);
|
||||
if(!string.IsNullOrEmpty(externalPluginPath))
|
||||
{
|
||||
@@ -38,6 +35,7 @@ public class PluginService : IPluginService
|
||||
|
||||
foreach (var pluginDir in pluginDirs)
|
||||
{
|
||||
Console.WriteLine($"当前插件搜寻目录: {pluginDir}");
|
||||
if (string.IsNullOrWhiteSpace(pluginDir))
|
||||
continue;
|
||||
var manifestPath = Path.Combine(pluginDir, PluginManifestFileName);
|
||||
@@ -47,17 +45,26 @@ public class PluginService : IPluginService
|
||||
}
|
||||
|
||||
var manifestYaml = File.ReadAllText(manifestPath);
|
||||
var manifest = deserializer.Deserialize<PluginManifest?>(manifestYaml);
|
||||
if (manifest == null)
|
||||
PluginManifest manifest = new();
|
||||
try
|
||||
{
|
||||
Console.WriteLine(manifestYaml);
|
||||
manifest = JsonSerializer.Deserialize(manifestYaml,JsonContextWithCamelCase.Default.PluginManifest);
|
||||
Console.WriteLine("成功解析YAML文件: " + manifestPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("YAML解析失败");
|
||||
Console.WriteLine(ex.ToString());
|
||||
continue;
|
||||
}
|
||||
Console.WriteLine("找到插件: " + manifest.Id);
|
||||
var info = new PluginInfo
|
||||
{
|
||||
Manifest = manifest,
|
||||
PluginFolderPath = Path.GetFullPath(pluginDir),
|
||||
RealIconPath = Path.Combine(Path.GetFullPath(pluginDir), "icon.png"),
|
||||
StyleInfo = manifest.Type == "ScreenStyle" ? deserializer.Deserialize<StyleInfo?>(File.ReadAllText(Path.Combine(Path.GetFullPath(pluginDir), "style.yml"))) : null,
|
||||
StyleInfo = JsonSerializer.Deserialize(File.ReadAllText(Path.Combine(Path.GetFullPath(pluginDir), StyleInfoFileName)),JsonContextWithCamelCase.Default.StyleInfo),
|
||||
};
|
||||
if (info.IsUninstalling)
|
||||
{
|
||||
@@ -81,6 +88,7 @@ public class PluginService : IPluginService
|
||||
var pluginDir = info.PluginFolderPath;
|
||||
try
|
||||
{
|
||||
Console.WriteLine("尝试加载插件: " + manifest.Id);
|
||||
var fullPath = Path.GetFullPath(Path.Combine(pluginDir, manifest.EntranceAssembly));
|
||||
var asm = Assembly.LoadFrom(fullPath);
|
||||
var entrance = asm.ExportedTypes.FirstOrDefault(x =>
|
||||
@@ -102,10 +110,11 @@ public class PluginService : IPluginService
|
||||
services.AddSingleton(typeof(PluginBase), entranceObj);
|
||||
services.AddSingleton(entrance, entranceObj);
|
||||
info.LoadStatus = PluginLoadStatus.Loaded;
|
||||
Console.WriteLine($"Initialize plugin: {pluginDir} ({manifest.Version})");
|
||||
Console.WriteLine($"加载插件成功: {pluginDir} ({manifest.Version})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"加载插件失败: {ex}");
|
||||
info.Exception = ex;
|
||||
info.LoadStatus = PluginLoadStatus.Error;
|
||||
}
|
||||
@@ -145,20 +154,21 @@ public class PluginService : IPluginService
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var packagePath = Path.Combine(tempDir, $"{id}{IPluginService.PluginPackageExtension}");
|
||||
DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
plugin.DownloadService = new DownloadService();
|
||||
plugin.DownloadService.DownloadProgressChanged += (s, e) =>
|
||||
{
|
||||
dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
plugin.DownloadProgress = (int)(e.ProgressPercentage);
|
||||
Console.WriteLine(e.ProgressPercentage);
|
||||
});
|
||||
};
|
||||
var downloader = new Downloader();
|
||||
plugin.DownloadProgress = 0;
|
||||
|
||||
try
|
||||
{
|
||||
await plugin.DownloadService.DownloadFileTaskAsync(packageUrl,packagePath);
|
||||
await downloader.DownloadFileAsync(packageUrl, packagePath, new Progress<double>(p =>
|
||||
{
|
||||
dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
plugin.DownloadProgress = (int)p;
|
||||
Console.WriteLine(p);
|
||||
});
|
||||
}));
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
plugin.DownloadProgress = 0;
|
||||
|
||||
41
CRSim.Core/Utils/Downloader.cs
Normal file
41
CRSim.Core/Utils/Downloader.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CRSim.Core.Utils
|
||||
{
|
||||
public class Downloader
|
||||
{
|
||||
private readonly HttpClient _httpClient = new();
|
||||
|
||||
public async Task DownloadFileAsync(string url, string outputPath, IProgress<double>? progress = null)
|
||||
{
|
||||
using var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var totalBytes = response.Content.Headers.ContentLength ?? -1L;
|
||||
var canReportProgress = totalBytes != -1 && progress != null;
|
||||
|
||||
await using var contentStream = await response.Content.ReadAsStreamAsync();
|
||||
await using var fileStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
|
||||
|
||||
var buffer = new byte[8192];
|
||||
long totalRead = 0;
|
||||
int bytesRead;
|
||||
|
||||
while ((bytesRead = await contentStream.ReadAsync(buffer)) > 0)
|
||||
{
|
||||
await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead));
|
||||
totalRead += bytesRead;
|
||||
|
||||
if (canReportProgress)
|
||||
{
|
||||
double percentage = totalRead * 100d / totalBytes;
|
||||
progress!.Report(percentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TrimMode>partial</TrimMode>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CRSim.Core\CRSim.Core.csproj">
|
||||
@@ -23,10 +22,10 @@
|
||||
<None Update="icon.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="manifest.yml">
|
||||
<None Update="manifest.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="style.yml">
|
||||
<None Update="style.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace CRSim.ExamplePlugin;
|
||||
[PluginEntrance]
|
||||
public class Plugin : PluginBase
|
||||
{
|
||||
public Type ViewModel => typeof(ScreenViewModel);
|
||||
public Type View => typeof(ScreenView);
|
||||
public override Type ViewModel => typeof(ScreenViewModel);
|
||||
public override Type View => typeof(ScreenView);
|
||||
public override void Initialize(HostBuilderContext context, IServiceCollection services)
|
||||
{
|
||||
services.AddTransient(ViewModel);
|
||||
|
||||
11
CRSim.ExamplePlugin/manifest.json
Normal file
11
CRSim.ExamplePlugin/manifest.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"entranceAssembly": "CRSim.ExamplePlugin.dll",
|
||||
"name": "示例插件",
|
||||
"id": "CRSim.ExamplePlugin",
|
||||
"url": "https://crsim.tech",
|
||||
"version": "0.0.0.0",
|
||||
"apiVersion": "3.0.0.0",
|
||||
"author": "电排骨",
|
||||
"type": "ScreenStyle",
|
||||
"description": "这是一个示例插件。"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
entranceAssembly: "CRSim.ExamplePlugin.dll"
|
||||
name: "示例插件"
|
||||
id: "denglihong2007.ExamplePlugin"
|
||||
url: "https://crsim.tech"
|
||||
version: "0.0.0.0"
|
||||
apiVersion: "3.0.0.0"
|
||||
author: "电排骨"
|
||||
type: "ScreenStyle"
|
||||
description: "这是一个示例插件。"
|
||||
5
CRSim.ExamplePlugin/style.json
Normal file
5
CRSim.ExamplePlugin/style.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"parameters": [ "station", "text" ],
|
||||
"region": "广元",
|
||||
"type": "车站大屏"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
parameters :
|
||||
- "station"
|
||||
- "text"
|
||||
region: "广元"
|
||||
type: "车站大屏"
|
||||
@@ -4,14 +4,13 @@
|
||||
<TargetFramework>net9.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TrimMode>partial</TrimMode>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
|
||||
<PackageReference Include="PinYinConverterCore" Version="1.0.2" />
|
||||
<PackageReference Include="PP.Wpf" Version="1.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
AppHost.Services.GetRequiredService<ITimeService>().Start();
|
||||
MainWindow = AppHost.Services.GetService<MainWindow>();
|
||||
MainWindow?.Activate();
|
||||
var win = AppHost.Services.GetService<StyleManager>();
|
||||
}
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<TrimMode>partial</TrimMode>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<Version>2.3.102.0</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
@@ -56,10 +54,10 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
|
||||
<PackageReference Include="EPPlus" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
|
||||
<PackageReference Include="EPPlus" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
@@ -131,11 +129,12 @@
|
||||
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
|
||||
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
|
||||
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
|
||||
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
|
||||
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>
|
||||
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<ApplicationIcon>Assets\CRSimIcon.ico</ApplicationIcon>
|
||||
<SignAssembly>False</SignAssembly>
|
||||
<PackageIcon>CRSimIcon.png</PackageIcon>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PublishAot>False</PublishAot>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -15,7 +15,7 @@ public partial class PluginManagementPageViewModel : ObservableObject
|
||||
[ObservableProperty]
|
||||
public partial PluginInfo? SelectedPlugin { get; set; }
|
||||
|
||||
public ObservableCollection<PluginInfo> Plugins = [];
|
||||
public ObservableCollection<PluginInfo> Plugins = IPluginService.OnlinePlugins;
|
||||
|
||||
private IPluginService _pluginService;
|
||||
|
||||
@@ -66,12 +66,14 @@ public partial class PluginManagementPageViewModel : ObservableObject
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void SourceSelected(SelectorBarItem selectorBarItem)
|
||||
public void SourceSelected(object args)
|
||||
{
|
||||
SelectedPlugin = null;
|
||||
Plugins = (selectorBarItem?.Text == "本地" || selectorBarItem is null)
|
||||
? IPluginService.OnlinePlugins : IPluginService.LoadedPlugins;
|
||||
OnPropertyChanged(nameof(Plugins));
|
||||
if(args is SelectorBarItem selectorBarItem)
|
||||
{
|
||||
SelectedPlugin = null;
|
||||
Plugins = (selectorBarItem?.Text == "本地") ? IPluginService.OnlinePlugins : IPluginService.LoadedPlugins;
|
||||
OnPropertyChanged(nameof(Plugins));
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace CRSim.ViewModels;
|
||||
|
||||
@@ -132,7 +133,7 @@ public partial class ScreenSimulatorPageViewModel(IServiceProvider serviceProvid
|
||||
[RelayCommand]
|
||||
public async Task StartSimulation()
|
||||
{
|
||||
StyleManager.ShowWindow(((dynamic)SelectedStylePlugin).View,
|
||||
StyleManager.ShowWindow(SelectedStylePlugin.View,
|
||||
databaseService.GetStationByName(SelectedStationName),
|
||||
TicketCheckNeeded ? SelectedTicketCheck : string.Empty,
|
||||
PlatformNeeded ? SelectedPlatformName : string.Empty,
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<SelectorBar x:Name="SelectorBar" Grid.Column="0">
|
||||
<SelectorBar x:Name="SelectorBar" Grid.Column="0" SelectionChanged="SelectorBar_SelectionChanged">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:EventTriggerBehavior EventName="SelectionChanged">
|
||||
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.SourceSelectedCommand}" CommandParameter="{x:Bind SelectorBar.SelectedItem,Mode=OneWay}"/>
|
||||
|
||||
@@ -11,4 +11,9 @@ public sealed partial class PluginManagementPage : Page
|
||||
InitializeComponent();
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SelectorBar_SelectionChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs args)
|
||||
{
|
||||
Console.WriteLine($"SelectorBar selection changed");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user