mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
finish suggestion methods
This commit is contained in:
@@ -41,12 +41,14 @@ internal class ScopedPage : Page
|
||||
/// 应当在 InitializeComponent() 前调用
|
||||
/// </summary>
|
||||
/// <typeparam name="TViewModel">视图模型类型</typeparam>
|
||||
protected void InitializeWith<TViewModel>()
|
||||
protected TViewModel InitializeWith<TViewModel>()
|
||||
where TViewModel : class, IViewModel
|
||||
{
|
||||
IViewModel viewModel = currentScope.ServiceProvider.GetRequiredService<TViewModel>();
|
||||
viewModel.CancellationToken = viewCancellationTokenSource.Token;
|
||||
DataContext = viewModel;
|
||||
|
||||
return (TViewModel)viewModel;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -73,6 +73,13 @@
|
||||
</shct:DescriptionTextBlock>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="SuggestionTemplate">
|
||||
<TextBlock
|
||||
Margin="12,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="AvatarListTemplate">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -266,21 +273,17 @@
|
||||
<!--<AppBarButton Icon="{shcm:FontIcon Glyph=}" Label="搜索提示"/>-->
|
||||
<AppBarElementContainer>
|
||||
<AutoSuggestBox
|
||||
x:Name="AvatarSuggestBox"
|
||||
Width="240"
|
||||
Height="36"
|
||||
Margin="6,6,6,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalContentAlignment="Center"
|
||||
ItemTemplate="{StaticResource SuggestionTemplate}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageWiKiAvatarAutoSuggestBoxPlaceHolder}"
|
||||
QueryIcon="{shcm:FontIcon Glyph=}"
|
||||
Style="{StaticResource DefaultAutoSuggestBoxStyle}"
|
||||
Text="{Binding FilterText, Mode=TwoWay}">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="QuerySubmitted">
|
||||
<mxic:InvokeCommandAction Command="{Binding FilterCommand}" CommandParameter="{Binding FilterText}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AutoSuggestBox>
|
||||
Text="{Binding FilterText, Mode=TwoWay}"/>
|
||||
</AppBarElementContainer>
|
||||
<AppBarButton
|
||||
Command="{Binding CultivateCommand}"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
@@ -17,7 +18,19 @@ internal sealed partial class WikiAvatarPage : ScopedPage
|
||||
/// </summary>
|
||||
public WikiAvatarPage()
|
||||
{
|
||||
InitializeWith<WikiAvatarViewModel>();
|
||||
WikiAvatarViewModel viewModel = InitializeWith<WikiAvatarViewModel>();
|
||||
InitializeComponent();
|
||||
|
||||
viewModel.Initialize(new AutoSuggestBoxAccessor(AvatarSuggestBox));
|
||||
}
|
||||
|
||||
private class AutoSuggestBoxAccessor : IAutoSuggestBoxAccessor
|
||||
{
|
||||
public AutoSuggestBoxAccessor(AutoSuggestBox autoSuggestBox)
|
||||
{
|
||||
AutoSuggestBox = autoSuggestBox;
|
||||
}
|
||||
|
||||
public AutoSuggestBox AutoSuggestBox { get; private set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
Source="{Binding Converter={StaticResource PropertyDescriptor}}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="SuggestionTemplate">
|
||||
<TextBlock
|
||||
Margin="12,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="WeaponListTemplate">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -132,20 +139,16 @@
|
||||
</CommandBar.Content>
|
||||
<AppBarElementContainer>
|
||||
<AutoSuggestBox
|
||||
x:Name="WeaponSuggestBox"
|
||||
Width="240"
|
||||
Height="36"
|
||||
Margin="16,6,6,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalContentAlignment="Center"
|
||||
ItemTemplate="{StaticResource SuggestionTemplate}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageWiKiWeaponAutoSuggestBoxPlaceHolder}"
|
||||
QueryIcon="{shcm:FontIcon Glyph=}"
|
||||
Text="{Binding FilterText, Mode=TwoWay}">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="QuerySubmitted">
|
||||
<mxic:InvokeCommandAction Command="{Binding FilterCommand}" CommandParameter="{Binding FilterText}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AutoSuggestBox>
|
||||
Text="{Binding FilterText, Mode=TwoWay}"/>
|
||||
</AppBarElementContainer>
|
||||
<AppBarButton
|
||||
Command="{Binding CultivateCommand}"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
@@ -17,7 +18,19 @@ internal sealed partial class WikiWeaponPage : ScopedPage
|
||||
/// </summary>
|
||||
public WikiWeaponPage()
|
||||
{
|
||||
InitializeWith<WikiWeaponViewModel>();
|
||||
WikiWeaponViewModel viewModel = InitializeWith<WikiWeaponViewModel>();
|
||||
InitializeComponent();
|
||||
|
||||
viewModel.Initialize(new AutoSuggestBoxAccessor(WeaponSuggestBox));
|
||||
}
|
||||
|
||||
private class AutoSuggestBoxAccessor : IAutoSuggestBoxAccessor
|
||||
{
|
||||
public AutoSuggestBoxAccessor(AutoSuggestBox autoSuggestBox)
|
||||
{
|
||||
AutoSuggestBox = autoSuggestBox;
|
||||
}
|
||||
|
||||
public AutoSuggestBox AutoSuggestBox { get; private set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Control;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
internal interface IAutoSuggestBoxAccessor : IXamlElementAccessor
|
||||
{
|
||||
AutoSuggestBox AutoSuggestBox { get; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
internal interface IWikiViewModelInitialization
|
||||
{
|
||||
void Initialize(IAutoSuggestBoxAccessor accessor);
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Control.Collection.AdvancedCollectionView;
|
||||
using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Entity.Primitive;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Intrinsic.Frozen;
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
@@ -17,6 +19,7 @@ using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Collections.Frozen;
|
||||
using System.Runtime.InteropServices;
|
||||
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
|
||||
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
|
||||
@@ -32,7 +35,7 @@ namespace Snap.Hutao.ViewModel.Wiki;
|
||||
[HighQuality]
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel, IWikiViewModelInitialization
|
||||
{
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly ICultivationService cultivationService;
|
||||
@@ -49,6 +52,7 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
private BaseValueInfo? baseValueInfo;
|
||||
private Dictionary<Level, Dictionary<GrowCurveType, float>>? levelAvatarCurveMap;
|
||||
private List<Promote>? promotes;
|
||||
private FrozenSet<string> availableQueries;
|
||||
|
||||
/// <summary>
|
||||
/// 角色列表
|
||||
@@ -79,6 +83,13 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
/// </summary>
|
||||
public string? FilterText { get => filterText; set => SetProperty(ref filterText, value); }
|
||||
|
||||
public void Initialize(IAutoSuggestBoxAccessor accessor)
|
||||
{
|
||||
accessor.AutoSuggestBox.TextChanged += OnFilterSuggestionRequested;
|
||||
accessor.AutoSuggestBox.SuggestionChosen += OnFilterSuggestionChosen;
|
||||
accessor.AutoSuggestBox.QuerySubmitted += ApplyFilter;
|
||||
}
|
||||
|
||||
protected override async ValueTask<bool> InitializeUIAsync()
|
||||
{
|
||||
if (!await metadataService.InitializeAsync().ConfigureAwait(false))
|
||||
@@ -101,6 +112,17 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
Avatars = new(list, true);
|
||||
Selected = Avatars.View.ElementAtOrDefault(0);
|
||||
|
||||
availableQueries = FrozenSet.ToFrozenSet<string>(
|
||||
[
|
||||
.. avatars.Select(a => a.Name),
|
||||
.. IntrinsicFrozen.AssociationTypes,
|
||||
.. IntrinsicFrozen.BodyTypes,
|
||||
.. IntrinsicFrozen.ElementNames,
|
||||
.. IntrinsicFrozen.ItemQualities,
|
||||
.. IntrinsicFrozen.WeaponTypes,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -202,21 +224,43 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
BaseValueInfo = new(avatar.MaxLevel, propertyCurveValues, levelAvatarCurveMap, avatarPromoteMap);
|
||||
}
|
||||
|
||||
[Command("FilterCommand")]
|
||||
private void ApplyFilter(string? input)
|
||||
private void OnFilterSuggestionRequested(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
{
|
||||
if (Avatars is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
if (string.IsNullOrWhiteSpace(FilterText))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
|
||||
{
|
||||
sender.ItemsSource = availableQueries.Where(q => q.Contains(FilterText, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFilterSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
|
||||
{
|
||||
sender.Text = args.SelectedItem.ToString();
|
||||
}
|
||||
|
||||
private void ApplyFilter(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||
{
|
||||
if (Avatars is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(FilterText))
|
||||
{
|
||||
Avatars.Filter = default!;
|
||||
return;
|
||||
}
|
||||
|
||||
Avatars.Filter = AvatarFilter.Compile(input);
|
||||
Avatars.Filter = AvatarFilter.Compile(FilterText);
|
||||
|
||||
if (Selected is not null && Avatars.Contains(Selected))
|
||||
{
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Control.Collection.AdvancedCollectionView;
|
||||
using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Entity.Primitive;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Intrinsic.Frozen;
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.Model.Metadata.Weapon;
|
||||
@@ -17,6 +19,7 @@ using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Collections.Frozen;
|
||||
using System.Runtime.InteropServices;
|
||||
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
|
||||
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
|
||||
@@ -29,7 +32,7 @@ namespace Snap.Hutao.ViewModel.Wiki;
|
||||
/// </summary>
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel, IWikiViewModelInitialization
|
||||
{
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly CalculateClient calculateClient;
|
||||
@@ -46,6 +49,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
private BaseValueInfo? baseValueInfo;
|
||||
private Dictionary<Level, Dictionary<GrowCurveType, float>>? levelWeaponCurveMap;
|
||||
private List<Promote>? promotes;
|
||||
private FrozenSet<string> availableQueries;
|
||||
|
||||
/// <summary>
|
||||
/// 角色列表
|
||||
@@ -76,6 +80,13 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
/// </summary>
|
||||
public string? FilterText { get => filterText; set => SetProperty(ref filterText, value); }
|
||||
|
||||
public void Initialize(IAutoSuggestBoxAccessor accessor)
|
||||
{
|
||||
accessor.AutoSuggestBox.TextChanged += OnFilterSuggestionRequested;
|
||||
accessor.AutoSuggestBox.SuggestionChosen += OnFilterSuggestionChosen;
|
||||
accessor.AutoSuggestBox.QuerySubmitted += ApplyFilter;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OpenUIAsync()
|
||||
{
|
||||
@@ -98,6 +109,14 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
|
||||
Weapons = new(list, true);
|
||||
Selected = Weapons.View.ElementAtOrDefault(0);
|
||||
|
||||
availableQueries = FrozenSet.ToFrozenSet(
|
||||
[
|
||||
.. weapons.Select(w => w.Name),
|
||||
.. IntrinsicFrozen.ItemQualities,
|
||||
.. IntrinsicFrozen.FightProperties,
|
||||
.. IntrinsicFrozen.WeaponTypes,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,21 +206,43 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
BaseValueInfo = new(weapon.MaxLevel, propertyCurveValues, levelWeaponCurveMap, weaponPromoteMap);
|
||||
}
|
||||
|
||||
[Command("FilterCommand")]
|
||||
private void ApplyFilter(string? input)
|
||||
private void OnFilterSuggestionRequested(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
{
|
||||
if (Weapons is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
if (string.IsNullOrWhiteSpace(FilterText))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
|
||||
{
|
||||
sender.ItemsSource = availableQueries.Where(q => q.Contains(FilterText, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFilterSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
|
||||
{
|
||||
sender.Text = args.SelectedItem.ToString();
|
||||
}
|
||||
|
||||
private void ApplyFilter(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||
{
|
||||
if (Weapons is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(FilterText))
|
||||
{
|
||||
Weapons.Filter = default!;
|
||||
return;
|
||||
}
|
||||
|
||||
Weapons.Filter = WeaponFilter.Compile(input);
|
||||
Weapons.Filter = WeaponFilter.Compile(FilterText);
|
||||
|
||||
if (Selected is not null && Weapons.Contains(Selected))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user