use binding proxy to replace property

This commit is contained in:
DismissedLight
2022-07-17 13:37:08 +08:00
parent 93da7cdac4
commit f232e072a9
27 changed files with 124 additions and 177 deletions

View File

@@ -13,8 +13,8 @@
<!--Modify Window title bar color--> <!--Modify Window title bar color-->
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush" /> <StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush" />
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush" /> <StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush" />
<StaticResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" /> <ThemeResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" /> <ThemeResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush" /> <StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI.UI;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.VisualStudio.Threading; using Microsoft.VisualStudio.Threading;
@@ -31,6 +32,7 @@ public partial class App : Application
// load app resource // load app resource
InitializeComponent(); InitializeComponent();
InitializeDependencyInjection(); InitializeDependencyInjection();
InitializeImageCache();
logger = Ioc.Default.GetRequiredService<ILogger<App>>(); logger = Ioc.Default.GetRequiredService<ILogger<App>>();
UnhandledException += AppUnhandledException; UnhandledException += AppUnhandledException;
@@ -69,10 +71,11 @@ public partial class App : Application
Window = Ioc.Default.GetRequiredService<MainWindow>(); Window = Ioc.Default.GetRequiredService<MainWindow>();
Window.Activate(); 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) if (Ioc.Default.GetRequiredService<IMetadataService>() is IMetadataInitializer initializer)
{ {
initializer.InitializeInternalAsync().SafeForget(); initializer.InitializeInternalAsync().SafeForget(logger: logger);
} }
if (uri != null) if (uri != null)
@@ -104,6 +107,12 @@ public partial class App : Application
Ioc.Default.ConfigureServices(services); 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) private void AppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
{ {
logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常"); logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常");

View File

@@ -8,6 +8,7 @@ namespace Snap.Hutao.Control;
/// <summary> /// <summary>
/// 绑定探针 /// 绑定探针
/// 用于处理特定情况下需要穿透数据上下文的工作
/// </summary> /// </summary>
public class BindingProxy : DependencyObject public class BindingProxy : DependencyObject
{ {

View File

@@ -14,12 +14,6 @@ namespace Snap.Hutao.Control.Image;
/// </summary> /// </summary>
public class CachedImage : ImageEx public class CachedImage : ImageEx
{ {
static CachedImage()
{
ImageCache.Instance.CacheDuration = TimeSpan.FromDays(30);
ImageCache.Instance.RetryCount = 3;
}
/// <summary> /// <summary>
/// 构造一个新的缓存图像 /// 构造一个新的缓存图像
/// </summary> /// </summary>

View File

@@ -27,6 +27,7 @@ public class DescriptionTextBlock : ContentControl
/// </summary> /// </summary>
public DescriptionTextBlock() public DescriptionTextBlock()
{ {
IsTabStop = false;
Content = new TextBlock(); Content = new TextBlock();
} }

View File

@@ -16,5 +16,10 @@ internal static class EventIds
/// <summary> /// <summary>
/// 未处理的异常 /// 未处理的异常
/// </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));
}

View File

@@ -42,9 +42,12 @@ internal static class Property<TOwner>
/// <param name="defaultValue">默认值</param> /// <param name="defaultValue">默认值</param>
/// <param name="callback">属性更改回调</param> /// <param name="callback">属性更改回调</param>
/// <returns>注册的依赖属性</returns> /// <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> /// <summary>
@@ -75,10 +78,14 @@ internal static class Property<TOwner>
/// </summary> /// </summary>
/// <typeparam name="TProperty">属性的类型</typeparam> /// <typeparam name="TProperty">属性的类型</typeparam>
/// <param name="name">属性名称</param> /// <param name="name">属性名称</param>
/// <param name="defaultValue">默认值</param>
/// <param name="callback">属性更改回调</param> /// <param name="callback">属性更改回调</param>
/// <returns>注册的附加属性</returns> /// <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)));
} }
} }

View File

