mirror of
https://github.com/denglihong2007/CRSim
synced 2026-08-08 02:25:35 +08:00
feat: #203 添加插件市场
This commit is contained in:
@@ -14,9 +14,9 @@
|
||||
{
|
||||
LaunchDebugConsole();
|
||||
}
|
||||
if (!Directory.Exists(AppPaths.AppDataFolder))
|
||||
if (!Directory.Exists(AppPaths.AppDataPath))
|
||||
{
|
||||
Directory.CreateDirectory(AppPaths.AppDataFolder);
|
||||
Directory.CreateDirectory(AppPaths.AppDataPath);
|
||||
}
|
||||
AppHost = Host.CreateDefaultBuilder()
|
||||
.ConfigureServices((context, services) =>
|
||||
@@ -34,6 +34,7 @@
|
||||
services.AddTransient<StationManagementPageViewModel>();
|
||||
services.AddTransient<ScreenSimulatorPageViewModel>();
|
||||
services.AddTransient<SettingsPageViewModel>();
|
||||
services.AddTransient<PluginManagementPageViewModel>();
|
||||
PluginService.InitializePlugins(context, services, parsedOptions.ExternalPluginPath);
|
||||
})
|
||||
.Build();
|
||||
@@ -45,7 +46,6 @@
|
||||
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,6 +13,8 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<TrimMode>partial</TrimMode>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<Version>2.3.101.1</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
@@ -82,6 +84,9 @@
|
||||
<Page Update="Views\ScreenSimulatorPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\PluginManagementPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\SettingsPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
|
||||
@@ -6,7 +6,9 @@ namespace CRSim.Converters
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
return value == null ? Visibility.Collapsed : Visibility.Visible;
|
||||
bool invert = (parameter as string)?.ToLower() == "invert";
|
||||
bool isNull = value == null;
|
||||
return invert ? isNull ? Visibility.Visible : Visibility.Collapsed : isNull ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
|
||||
34
CRSim/Converters/PluginLoadStatusToVisibilityConverter.cs
Normal file
34
CRSim/Converters/PluginLoadStatusToVisibilityConverter.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using CRSim.Core.Enums;
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace CRSim.Converters
|
||||
{
|
||||
public partial class PluginLoadStatusToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if(value is PluginInfo plugin && parameter is string target)
|
||||
{
|
||||
PluginLoadStatus status = plugin.LoadStatus;
|
||||
if ((plugin.IsUninstalling && target== "Loaded") || (plugin.RestartRequired && target == "NotLoaded"))
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
if ((status == PluginLoadStatus.Loaded && target == "Loaded") ||
|
||||
(status == PluginLoadStatus.Error && target == "Error") ||
|
||||
(status == PluginLoadStatus.NotLoaded && target == "NotLoaded") ||
|
||||
(status == PluginLoadStatus.Disabled && target == "Disabled"))
|
||||
{
|
||||
return Visibility.Visible;
|
||||
}
|
||||
}
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,11 @@
|
||||
IsBackButtonVisible="Collapsed" IsBackEnabled="False">
|
||||
<NavigationView.MenuItems>
|
||||
<NavigationViewItem Icon="Home" Content="主页" Tag="DashboardPage" />
|
||||
<NavigationViewItem Content="插件" Tag="PluginManagementPage">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph="" />
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
<NavigationViewItemHeader Content="数据管理"/>
|
||||
<NavigationViewItem Content="车站" Tag="StationManagementPage">
|
||||
<NavigationViewItem.Icon>
|
||||
|
||||
92
CRSim/ViewModels/PluginManagementPageViewModel.cs
Normal file
92
CRSim/ViewModels/PluginManagementPageViewModel.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using CRSim.Core.Abstractions;
|
||||
using CRSim.Core.Models;
|
||||
using CRSim.Core.Models.Plugin;
|
||||
using CRSim.Core.Services;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CRSim.ViewModels;
|
||||
|
||||
public partial class PluginManagementPageViewModel : ObservableObject
|
||||
{
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string PageTitle { get; set; } = "插件管理";
|
||||
|
||||
[ObservableProperty]
|
||||
public partial PluginInfo? SelectedPlugin { get; set; }
|
||||
|
||||
public ObservableCollection<PluginInfo> Plugins = [];
|
||||
|
||||
private IPluginService _pluginService;
|
||||
|
||||
public PluginManagementPageViewModel(IPluginService pluginService)
|
||||
{
|
||||
_pluginService = pluginService;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void PluginSelected(object args)
|
||||
{
|
||||
if(args is SelectionChangedEventArgs selectionChangedEventArgs && selectionChangedEventArgs.AddedItems.Count == 1)
|
||||
{
|
||||
SelectedPlugin = (PluginInfo)selectionChangedEventArgs.AddedItems.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async Task InstallPlugin()
|
||||
{
|
||||
await _pluginService.InstallPluginAsync(SelectedPlugin);
|
||||
OnPropertyChanged(nameof(SelectedPlugin));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void UninstallPlugin()
|
||||
{
|
||||
SelectedPlugin.IsUninstalling = true;
|
||||
OnPropertyChanged(nameof(SelectedPlugin));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void CancelUninstallPlugin()
|
||||
{
|
||||
SelectedPlugin.IsUninstalling = false;
|
||||
OnPropertyChanged(nameof(SelectedPlugin));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public static void Restart()
|
||||
{
|
||||
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
Process.Start(new ProcessStartInfo(exePath)
|
||||
{
|
||||
UseShellExecute = true
|
||||
});
|
||||
Application.Current.Exit();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void SourceSelected(SelectorBarItem selectorBarItem)
|
||||
{
|
||||
SelectedPlugin = null;
|
||||
Plugins = (selectorBarItem?.Text == "本地" || selectorBarItem is null)
|
||||
? IPluginService.OnlinePlugins : IPluginService.LoadedPlugins;
|
||||
OnPropertyChanged(nameof(Plugins));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public static void OpenPluginFolder()
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = AppPaths.PluginsRootPath,
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void Refresh()
|
||||
{
|
||||
_pluginService.LoadOnlinePlugins();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Reflection;
|
||||
using System.Diagnostics.Metrics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CRSim.ViewModels
|
||||
{
|
||||
@@ -9,7 +10,11 @@ namespace CRSim.ViewModels
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string AppVersion { get; set; } = "";
|
||||
|
||||
public ObservableCollection<InfoItem> Apis { get; } =
|
||||
[
|
||||
new InfoItem { Title = "官方插件源", Detail = "http://47.122.74.193:25565" },
|
||||
new InfoItem { Title = "镜像站插件源", Detail = "https://crsim.com.cn/api" },
|
||||
];
|
||||
private Settings _settings;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IDatabaseService _databaseService;
|
||||
@@ -39,6 +44,9 @@ namespace CRSim.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial string SwitchPageSeconds { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial InfoItem ApiUri { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string UserKey { get; set; }
|
||||
|
||||
@@ -67,6 +75,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();
|
||||
MaxPages = _settings.MaxPages.ToString();
|
||||
SwitchPageSeconds = _settings.SwitchPageSeconds.ToString();
|
||||
UserKey = _settings.UserKey;
|
||||
@@ -88,6 +97,7 @@ namespace CRSim.ViewModels
|
||||
_settings.UserKey = UserKey;
|
||||
_settings.LoadTodayOnly = LoadTodayOnly;
|
||||
_settings.ReopenUnclosedScreensOnLoad = ReopenUnclosedScreensOnLoad;
|
||||
_settings.ApiUri = ApiUri.Detail;
|
||||
_settingsService.SaveSettings();
|
||||
}
|
||||
private void UpdateSettings(string input, bool allowNegative, Action<int> updateAction)
|
||||
|
||||
@@ -573,24 +573,17 @@ public partial class StationManagementPageViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
public async Task ImportFromInternet()
|
||||
{
|
||||
try
|
||||
if (!await CheckCanImport()) return;
|
||||
var stops = await _networkService.GetTrainNumbersAsync(SelectedStation.Name);
|
||||
if (stops is not null && stops.Count != 0)
|
||||
{
|
||||
if (!await CheckCanImport()) return;
|
||||
var stops = await _networkService.GetTrainNumbersAsync(SelectedStation.Name);
|
||||
if (stops.Count != 0)
|
||||
TrainStops.Clear();
|
||||
foreach (TrainStop t in stops)
|
||||
{
|
||||
TrainStops.Clear();
|
||||
foreach (TrainStop t in stops)
|
||||
{
|
||||
TrainStops.Add(RandomTrainStopProperties(t));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception();
|
||||
TrainStops.Add(RandomTrainStopProperties(t));
|
||||
}
|
||||
}
|
||||
catch
|
||||
else
|
||||
{
|
||||
await _dialogService.ShowMessageAsync("获取失败", "服务器繁忙或车站不存在。");
|
||||
}
|
||||
|
||||
144
CRSim/Views/PluginManagementPage.xaml
Normal file
144
CRSim/Views/PluginManagementPage.xaml
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Page
|
||||
x:Class="CRSim.Views.PluginManagementPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CRSim.Views"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:converters="using:CRSim.Converters"
|
||||
xmlns:converters1="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:winui="using:CommunityToolkit.WinUI"
|
||||
xmlns:viewmodels="using:CRSim.ViewModels"
|
||||
xmlns:models="using:CRSim.Models"
|
||||
xmlns:coremodels="using:CRSim.Core.Models"
|
||||
xmlns:pluginmodels="using:CRSim.Core.Models.Plugin"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=viewmodels:PluginManagementPageViewModel}">
|
||||
<Page.Resources>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
|
||||
<converters:IntToVisibilityConverter x:Key="IntToVisibilityConverter"/>
|
||||
<converters:PluginLoadStatusToVisibilityConverter x:Key="PluginLoadStatusToVisibilityConverter"/>
|
||||
<converters1:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
</Page.Resources>
|
||||
<Grid x:Name="ContentPagePane" Margin="36,40,0,36">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="{x:Bind ViewModel.PageTitle}" Margin="0,0,0,36"
|
||||
Style="{StaticResource TitleTextBlockStyle}"/>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<SelectorBar x:Name="SelectorBar" Grid.Column="0">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:EventTriggerBehavior EventName="SelectionChanged">
|
||||
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.SourceSelectedCommand}" CommandParameter="{x:Bind SelectorBar.SelectedItem,Mode=OneWay}"/>
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<SelectorBarItem Text="在线" Icon="{winui:FontIcon Glyph=}" IsSelected="True"/>
|
||||
<SelectorBarItem Text="本地" Icon="{winui:FontIcon Glyph=}" />
|
||||
</SelectorBar>
|
||||
<Button Grid.Column="2" Content="{winui:FontIcon Glyph=}" Style="{StaticResource EllipsisButton}"
|
||||
Command="{x:Bind ViewModel.RefreshCommand}"/>
|
||||
<Button Grid.Column="3" Content="{winui:FontIcon Glyph=}" Style="{StaticResource EllipsisButton}"
|
||||
Command="{x:Bind ViewModel.OpenPluginFolderCommand}"/>
|
||||
</Grid>
|
||||
<Border Style="{StaticResource ListViewBorder}" Grid.Row="1">
|
||||
<ListView ItemsSource="{x:Bind ViewModel.Plugins,Mode=OneWay}" Width="290" SelectionMode="Single">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:EventTriggerBehavior EventName="SelectionChanged">
|
||||
<interactivity:InvokeCommandAction Command="{x:Bind ViewModel.PluginSelectedCommand}" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="pluginmodels:PluginInfo">
|
||||
<StackPanel Orientation="Horizontal" Padding="0,6">
|
||||
<Border CornerRadius="4">
|
||||
<Image Width="72" Height="72" Source="{x:Bind RealIconPath}" Margin="0,0,8,0"/>
|
||||
</Border>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="{x:Bind Manifest.Name}" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="{x:Bind Manifest.Description}" TextWrapping="Wrap" MaxWidth="185"
|
||||
Style="{StaticResource CaptionTextBlockStyle}" Foreground="{ThemeResource SystemControlBackgroundBaseMediumBrush}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Border>
|
||||
</Grid>
|
||||
<ScrollViewer Grid.Column="1" Padding="16,0,36,0">
|
||||
<Grid>
|
||||
<TextBlock Text="请在左侧选择一个插件" Visibility="{x:Bind ViewModel.SelectedPlugin,Mode=OneWay,Converter={StaticResource NullToVisibilityConverter},ConverterParameter=invert}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{ThemeResource SystemControlBackgroundBaseMediumBrush}"/>
|
||||
<StackPanel Orientation="Vertical" Visibility="{x:Bind ViewModel.SelectedPlugin,Mode=OneWay,Converter={StaticResource NullToVisibilityConverter}}">
|
||||
<Grid Margin="0,0,0,12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Height="124" Source="{x:Bind ViewModel.SelectedPlugin.RealIconPath,Mode=OneWay}" HorizontalAlignment="Left"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Vertical" Margin="12,0,0,0">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,6">
|
||||
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{x:Bind ViewModel.SelectedPlugin.Manifest.Name,Mode=OneWay}" />
|
||||
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{x:Bind ViewModel.SelectedPlugin.Manifest.Version, Mode=OneWay}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" VerticalAlignment="Bottom" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
|
||||
<HyperlinkButton Content="项目主页" NavigateUri="{x:Bind ViewModel.SelectedPlugin.Manifest.Url,Mode=OneWay}" Style="{StaticResource TextBlockButtonStyle}"/>
|
||||
<TextBlock Text="{x:Bind ViewModel.SelectedPlugin.Manifest.Author, Mode=OneWay}" VerticalAlignment="Center" Margin="8,0,0,0"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,0,0,8">
|
||||
<Button Style="{StaticResource AccentButtonStyle}" Command="{x:Bind ViewModel.RestartCommand}" Visibility="{x:Bind ViewModel.SelectedPlugin.RestartRequired,Mode=OneWay,Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<FontIcon Glyph="" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="重启应用" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource AccentButtonStyle}" Command="{x:Bind ViewModel.InstallPluginCommand}" Visibility="{x:Bind ViewModel.SelectedPlugin,Mode=OneWay,Converter={StaticResource PluginLoadStatusToVisibilityConverter},ConverterParameter=NotLoaded}">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<FontIcon Glyph="" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="下载" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{x:Bind ViewModel.UninstallPluginCommand}" Visibility="{x:Bind ViewModel.SelectedPlugin,Mode=OneWay,Converter={StaticResource PluginLoadStatusToVisibilityConverter},ConverterParameter=Loaded}">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<FontIcon Glyph="" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="卸载" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{x:Bind ViewModel.CancelUninstallPluginCommand}" Visibility="{x:Bind ViewModel.SelectedPlugin.IsUninstalling,Mode=OneWay,Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<FontIcon Glyph="" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="撤销" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<ProgressBar Value="{x:Bind ViewModel.SelectedPlugin.DownloadProgress,Mode=OneWay}" Visibility="{x:Bind ViewModel.SelectedPlugin.DownloadProgress,Mode=OneWay,Converter={StaticResource IntToVisibilityConverter},ConverterParameter=false}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<TextBlock Text="{x:Bind ViewModel.SelectedPlugin.Manifest.Description,Mode=OneWay}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
||||
14
CRSim/Views/PluginManagementPage.xaml.cs
Normal file
14
CRSim/Views/PluginManagementPage.xaml.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CRSim.Views;
|
||||
|
||||
public sealed partial class PluginManagementPage : Page
|
||||
{
|
||||
public PluginManagementPageViewModel ViewModel { get; } = App.AppHost.Services.GetService<PluginManagementPageViewModel>();
|
||||
|
||||
public PluginManagementPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,10 @@
|
||||
<controls:SettingsCard Header="密钥" Description="用于解锁特定功能" HeaderIcon="{winui:FontIcon Glyph=}">
|
||||
<TextBox Width="168" Text="{x:Bind ViewModel.UserKey, Mode=TwoWay}"/>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="插件市场API" Description="插件市场资源源,重启应用生效" HeaderIcon="{winui:FontIcon Glyph=}">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.Apis}" SelectedItem="{x:Bind ViewModel.ApiUri,Mode=TwoWay}"
|
||||
DisplayMemberPath="Title" Width="168"/>
|
||||
</controls:SettingsCard>
|
||||
</StackPanel>
|
||||
<TextBlock Text="引导屏模拟" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Margin="0,0,0,12"/>
|
||||
<StackPanel Spacing="4" Margin="0,0,0,24">
|
||||
|
||||
Reference in New Issue
Block a user