提交 783226c2 编写于 作者: A Anran Zhang

添加横幅显示

上级 cada8b5d
......@@ -17,6 +17,9 @@
<Compile Include="$(SolutionDir)\src\Shared\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Controls\BannerView.xaml.cs">
<DependentUpon>BannerView.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\Layout\AdaptiveLayoutState.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
......@@ -34,6 +37,7 @@
<Compile Include="Controls\Layout\FlowLayoutAnchorInfo.cs" />
<Compile Include="Controls\Layout\IFlowLayoutAlgorithmDelegates.cs" />
<Compile Include="Controls\Layout\OrientationBasedMeasures.cs" />
<Compile Include="Controls\OffsetButton.cs" />
<Compile Include="Controls\RootNavigationView.xaml.cs">
<DependentUpon>RootNavigationView.xaml</DependentUpon>
</Compile>
......@@ -163,6 +167,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\BannerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\Bili\PartitionItem.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
......
<UserControl
x:Class="Richasy.Bili.App.Controls.BannerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:bilibili="using:Richasy.Bili.Models.BiliBili"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Richasy.Bili.App.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Common">
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="{StaticResource CompactModeThresholdWidth}" />
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="WideContainer.Visibility" Value="Collapsed" />
<Setter Target="NarrowContainer.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="WideContainer" CornerRadius="{StaticResource ControlCornerRadius}">
<controls:ScrollView
x:Name="WideScrollView"
HorizontalScrollBarVisibility="Hidden"
HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Hidden"
VerticalScrollMode="Disabled"
ViewChanged="OnWideScrollViewChanged">
<controls:ItemsRepeater x:Name="BannerRepeater" ItemsSource="{x:Bind ItemsSource, Mode=OneWay}">
<controls:ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="bilibili:Banner">
<Grid x:Name="ImageContainer" CornerRadius="{StaticResource ControlCornerRadius}">
<Image
AutomationProperties.Name="{x:Bind Title}"
MaxHeight="114"
Source="{x:Bind Image}"
Stretch="Uniform"
ToolTipService.ToolTip="{x:Bind Title}" />
</Grid>
</DataTemplate>
</controls:ItemsRepeater.ItemTemplate>
<controls:ItemsRepeater.Layout>
<controls:StackLayout Orientation="Horizontal" Spacing="12" />
</controls:ItemsRepeater.Layout>
</controls:ItemsRepeater>
</controls:ScrollView>
<local:OffsetButton
x:Name="LeftOffsetButton"
HorizontalAlignment="Left"
Click="OnLeftOffsetButtonClick"
Glyph="&#xEDD9;" />
<local:OffsetButton
x:Name="RightOffsetButton"
HorizontalAlignment="Right"
Click="OnRightOffsetButtonClick"
Glyph="&#xEDDA;" />
</Grid>
<Grid x:Name="NarrowContainer" Visibility="Collapsed">
<FlipView Height="128" ItemsSource="{x:Bind ItemsSource, Mode=OneWay}">
<FlipView.ItemTemplate>
<DataTemplate x:DataType="bilibili:Banner">
<Grid x:Name="ImageContainer" CornerRadius="{StaticResource ControlCornerRadius}">
<Image
AutomationProperties.Name="{x:Bind Title}"
RenderTransformOrigin="0.5,0.5"
Source="{x:Bind Image}"
Stretch="UniformToFill"
ToolTipService.ToolTip="{x:Bind Title}" />
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Grid>
</Grid>
</UserControl>
// Copyright (c) Richasy. All rights reserved.
using Microsoft.UI.Xaml.Controls;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Richasy.Bili.App.Controls
{
/// <summary>
/// 横幅视图.
/// </summary>
public sealed partial class BannerView : UserControl
{
/// <summary>
/// 数据源的依赖属性.
/// </summary>
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(BannerView), new PropertyMetadata(null));
/// <summary>
/// Initializes a new instance of the <see cref="BannerView"/> class.
/// </summary>
public BannerView()
{
this.InitializeComponent();
this.SizeChanged += OnSizeChanged;
}
/// <summary>
/// 横幅数据源.
/// </summary>
public object ItemsSource
{
get { return (object)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
CheckOffsetButtonStatus();
}
private void CheckOffsetButtonStatus()
{
if (WideScrollView.ExtentWidth <= WideScrollView.ViewportWidth)
{
LeftOffsetButton.Visibility = RightOffsetButton.Visibility = Visibility.Collapsed;
}
else
{
LeftOffsetButton.Visibility = WideScrollView.HorizontalOffset == 0 ? Visibility.Collapsed : Visibility.Visible;
RightOffsetButton.Visibility = WideScrollView.ScrollableWidth - WideScrollView.HorizontalOffset > 0 ? Visibility.Visible : Visibility.Collapsed;
}
}
private void OnLeftOffsetButtonClick(object sender, RoutedEventArgs e)
{
var leftOffset = WideScrollView.HorizontalOffset - WideScrollView.ViewportWidth;
if (leftOffset < 0)
{
leftOffset = 0;
}
var options = new ScrollingScrollOptions(ScrollingAnimationMode.Enabled, ScrollingSnapPointsMode.Ignore);
WideScrollView.ScrollTo(leftOffset, 0, options);
}
private void OnRightOffsetButtonClick(object sender, RoutedEventArgs e)
{
var rightOffset = WideScrollView.HorizontalOffset + WideScrollView.ViewportWidth;
if (rightOffset > WideScrollView.ExtentWidth)
{
rightOffset = WideScrollView.ScrollableWidth;
}
var options = new ScrollingScrollOptions(ScrollingAnimationMode.Auto, ScrollingSnapPointsMode.Ignore);
WideScrollView.ScrollTo(rightOffset, 0, options);
}
private void OnWideScrollViewChanged(ScrollView sender, object args)
{
CheckOffsetButtonStatus();
}
}
}
// Copyright (c) Richasy. All rights reserved.
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Richasy.Bili.App.Controls
{
/// <summary>
/// 用于ScrollViewer中的偏移按钮.
/// </summary>
public class OffsetButton : Button
{
/// <summary>
/// 图标的依赖属性.
/// </summary>
public static readonly DependencyProperty GlyphProperty =
DependencyProperty.Register(nameof(Glyph), typeof(string), typeof(OffsetButton), new PropertyMetadata(string.Empty));
/// <summary>
/// 按钮图标.
/// </summary>
public string Glyph
{
get { return (string)GetValue(GlyphProperty); }
set { SetValue(GlyphProperty, value); }
}
}
}
......@@ -2,6 +2,7 @@
x:Class="Richasy.Bili.App.Pages.Overlay.PartitionDetailPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Richasy.Bili.App.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Richasy.Bili.App.Pages.Overlay"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
......@@ -9,11 +10,28 @@
xmlns:uwp="using:Richasy.Bili.ViewModels.Uwp"
mc:Ignorable="d">
<Grid Padding="{StaticResource DefaultContainerPadding}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Common">
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="{StaticResource CompactModeThresholdWidth}" />
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ContentScrollView.Padding" Value="{StaticResource NarrowContainerPadding}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel
x:Name="PartitionHeader"
HorizontalAlignment="Left"
......@@ -47,6 +65,40 @@
<muxc:NavigationViewItem Content="{x:Bind Title, Mode=OneWay}" Tag="{x:Bind SubPartitionId}" />
</DataTemplate>
</muxc:NavigationView.MenuItemTemplate>
<muxc:NavigationView.Content>
<muxc:ScrollView
x:Name="ContentScrollView"
Padding="{StaticResource DefaultContainerPadding}"
HorizontalScrollBarVisibility="Hidden"
HorizontalScrollMode="Disabled"
VerticalScrollBarVisibility="Auto">
<Grid x:Name="ContentGrid" Padding="0,12,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:BannerView
x:Name="BannerView"
VerticalAlignment="Top"
ItemsSource="{x:Bind ViewModel.CurrentSelectedSubPartition.BannerCollection, Mode=OneWay}" />
<muxc:ProgressRing
x:Name="LoadingRing"
Style="{StaticResource PageProgressRingStyle}"
Grid.RowSpan="2"
IsActive="{x:Bind ViewModel.CurrentSelectedSubPartition.IsInitializeLoading, Mode=OneWay}" />
<muxc:ProgressBar
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
IsIndeterminate="True"
Visibility="{x:Bind ViewModel.CurrentSelectedSubPartition.IsDeltaLoading, Mode=OneWay}" />
</Grid>
</muxc:ScrollView>
</muxc:NavigationView.Content>
</muxc:NavigationView>
</Grid>
</Page>
......@@ -71,14 +71,14 @@ namespace Richasy.Bili.App.Pages.Overlay
private void OnLoaded(object sender, RoutedEventArgs e)
{
ViewModel.PropertyChanged += OnViewModelPropertyChanged;
CheckCurrentSubPartition();
CheckCurrentSubPartitionAsync();
}
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ViewModel.CurrentSelectedSubPartition))
{
CheckCurrentSubPartition();
CheckCurrentSubPartitionAsync();
}
}
......@@ -99,11 +99,17 @@ namespace Richasy.Bili.App.Pages.Overlay
ViewModel.CurrentSelectedSubPartition = vm;
}
private void CheckCurrentSubPartition()
private async void CheckCurrentSubPartitionAsync()
{
var vm = ViewModel.CurrentSelectedSubPartition;
if (vm != null)
{
if (!vm.IsRequested)
{
await vm.RequestDataAsync();
}
BannerView.Visibility = vm.BannerCollection != null && vm.BannerCollection.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
if (!(DetailNavigationView.SelectedItem is SubPartitionViewModel selectedItem) || selectedItem != vm)
{
DetailNavigationView.SelectedItem = vm;
......
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Richasy.Bili.App.Controls"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
<Thickness x:Key="NavigationViewContentMargin">0</Thickness>
<Thickness x:Key="NavigationViewContentPresenterMargin">0</Thickness>
......@@ -12,4 +13,84 @@
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="IsActive" Value="True" />
</Style>
<Style TargetType="controls:OffsetButton">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Width" Value="16" />
<Setter Property="Height" Value="32" />
<Setter Property="Margin" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:OffsetButton">
<Border
x:Name="Root"
Background="{ThemeResource FlipViewNextPreviousButtonBackground}"
BorderBrush="{ThemeResource FlipViewNextPreviousButtonBorderBrush}"
BorderThickness="{ThemeResource FlipViewButtonBorderThemeThickness}"
CornerRadius="{ThemeResource ControlCornerRadius}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousArrowForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Arrow" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousArrowForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="ScaleTransform"
Storyboard.TargetProperty="ScaleX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0.016" Value="{ThemeResource FlipViewButtonScalePressed}" />
<DiscreteDoubleKeyFrame KeyTime="0:0:30" Value="{ThemeResource FlipViewButtonScalePressed}" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="ScaleTransform"
Storyboard.TargetProperty="ScaleY">
<DiscreteDoubleKeyFrame KeyTime="0:0:0.016" Value="{ThemeResource FlipViewButtonScalePressed}" />
<DiscreteDoubleKeyFrame KeyTime="0:0:30" Value="{ThemeResource FlipViewButtonScalePressed}" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<FontIcon
x:Name="Arrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{ThemeResource FlipViewButtonFontSize}"
Foreground="{ThemeResource FlipViewNextPreviousArrowForeground}"
Glyph="{TemplateBinding Glyph}"
MirroredWhenRightToLeft="True"
RenderTransformOrigin="0.5, 0.5"
UseLayoutRounding="False">
<FontIcon.RenderTransform>
<ScaleTransform x:Name="ScaleTransform" ScaleX="1" ScaleY="1" />
</FontIcon.RenderTransform>
</FontIcon>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Place dark theme resource here -->
<AcrylicBrush
x:Key="AppMaskAcrylicBrush"
FallbackColor="Black"
TintColor="#2b2b2b"
TintOpacity="0.5" />
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Place high contrast theme resource here -->
<SolidColorBrush x:Key="AppMaskAcrylicBrush" Color="{ThemeResource SystemChromeAltMediumHighColor}" />
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Place light theme resource here -->
<AcrylicBrush
x:Key="AppMaskAcrylicBrush"
FallbackColor="White"
TintColor="White"
TintOpacity="0.1" />
</ResourceDictionary>
......@@ -15,12 +15,17 @@ namespace Richasy.Bili.ViewModels.Uwp
private readonly Partition _partition;
private readonly bool _isRecommendPartition;
private readonly IResourceToolkit _resourceToolkit;
private bool _isRequested;
/// <summary>
/// 子分区Id.
/// </summary>
public int SubPartitionId => _partition.Tid;
public int SubPartitionId => _partition?.Tid ?? -1;
/// <summary>
/// 标识该分区是否已经加载过数据.
/// </summary>
[Reactive]
public bool IsRequested { get; private set; }
/// <summary>
/// 子分区名称.
......
......@@ -43,7 +43,7 @@ namespace Richasy.Bili.ViewModels.Uwp
/// <returns><see cref="Task"/>.</returns>
public async Task RequestDataAsync()
{
if (_isRequested)
if (IsRequested)
{
await DeltaRequestAsync();
}
......@@ -99,7 +99,7 @@ namespace Richasy.Bili.ViewModels.Uwp
}
IsInitializeLoading = false;
_isRequested = true;
IsRequested = true;
}
/// <summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册