@@ -9,14 +9,11 @@ namespace Snap.Hutao.Core;
/// 检测 WebView2运行时 是否存在 /// 检测 WebView2运行时 是否存在
/// 不再使用注册表检查方式 /// 不再使用注册表检查方式
/// </summary> /// </summary>
internal class WebView2Helper internal abstract class WebView2Helper
{ {
private static bool hasEverDetected = false; private static bool hasEverDetected = false;
private static bool isSupported = false; private static bool isSupported = false;
private static string version = "未检测到 WebView2 运行时";
private WebView2Helper()
{
}
/// <summary> /// <summary>
/// 检测 WebView2 是否存在 /// 检测 WebView2 是否存在
@@ -35,7 +32,7 @@ internal class WebView2Helper
isSupported = true; isSupported = true;
try try
{ {
string version = CoreWebView2Environment.GetAvailableBrowserVersionString(); version = CoreWebView2Environment.GetAvailableBrowserVersionString();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -47,4 +44,9 @@ internal class WebView2Helper
} }
} }
} }
}
/// <summary>
/// WebView2的版本
/// </summary>
public static string Version => version;
}

View 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}";
}
}

View File

@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved. // Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Core.Logging;
namespace Snap.Hutao.Extension; namespace Snap.Hutao.Extension;
/// <summary> /// <summary>
@@ -12,18 +14,19 @@ public static class TaskExtensions
/// 安全的触发任务 /// 安全的触发任务
/// </summary> /// </summary>
/// <param name="task">任务</param> /// <param name="task">任务</param>
/// <param name="continueOnCapturedContext">是否在捕获的上下文中继续执行</param>
/// <param name="logger">日志器</param> /// <param name="logger">日志器</param>
[SuppressMessage("", "VSTHRD003")] [SuppressMessage("", "VSTHRD003")]
[SuppressMessage("", "VSTHRD100")] [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 try
{ {
await task; await task.ConfigureAwait(continueOnCapturedContext);
} }
catch (Exception e) catch (Exception e)
{ {
logger?.LogError(e, "{caller}:{exception}", nameof(SafeForget), e.GetBaseException()); logger?.LogError(EventIds.TaskException, e, "{caller}:{exception}", nameof(SafeForget), e.GetBaseException());
} }
} }
} }

View File

@@ -9,17 +9,10 @@
Closed="MainWindowClosed"> Closed="MainWindowClosed">
<Grid> <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48.8"/>
<RowDefinition/>
</Grid.RowDefinitions>
<view:TitleView <view:TitleView
Margin="48,0,0,0" Margin="48,0,0,0"
Grid.Row="0" Height="44"
x:Name="TitleBarView"/> x:Name="TitleBarView"/>
<view:MainView <view:MainView/>
Grid.Row="0"
Grid.RowSpan="2"/>
</Grid> </Grid>
</Window> </Window>

View File

