mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
use binding proxy to replace property
This commit is contained in:
@@ -13,8 +13,8 @@
|
||||
<!--Modify Window title bar color-->
|
||||
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush" />
|
||||
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush" />
|
||||
<StaticResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<StaticResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<ThemeResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
<ThemeResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||
|
||||
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI.UI;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
@@ -31,6 +32,7 @@ public partial class App : Application
|
||||
// load app resource
|
||||
InitializeComponent();
|
||||
InitializeDependencyInjection();
|
||||
InitializeImageCache();
|
||||
|
||||
logger = Ioc.Default.GetRequiredService<ILogger<App>>();
|
||||
UnhandledException += AppUnhandledException;
|
||||
@@ -69,10 +71,11 @@ public partial class App : Application
|
||||
Window = Ioc.Default.GetRequiredService<MainWindow>();
|
||||
Window.Activate();
|
||||
|
||||
logger.LogInformation("Image cache folder : {folder}", Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
|
||||
logger.LogInformation("Cache folder : {folder}", Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
|
||||
|
||||
if (Ioc.Default.GetRequiredService<IMetadataService>() is IMetadataInitializer initializer)
|
||||
{
|
||||
initializer.InitializeInternalAsync().SafeForget();
|
||||
initializer.InitializeInternalAsync().SafeForget(logger: logger);
|
||||
}
|
||||
|
||||
if (uri != null)
|
||||
@@ -104,6 +107,12 @@ public partial class App : Application
|
||||
Ioc.Default.ConfigureServices(services);
|
||||
}
|
||||
|
||||
private static void InitializeImageCache()
|
||||
{
|
||||
ImageCache.Instance.CacheDuration = TimeSpan.FromDays(30);
|
||||
ImageCache.Instance.RetryCount = 3;
|
||||
}
|
||||
|
||||
private void AppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||
{
|
||||
logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常");
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Snap.Hutao.Control;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定探针
|
||||
/// 用于处理特定情况下需要穿透数据上下文的工作
|
||||
/// </summary>
|
||||
public class BindingProxy : DependencyObject
|
||||
{
|
||||
|
||||
@@ -14,12 +14,6 @@ namespace Snap.Hutao.Control.Image;
|
||||
/// </summary>
|
||||
public class CachedImage : ImageEx
|
||||
{
|
||||
static CachedImage()
|
||||
{
|
||||
ImageCache.Instance.CacheDuration = TimeSpan.FromDays(30);
|
||||
ImageCache.Instance.RetryCount = 3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的缓存图像
|
||||
/// </summary>
|
||||
|
||||
@@ -27,6 +27,7 @@ public class DescriptionTextBlock : ContentControl
|
||||
/// </summary>
|
||||
public DescriptionTextBlock()
|
||||
{
|
||||
IsTabStop = false;
|
||||
Content = new TextBlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,5 +16,10 @@ internal static class EventIds
|
||||
/// <summary>
|
||||
/// 未处理的异常
|
||||
/// </summary>
|
||||
public static readonly EventId UnhandledException = new(100000, nameof(UnhandledException));
|
||||
}
|
||||
public static readonly EventId UnhandledException = new(100001, nameof(UnhandledException));
|
||||
|
||||
/// <summary>
|
||||
/// Forget任务执行异常
|
||||
/// </summary>
|
||||
public static readonly EventId TaskException = new(100002, nameof(TaskException));
|
||||
}
|
||||
@@ -42,9 +42,12 @@ internal static class Property<TOwner>
|
||||
/// <param name="defaultValue">默认值</param>
|
||||
/// <param name="callback">属性更改回调</param>
|
||||
/// <returns>注册的依赖属性</returns>
|
||||
public static DependencyProperty Depend<TProperty>(string name, TProperty defaultValue, PropertyChangedCallback callback)
|
||||
public static DependencyProperty Depend<TProperty>(
|
||||
string name,
|
||||
TProperty defaultValue,
|
||||
Action<DependencyObject, DependencyPropertyChangedEventArgs> callback)
|
||||
{
|
||||
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new(defaultValue, callback));
|
||||
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new(defaultValue, new(callback)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -75,10 +78,14 @@ internal static class Property<TOwner>
|
||||
/// </summary>
|
||||
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||
/// <param name="name">属性名称</param>
|
||||
/// <param name="defaultValue">默认值</param>
|
||||
/// <param name="callback">属性更改回调</param>
|
||||
/// <returns>注册的附加属性</returns>
|
||||
public static DependencyProperty Attach<TProperty>(string name, PropertyChangedCallback callback)
|
||||
public static DependencyProperty Attach<TProperty>(
|
||||
string name,
|
||||
TProperty defaultValue,
|
||||
Action<DependencyObject, DependencyPropertyChangedEventArgs> callback)
|
||||
{
|
||||
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new(callback));
|
||||
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new(defaultValue, new(callback)));
|
||||
}
|
||||
}
|
||||
@@ -9,14 +9,11 @@ namespace Snap.Hutao.Core;
|
||||
/// 检测 WebView2运行时 是否存在
|
||||
/// 不再使用注册表检查方式
|
||||
/// </summary>
|
||||
internal class WebView2Helper
|
||||
internal abstract class WebView2Helper
|
||||
{
|
||||
private static bool hasEverDetected = false;
|
||||
private static bool isSupported = false;
|
||||
|
||||
private WebView2Helper()
|
||||
{
|
||||
}
|
||||
private static string version = "未检测到 WebView2 运行时";
|
||||
|
||||
/// <summary>
|
||||
/// 检测 WebView2 是否存在
|
||||
@@ -35,7 +32,7 @@ internal class WebView2Helper
|
||||
isSupported = true;
|
||||
try
|
||||
{
|
||||
string version = CoreWebView2Environment.GetAvailableBrowserVersionString();
|
||||
version = CoreWebView2Environment.GetAvailableBrowserVersionString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -47,4 +44,9 @@ internal class WebView2Helper
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WebView2的版本
|
||||
/// </summary>
|
||||
public static string Version => version;
|
||||
}
|
||||
21
src/Snap.Hutao/Snap.Hutao/Extension/MemoryCacheExtensions.cs
Normal file
21
src/Snap.Hutao/Snap.Hutao/Extension/MemoryCacheExtensions.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Extension;
|
||||
|
||||
/// <summary>
|
||||
/// 内存缓存扩展
|
||||
/// </summary>
|
||||
public static class MemoryCacheExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取缓存键名称
|
||||
/// </summary>
|
||||
/// <param name="className">类名</param>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>缓存</returns>
|
||||
public static string GetCacheKey(string className, string propertyName)
|
||||
{
|
||||
return $"{className}.Cache.{propertyName}";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.Logging;
|
||||
|
||||
namespace Snap.Hutao.Extension;
|
||||
|
||||
/// <summary>
|
||||
@@ -12,18 +14,19 @@ public static class TaskExtensions
|
||||
/// 安全的触发任务
|
||||
/// </summary>
|
||||
/// <param name="task">任务</param>
|
||||
/// <param name="continueOnCapturedContext">是否在捕获的上下文中继续执行</param>
|
||||
/// <param name="logger">日志器</param>
|
||||
[SuppressMessage("", "VSTHRD003")]
|
||||
[SuppressMessage("", "VSTHRD100")]
|
||||
public static async void SafeForget(this Task task, ILogger? logger = null)
|
||||
public static async void SafeForget(this Task task, bool continueOnCapturedContext = true, ILogger? logger = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await task;
|
||||
await task.ConfigureAwait(continueOnCapturedContext);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger?.LogError(e, "{caller}:{exception}", nameof(SafeForget), e.GetBaseException());
|
||||
logger?.LogError(EventIds.TaskException, e, "{caller}:{exception}", nameof(SafeForget), e.GetBaseException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,17 +9,10 @@
|
||||
Closed="MainWindowClosed">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48.8"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<view:TitleView
|
||||
Margin="48,0,0,0"
|
||||
Grid.Row="0"
|
||||
Height="44"
|
||||
x:Name="TitleBarView"/>
|
||||
<view:MainView
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"/>
|
||||
<view:MainView/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -33,10 +33,6 @@ public sealed partial class MainWindow : Window
|
||||
this.logger = logger;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
SetTitleBar(TitleBarView.DragableArea);
|
||||
|
||||
handle = WindowNative.GetWindowHandle(this);
|
||||
InitializeWindow();
|
||||
}
|
||||
@@ -53,6 +49,9 @@ public sealed partial class MainWindow : Window
|
||||
|
||||
private void InitializeWindow()
|
||||
{
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
SetTitleBar(TitleBarView.DragableArea);
|
||||
|
||||
RECT rect = RetriveWindowRect();
|
||||
if (!rect.Size.IsEmpty)
|
||||
{
|
||||
|
||||
@@ -45,10 +45,7 @@ public class FetterInfo
|
||||
/// </summary>
|
||||
public string BirthFormatted
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{BirthMonth} 月 {BirthDay} 日";
|
||||
}
|
||||
get => $"{BirthMonth} 月 {BirthDay} 日";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -13,8 +13,7 @@ public interface IAnnouncementService
|
||||
/// <summary>
|
||||
/// 异步获取游戏公告与活动,通常会进行缓存
|
||||
/// </summary>
|
||||
/// <param name="openAnnouncementUICommand">打开公告时触发的命令</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
/// <returns>公告包装器</returns>
|
||||
ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(ICommand openAnnouncementUICommand, CancellationToken cancellationToken = default);
|
||||
ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,7 +15,7 @@ namespace Snap.Hutao.Service;
|
||||
[Injection(InjectAs.Transient, typeof(IAnnouncementService))]
|
||||
internal class AnnouncementService : IAnnouncementService
|
||||
{
|
||||
private const string CacheKey = $"{nameof(AnnouncementService)}.Cache.{nameof(AnnouncementWrapper)}";
|
||||
private static readonly string CacheKey = MemoryCacheExtensions.GetCacheKey(nameof(AnnouncementService), nameof(AnnouncementWrapper));
|
||||
|
||||
private readonly AnnouncementClient announcementClient;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
@@ -31,12 +32,12 @@ internal class AnnouncementService : IAnnouncementService
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(ICommand openAnnouncementUICommand, CancellationToken cancellationToken = default)
|
||||
public async ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
// 缓存中存在记录,直接返回
|
||||
if (memoryCache.TryGetValue(CacheKey, out object? cache))
|
||||
{
|
||||
return Must.NotNull((cache as AnnouncementWrapper)!);
|
||||
return Must.NotNull((AnnouncementWrapper)cache);
|
||||
}
|
||||
|
||||
AnnouncementWrapper? wrapper = await announcementClient
|
||||
@@ -55,30 +56,27 @@ internal class AnnouncementService : IAnnouncementService
|
||||
wrapper.List.Reverse();
|
||||
|
||||
// 将公告内容联入公告列表
|
||||
JoinAnnouncements(openAnnouncementUICommand, contentMap, wrapper.List);
|
||||
JoinAnnouncements(contentMap, wrapper.List);
|
||||
|
||||
return memoryCache.Set(CacheKey, wrapper, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
|
||||
private static void JoinAnnouncements(ICommand openAnnouncementUICommand, Dictionary<int, string> contentMap, List<AnnouncementListWrapper> announcementListWrappers)
|
||||
private static void JoinAnnouncements(Dictionary<int, string> contentMap, List<AnnouncementListWrapper> announcementListWrappers)
|
||||
{
|
||||
// 匹配特殊的时间格式: <t>(.*?)</t>
|
||||
Regex timeTagRegrex = new("<t.*?>(.*?)</t>", RegexOptions.Multiline);
|
||||
|
||||
Regex timeTagInnerRegex = new("(?<=<t.*?>)(.*?)(?=</t>)");
|
||||
|
||||
announcementListWrappers.ForEach(listWrapper =>
|
||||
{
|
||||
listWrapper.List?.ForEach(item =>
|
||||
listWrapper.List.ForEach(item =>
|
||||
{
|
||||
if (contentMap.TryGetValue(item.AnnId, out string? rawContent))
|
||||
{
|
||||
// remove <t/> tag
|
||||
rawContent = timeTagRegrex.Replace(rawContent!, x => timeTagInnerRegex.Match(x.Value).Value);
|
||||
rawContent = timeTagRegrex.Replace(rawContent!, x => x.Groups[1].Value);
|
||||
}
|
||||
|
||||
item.Content = rawContent ?? string.Empty;
|
||||
item.OpenAnnouncementUICommand = openAnnouncementUICommand;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Behaviors" Version="7.1.2" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Media" Version="7.1.2" />
|
||||
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.5.1" />
|
||||
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" />
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
xmlns:view="using:Snap.Hutao.View"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
|
||||
<Thickness x:Key="NavigationViewContentMargin">0,44,0,0</Thickness>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<NavigationView
|
||||
|
||||
@@ -16,7 +16,7 @@ public sealed partial class AnnouncementContentPage : Microsoft.UI.Xaml.Controls
|
||||
{
|
||||
// support click open browser.
|
||||
private const string MihoyoSDKDefinition =
|
||||
@"window.miHoYoGameJSSDK = {
|
||||
@"window.miHoYoGameJSSDK = {
|
||||
openInBrowser: function(url){ window.chrome.webview.postMessage(url); },
|
||||
openInWebview: function(url){ location.href = url }}";
|
||||
|
||||
@@ -25,7 +25,6 @@ openInWebview: function(url){ location.href = url }}";
|
||||
/// <summary>
|
||||
/// 构造一个新的公告窗体
|
||||
/// </summary>
|
||||
/// <param name="content">要展示的内容</param>
|
||||
public AnnouncementContentPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -43,7 +42,7 @@ openInWebview: function(url){ location.href = url }}";
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadAnnouncementAsync(INavigationData extra)
|
||||
private async Task LoadAnnouncementAsync(INavigationData data)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -54,11 +53,11 @@ openInWebview: function(url){ location.href = url }}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
extra.NotifyNavigationException(ex);
|
||||
data.NotifyNavigationException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
WebView.NavigateToString(targetContent);
|
||||
extra.NotifyNavigationCompleted();
|
||||
data.NotifyNavigationCompleted();
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,9 @@
|
||||
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
|
||||
xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters"
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shca="using:Snap.Hutao.Control.Animation"
|
||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||
xmlns:shcc="using:Snap.Hutao.Control.Cancellable"
|
||||
@@ -25,6 +26,8 @@
|
||||
<shcc:CancellablePage.Resources>
|
||||
<cwuconv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
<shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
|
||||
|
||||
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
||||
</shcc:CancellablePage.Resources>
|
||||
<Grid>
|
||||
<ScrollViewer Padding="0,0,4,0">
|
||||
@@ -152,7 +155,7 @@
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Tapped">
|
||||
<mxic:InvokeCommandAction
|
||||
Command="{Binding OpenAnnouncementUICommand}"
|
||||
Command="{Binding DataContext.OpenAnnouncementUICommand,Source={StaticResource BindingProxy}}"
|
||||
CommandParameter="{Binding Content}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
||||
|
||||
@@ -27,9 +27,9 @@ public sealed partial class AnnouncementPage : CancellablePage
|
||||
{
|
||||
base.OnNavigatedTo(e);
|
||||
|
||||
if (e.Parameter is INavigationData extra)
|
||||
if (e.Parameter is INavigationData data)
|
||||
{
|
||||
extra.NotifyNavigationCompleted();
|
||||
data.NotifyNavigationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ public sealed partial class SettingPage : Microsoft.UI.Xaml.Controls.Page
|
||||
{
|
||||
base.OnNavigatedTo(e);
|
||||
|
||||
if (e.Parameter is INavigationData extra)
|
||||
if (e.Parameter is INavigationData data)
|
||||
{
|
||||
extra.NotifyNavigationCompleted();
|
||||
data.NotifyNavigationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:cwum="using:CommunityToolkit.WinUI.UI.Media"
|
||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
@@ -43,12 +44,14 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<shct:DescriptionTextBlock
|
||||
Margin="16,16,16,0"
|
||||
Grid.Column="0"
|
||||
MaxWidth="280"
|
||||
Margin="16"
|
||||
Description="{Binding Description}">
|
||||
<shct:DescriptionTextBlock.Resources>
|
||||
<Style
|
||||
@@ -59,7 +62,7 @@
|
||||
</shct:DescriptionTextBlock.Resources>
|
||||
</shct:DescriptionTextBlock>
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalScrollMode="Disabled"
|
||||
HorizontalScrollBarVisibility="Auto">
|
||||
<Grid
|
||||
@@ -195,16 +198,16 @@
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<shci:CachedImage
|
||||
<BitmapIcon
|
||||
Grid.Column="0"
|
||||
Width="27.2"
|
||||
Height="27.2"
|
||||
Source="{Binding Selected.FetterInfo.VisionBefore,Converter={StaticResource ElementNameIconConverter}}"/>
|
||||
<shci:CachedImage
|
||||
UriSource="{Binding Selected.FetterInfo.VisionBefore,Converter={StaticResource ElementNameIconConverter}}"/>
|
||||
<BitmapIcon
|
||||
Grid.Column="1"
|
||||
Width="27.2"
|
||||
Height="27.2"
|
||||
Source="{Binding Selected.Weapon,Converter={StaticResource WeaponTypeIconConverter}}"/>
|
||||
UriSource="{Binding Selected.Weapon,Converter={StaticResource WeaponTypeIconConverter}}"/>
|
||||
</Grid>
|
||||
<shvc:ItemIcon
|
||||
Height="100"
|
||||
@@ -395,93 +398,11 @@
|
||||
ItemsSource="{Binding Selected.SkillDepot.Skills}"
|
||||
ItemTemplate="{StaticResource SkillDataTemplate}"/>
|
||||
|
||||
<!--元素爆发-->
|
||||
<Expander
|
||||
Margin="16,16,0,0"
|
||||
Header="{Binding Name}"
|
||||
DataContext="{Binding Selected.SkillDepot.EnergySkill}"
|
||||
<ContentControl
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<shct:DescriptionTextBlock
|
||||
Margin="16,16,16,0"
|
||||
Description="{Binding Description}">
|
||||
<shct:DescriptionTextBlock.Resources>
|
||||
<Style
|
||||
TargetType="TextBlock"
|
||||
BasedOn="{StaticResource BodyTextBlockStyle}">
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
</shct:DescriptionTextBlock.Resources>
|
||||
</shct:DescriptionTextBlock>
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
VerticalScrollMode="Disabled"
|
||||
HorizontalScrollBarVisibility="Auto">
|
||||
<Grid>
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
Margin="16"
|
||||
DataContext="{Binding Proud,Converter={StaticResource DescParamDescriptor}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<ItemsControl
|
||||
Grid.Row="0"
|
||||
ItemsSource="{Binding Descriptions}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<cwuc:UniformGrid
|
||||
ColumnSpacing="16"
|
||||
Columns="{Binding Descriptions.Count}"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock
|
||||
Text="{Binding}"
|
||||
TextWrapping="NoWrap"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Style="{StaticResource BaseTextBlockStyle}"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<ItemsControl
|
||||
Margin="0,6,0,0"
|
||||
Grid.Row="2"
|
||||
ItemsSource="{Binding Parameters}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ItemsControl ItemsSource="{Binding}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<cwuc:UniformGrid
|
||||
ColumnSpacing="16"
|
||||
Columns="{Binding Count}"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock
|
||||
Text="{Binding}"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Expander>
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{Binding Selected.SkillDepot.EnergySkill}"
|
||||
ContentTemplate="{StaticResource SkillDataTemplate}"/>
|
||||
|
||||
<ItemsControl
|
||||
ItemsSource="{Binding Selected.SkillDepot.Inherents}"
|
||||
|
||||
@@ -26,9 +26,9 @@ public sealed partial class WikiAvatarPage : Microsoft.UI.Xaml.Controls.Page
|
||||
{
|
||||
base.OnNavigatedTo(e);
|
||||
|
||||
if (e.Parameter is INavigationData extra)
|
||||
if (e.Parameter is INavigationData data)
|
||||
{
|
||||
extra.NotifyNavigationCompleted();
|
||||
data.NotifyNavigationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Height="48.8">
|
||||
VerticalAlignment="Top"
|
||||
Height="44">
|
||||
<Grid x:Name="DragableGrid">
|
||||
<TextBlock
|
||||
Text="胡桃"
|
||||
|
||||
@@ -59,7 +59,6 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation
|
||||
public AnnouncementWrapper? Announcement
|
||||
{
|
||||
get => announcement;
|
||||
|
||||
set => SetProperty(ref announcement, value);
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation
|
||||
{
|
||||
try
|
||||
{
|
||||
Announcement = await announcementService.GetAnnouncementsAsync(OpenAnnouncementUICommand, CancellationToken);
|
||||
Announcement = await announcementService.GetAnnouncementsAsync(CancellationToken);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
||||
@@ -12,11 +12,6 @@ public class Announcement : AnnouncementContent
|
||||
{
|
||||
private double timePercent;
|
||||
|
||||
/// <summary>
|
||||
/// 启动展示窗口的命令
|
||||
/// </summary>
|
||||
public ICommand? OpenAnnouncementUICommand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否应展示时间
|
||||
/// </summary>
|
||||
|
||||
@@ -38,8 +38,7 @@ public struct PlayerUid
|
||||
{
|
||||
get
|
||||
{
|
||||
region ??= EvaluateRegion(Value[0]);
|
||||
return region;
|
||||
return region ??= EvaluateRegion(Value[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +52,7 @@ public struct PlayerUid
|
||||
'7' => "os_euro", // 欧服
|
||||
'8' => "os_asia", // 亚服
|
||||
'9' => "os_cht", // 台服
|
||||
_ => Must.NeverHappen<string>(),
|
||||
_ => throw Must.NeverHappen(),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user