@@ -33,10 +33,6 @@ public sealed partial class MainWindow : Window
this.logger = logger; this.logger = logger;
InitializeComponent(); InitializeComponent();
ExtendsContentIntoTitleBar = true;
SetTitleBar(TitleBarView.DragableArea);
handle = WindowNative.GetWindowHandle(this); handle = WindowNative.GetWindowHandle(this);
InitializeWindow(); InitializeWindow();
} }
@@ -53,6 +49,9 @@ public sealed partial class MainWindow : Window
private void InitializeWindow() private void InitializeWindow()
{ {
ExtendsContentIntoTitleBar = true;
SetTitleBar(TitleBarView.DragableArea);
RECT rect = RetriveWindowRect(); RECT rect = RetriveWindowRect();
if (!rect.Size.IsEmpty) if (!rect.Size.IsEmpty)
{ {

View File

@@ -45,10 +45,7 @@ public class FetterInfo
/// </summary> /// </summary>
public string BirthFormatted public string BirthFormatted
{ {
get get => $"{BirthMonth} 月 {BirthDay} 日";
{
return $"{BirthMonth} 月 {BirthDay} 日";
}
} }
/// <summary> /// <summary>

View File

@@ -13,8 +13,7 @@ public interface IAnnouncementService
/// <summary> /// <summary>
/// 异步获取游戏公告与活动,通常会进行缓存 /// 异步获取游戏公告与活动,通常会进行缓存
/// </summary> /// </summary>
/// <param name="openAnnouncementUICommand">打开公告时触发的命令</param>
/// <param name="cancellationToken">取消令牌</param> /// <param name="cancellationToken">取消令牌</param>
/// <returns>公告包装器</returns> /// <returns>公告包装器</returns>
ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(ICommand openAnnouncementUICommand, CancellationToken cancellationToken = default); ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(CancellationToken cancellationToken = default);
} }

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Snap.Hutao.Extension;
using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement; using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
using System.Collections.Generic; using System.Collections.Generic;
@@ -14,7 +15,7 @@ namespace Snap.Hutao.Service;
[Injection(InjectAs.Transient, typeof(IAnnouncementService))] [Injection(InjectAs.Transient, typeof(IAnnouncementService))]
internal class AnnouncementService : 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 AnnouncementClient announcementClient;
private readonly IMemoryCache memoryCache; private readonly IMemoryCache memoryCache;
@@ -31,12 +32,12 @@ internal class AnnouncementService : IAnnouncementService
} }
/// <inheritdoc/> /// <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)) if (memoryCache.TryGetValue(CacheKey, out object? cache))
{ {
return Must.NotNull((cache as AnnouncementWrapper)!); return Must.NotNull((AnnouncementWrapper)cache);
} }
AnnouncementWrapper? wrapper = await announcementClient AnnouncementWrapper? wrapper = await announcementClient
@@ -55,30 +56,27 @@ internal class AnnouncementService : IAnnouncementService
wrapper.List.Reverse(); wrapper.List.Reverse();
// 将公告内容联入公告列表 // 将公告内容联入公告列表
JoinAnnouncements(openAnnouncementUICommand, contentMap, wrapper.List); JoinAnnouncements(contentMap, wrapper.List);
return memoryCache.Set(CacheKey, wrapper, TimeSpan.FromMinutes(30)); 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> // 匹配特殊的时间格式: <t>(.*?)</t>
Regex timeTagRegrex = new("&lt;t.*?&gt;(.*?)&lt;/t&gt;", RegexOptions.Multiline); Regex timeTagRegrex = new("&lt;t.*?&gt;(.*?)&lt;/t&gt;", RegexOptions.Multiline);
Regex timeTagInnerRegex = new("(?<=&lt;t.*?&gt;)(.*?)(?=&lt;/t&gt;)");
announcementListWrappers.ForEach(listWrapper => announcementListWrappers.ForEach(listWrapper =>
{ {
listWrapper.List?.ForEach(item => listWrapper.List.ForEach(item =>
{ {
if (contentMap.TryGetValue(item.AnnId, out string? rawContent)) if (contentMap.TryGetValue(item.AnnId, out string? rawContent))
{ {
// remove <t/> tag // 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.Content = rawContent ?? string.Empty;
item.OpenAnnouncementUICommand = openAnnouncementUICommand;
}); });
}); });
} }

View File

@@ -70,6 +70,7 @@
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" /> <PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
<PackageReference Include="CommunityToolkit.WinUI.UI.Behaviors" 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.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.Analytics" Version="4.5.1" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.1" /> <PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" />

View File

@@ -9,7 +9,7 @@
xmlns:view="using:Snap.Hutao.View" xmlns:view="using:Snap.Hutao.View"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness> <Thickness x:Key="NavigationViewContentMargin">0,44,0,0</Thickness>
</UserControl.Resources> </UserControl.Resources>
<Grid> <Grid>
<NavigationView <NavigationView

View File

@@ -16,7 +16,7 @@ public sealed partial class AnnouncementContentPage : Microsoft.UI.Xaml.Controls
{ {
// support click open browser. // support click open browser.
private const string MihoyoSDKDefinition = private const string MihoyoSDKDefinition =
@"window.miHoYoGameJSSDK = { @"window.miHoYoGameJSSDK = {
openInBrowser: function(url){ window.chrome.webview.postMessage(url); }, openInBrowser: function(url){ window.chrome.webview.postMessage(url); },
openInWebview: function(url){ location.href = url }}"; openInWebview: function(url){ location.href = url }}";
@@ -25,7 +25,6 @@ openInWebview: function(url){ location.href = url }}";
/// <summary> /// <summary>
/// 构造一个新的公告窗体 /// 构造一个新的公告窗体
/// </summary> /// </summary>
/// <param name="content">要展示的内容</param>
public AnnouncementContentPage() public AnnouncementContentPage()
{ {
InitializeComponent(); InitializeComponent();
@@ -43,7 +42,7 @@ openInWebview: function(url){ location.href = url }}";
} }
} }
private async Task LoadAnnouncementAsync(INavigationData extra) private async Task LoadAnnouncementAsync(INavigationData data)
{ {
try try
{ {
@@ -54,11 +53,11 @@ openInWebview: function(url){ location.href = url }}";
} }
catch (Exception ex) catch (Exception ex)
{ {
extra.NotifyNavigationException(ex); data.NotifyNavigationException(ex);
return; return;
} }
WebView.NavigateToString(targetContent); WebView.NavigateToString(targetContent);
extra.NotifyNavigationCompleted(); data.NotifyNavigationCompleted();
} }
} }

View File

@@ -9,8 +9,9 @@
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors" xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls" xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters" xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core" 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:shca="using:Snap.Hutao.Control.Animation"
xmlns:shcb="using:Snap.Hutao.Control.Behavior" xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shcc="using:Snap.Hutao.Control.Cancellable" xmlns:shcc="using:Snap.Hutao.Control.Cancellable"
@@ -25,6 +26,8 @@
<shcc:CancellablePage.Resources> <shcc:CancellablePage.Resources>
<cwuconv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/> <cwuconv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/> <shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
</shcc:CancellablePage.Resources> </shcc:CancellablePage.Resources>
<Grid> <Grid>
<ScrollViewer Padding="0,0,4,0"> <ScrollViewer Padding="0,0,4,0">
@@ -152,7 +155,7 @@
<mxi:Interaction.Behaviors> <mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Tapped"> <mxic:EventTriggerBehavior EventName="Tapped">
<mxic:InvokeCommandAction <mxic:InvokeCommandAction
Command="{Binding OpenAnnouncementUICommand}" Command="{Binding DataContext.OpenAnnouncementUICommand,Source={StaticResource BindingProxy}}"
CommandParameter="{Binding Content}"/> CommandParameter="{Binding Content}"/>
</mxic:EventTriggerBehavior> </mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerEntered"> <mxic:EventTriggerBehavior EventName="PointerEntered">

View File

@@ -27,9 +27,9 @@ public sealed partial class AnnouncementPage : CancellablePage
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
if (e.Parameter is INavigationData extra) if (e.Parameter is INavigationData data)
{ {
extra.NotifyNavigationCompleted(); data.NotifyNavigationCompleted();
} }
} }
} }

View File

@@ -26,9 +26,9 @@ public sealed partial class SettingPage : Microsoft.UI.Xaml.Controls.Page
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
if (e.Parameter is INavigationData extra) if (e.Parameter is INavigationData data)
{ {
extra.NotifyNavigationCompleted(); data.NotifyNavigationCompleted();
} }
} }
} }

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls" xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:cwum="using:CommunityToolkit.WinUI.UI.Media"
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core" xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
xmlns:mxi="using:Microsoft.Xaml.Interactivity" xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:shc="using:Snap.Hutao.Control" xmlns:shc="using:Snap.Hutao.Control"
@@ -43,12 +44,14 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"> HorizontalContentAlignment="Stretch">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.ColumnDefinitions>
<RowDefinition Height="auto"/> <ColumnDefinition Width="auto"/>
<RowDefinition/> <ColumnDefinition/>
</Grid.RowDefinitions> </Grid.ColumnDefinitions>
<shct:DescriptionTextBlock <shct:DescriptionTextBlock
Margin="16,16,16,0" Grid.Column="0"
MaxWidth="280"
Margin="16"
Description="{Binding Description}"> Description="{Binding Description}">
<shct:DescriptionTextBlock.Resources> <shct:DescriptionTextBlock.Resources>
<Style <Style
@@ -59,7 +62,7 @@
</shct:DescriptionTextBlock.Resources> </shct:DescriptionTextBlock.Resources>
</shct:DescriptionTextBlock> </shct:DescriptionTextBlock>
<ScrollViewer <ScrollViewer
Grid.Row="1" Grid.Column="1"
VerticalScrollMode="Disabled" VerticalScrollMode="Disabled"
HorizontalScrollBarVisibility="Auto"> HorizontalScrollBarVisibility="Auto">
<Grid <Grid
@@ -195,16 +198,16 @@
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition/> <ColumnDefinition/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<shci:CachedImage <BitmapIcon
Grid.Column="0" Grid.Column="0"
Width="27.2" Width="27.2"
Height="27.2" Height="27.2"
Source="{Binding Selected.FetterInfo.VisionBefore,Converter={StaticResource ElementNameIconConverter}}"/> UriSource="{Binding Selected.FetterInfo.VisionBefore,Converter={StaticResource ElementNameIconConverter}}"/>
<shci:CachedImage <BitmapIcon
Grid.Column="1" Grid.Column="1"
Width="27.2" Width="27.2"
Height="27.2" Height="27.2"
Source="{Binding Selected.Weapon,Converter={StaticResource WeaponTypeIconConverter}}"/> UriSource="{Binding Selected.Weapon,Converter={StaticResource WeaponTypeIconConverter}}"/>
</Grid> </Grid>
<shvc:ItemIcon <shvc:ItemIcon
Height="100" Height="100"
@@ -395,93 +398,11 @@
ItemsSource="{Binding Selected.SkillDepot.Skills}" ItemsSource="{Binding Selected.SkillDepot.Skills}"
ItemTemplate="{StaticResource SkillDataTemplate}"/> ItemTemplate="{StaticResource SkillDataTemplate}"/>
<!--元素爆发--> <ContentControl
<Expander
Margin="16,16,0,0"
Header="{Binding Name}"
DataContext="{Binding Selected.SkillDepot.EnergySkill}"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"> HorizontalContentAlignment="Stretch"
<Grid> Content="{Binding Selected.SkillDepot.EnergySkill}"
<Grid.RowDefinitions> ContentTemplate="{StaticResource SkillDataTemplate}"/>
<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>
<ItemsControl <ItemsControl
ItemsSource="{Binding Selected.SkillDepot.Inherents}" ItemsSource="{Binding Selected.SkillDepot.Inherents}"

View File

@@ -26,9 +26,9 @@ public sealed partial class WikiAvatarPage : Microsoft.UI.Xaml.Controls.Page
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
if (e.Parameter is INavigationData extra) if (e.Parameter is INavigationData data)
{ {
extra.NotifyNavigationCompleted(); data.NotifyNavigationCompleted();
} }
} }
} }

View File

@@ -6,7 +6,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" mc:Ignorable="d"
Height="48.8"> VerticalAlignment="Top"
Height="44">
<Grid x:Name="DragableGrid"> <Grid x:Name="DragableGrid">
<TextBlock <TextBlock
Text="胡桃" Text="胡桃"

View File

@@ -59,7 +59,6 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation
public AnnouncementWrapper? Announcement public AnnouncementWrapper? Announcement
{ {
get => announcement; get => announcement;
set => SetProperty(ref announcement, value); set => SetProperty(ref announcement, value);
} }
@@ -77,7 +76,7 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation
{ {
try try
{ {
Announcement = await announcementService.GetAnnouncementsAsync(OpenAnnouncementUICommand, CancellationToken); Announcement = await announcementService.GetAnnouncementsAsync(CancellationToken);
} }
catch (TaskCanceledException) catch (TaskCanceledException)
{ {

View File

@@ -12,11 +12,6 @@ public class Announcement : AnnouncementContent
{ {
private double timePercent; private double timePercent;
/// <summary>
/// 启动展示窗口的命令
/// </summary>
public ICommand? OpenAnnouncementUICommand { get; set; }
/// <summary> /// <summary>
/// 是否应展示时间 /// 是否应展示时间
/// </summary> /// </summary>

View File

@@ -38,8 +38,7 @@ public struct PlayerUid
{ {
get get
{ {
region ??= EvaluateRegion(Value[0]); return region ??= EvaluateRegion(Value[0]);
return region;
} }
} }
@@ -53,7 +52,7 @@ public struct PlayerUid
'7' => "os_euro", // 欧服 '7' => "os_euro", // 欧服
'8' => "os_asia", // 亚服 '8' => "os_asia", // 亚服
'9' => "os_cht", // 台服 '9' => "os_cht", // 台服
_ => Must.NeverHappen<string>(), _ => throw Must.NeverHappen(),
}; };
} }
} }