♻️ 开启虚拟化防止卡顿, 增加自适应宽度

This commit is contained in:
BookerLiu
2023-04-06 20:36:20 +08:00
parent 3a18882372
commit 98f332dc2e
11 changed files with 81 additions and 57 deletions

View File

@@ -12,5 +12,7 @@ namespace GeekDesk.Constant
RIGHT_CARD = 1, //右侧托盘宽度 RIGHT_CARD = 1, //右侧托盘宽度
RIGHT_CARD_HALF = 2, //右侧托盘宽度的一半 RIGHT_CARD_HALF = 2, //右侧托盘宽度的一半
RIGHT_CARD_HALF_TEXT = 3, //右侧托盘宽度的一半 再减去左侧图像宽度 RIGHT_CARD_HALF_TEXT = 3, //右侧托盘宽度的一半 再减去左侧图像宽度
RIGHT_CARD_20 = 4, //右侧托盘宽度 - 20
RIGHT_CARD_40 = 5, //右侧托盘宽度 - 40
} }
} }

View File

@@ -8,7 +8,7 @@
xmlns:cvt="clr-namespace:GeekDesk.Converts" xmlns:cvt="clr-namespace:GeekDesk.Converts"
xmlns:cst="clr-namespace:GeekDesk.Constant" xmlns:cst="clr-namespace:GeekDesk.Constant"
xmlns:DraggAnimatedPanel="clr-namespace:DraggAnimatedPanel" xmlns:DraggAnimatedPanel="clr-namespace:DraggAnimatedPanel"
xmlns:util="clr-namespace:GeekDesk.Util" xmlns:component="clr-namespace:GeekDesk.CustomComponent.VirtualizingWrapPanel"
xmlns:xf="clr-namespace:XamlFlair;assembly=XamlFlair.WPF" xmlns:xf="clr-namespace:XamlFlair;assembly=XamlFlair.WPF"
xmlns:ot="clr-namespace:GeekDesk.Control.Other" xmlns:ot="clr-namespace:GeekDesk.Control.Other"
xmlns:viewmodel="clr-namespace:GeekDesk.ViewModel" d:DataContext="{d:DesignInstance Type=viewmodel:AppData}" xmlns:viewmodel="clr-namespace:GeekDesk.ViewModel" d:DataContext="{d:DesignInstance Type=viewmodel:AppData}"
@@ -162,18 +162,20 @@
<WrapPanel Orientation="Horizontal" <WrapPanel Orientation="Horizontal"
Margin="10" Margin="10"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsContainerVirtualizable="True"
> >
<UniformGrid x:Name="WrapUFG" xf:Animations.Primary="{xf:Animate BasedOn={StaticResource FadeInAndGrowHorizontally}, Event=Visibility}"> <UniformGrid x:Name="WrapUFG" xf:Animations.Primary="{xf:Animate BasedOn={StaticResource FadeInAndGrowHorizontally}, Event=Visibility}">
<!--<hc:TransitioningContentControl TransitionStoryboard="{StaticResource Custom3Transition3}">--> <!--<hc:TransitioningContentControl TransitionStoryboard="{StaticResource Custom3Transition3}">-->
<ListBox x:Name="IconListBox" <ListBox x:Name="IconListBox"
ItemsSource="{Binding AppConfig.SelectedMenuIcons, Mode=OneWay}" ItemsSource="{Binding AppConfig.SelectedMenuIcons, Mode=OneWay}"
BorderThickness="0" BorderThickness="0"
Padding="0,10,0,0" Padding="0,10,0,0"
ScrollViewer.CanContentScroll ="False" ScrollViewer.CanContentScroll ="True"
> VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.ScrollUnit="Pixel"
>
<ListBox.Template> <ListBox.Template>
<ControlTemplate TargetType="ListBox"> <ControlTemplate TargetType="ListBox">
<hc:ScrollViewer x:Name="WrapScroll" <hc:ScrollViewer x:Name="WrapScroll"
@@ -187,7 +189,7 @@
BorderThickness="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderBrush}"
Width="{Binding AppConfig.WindowWidth, Mode=OneWay, Width="{Binding AppConfig.WindowWidth, Mode=OneWay,
Converter={StaticResource GetWidthByWWConvert}, Converter={StaticResource GetWidthByWWConvert},
ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD}}" ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD_40}}"
> >
<ItemsPresenter/> <ItemsPresenter/>
</Border> </Border>
@@ -205,10 +207,13 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
SwapCommand="{Binding SwapCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>--> SwapCommand="{Binding SwapCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>-->
<util:VirtualizingWrapPanel <component:VirtualizingWrapPanel VirtualizationMode="Recycling"
IsVirtualizing="True"
IsContainerVirtualizable="True"
VirtualizingPanel.ScrollUnit="Pixel"
Width="{Binding AppConfig.WindowWidth, Mode=OneWay, Width="{Binding AppConfig.WindowWidth, Mode=OneWay,
Converter={StaticResource GetWidthByWWConvert}, Converter={StaticResource GetWidthByWWConvert},
ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD}}" ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD_40}}"
/> />
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ListBox.ItemsPanel> </ListBox.ItemsPanel>
@@ -291,7 +296,7 @@
<SolidColorBrush Color="#FFFFFFFF" Opacity="0"/> <SolidColorBrush Color="#FFFFFFFF" Opacity="0"/>
</hc:Card.BorderBrush> </hc:Card.BorderBrush>
<Grid> <Grid>
<WrapPanel Orientation="Horizontal" <WrapPanel Orientation="Horizontal"
Margin="10" Margin="10"
@@ -301,13 +306,16 @@
> >
<!--<hc:TransitioningContentControl TransitionMode="Left2RightWithFade">--> <!--<hc:TransitioningContentControl TransitionMode="Left2RightWithFade">-->
<ListBox ItemsSource="{Binding Source={StaticResource SearchIconList},Path=IconList, Mode=OneWay}" <ListBox ItemsSource="{Binding Source={StaticResource SearchIconList},Path=IconList, Mode=OneWay}"
VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.ScrollUnit="Pixel"
BorderThickness="0" BorderThickness="0"
Padding="0,10,0,0" Padding="0,10,0,0"
x:Name="SearchListBox" x:Name="SearchListBox"
SelectionChanged="SearchListBox_SelectionChanged" SelectionChanged="SearchListBox_SelectionChanged"
> >
<ListBox.Template> <ListBox.Template>
<ControlTemplate TargetType="ListBox"> <ControlTemplate TargetType="ListBox">
<hc:ScrollViewer <hc:ScrollViewer
@@ -351,10 +359,10 @@
<VirtualizingStackPanel <VirtualizingStackPanel
Orientation="Vertical" Orientation="Vertical"
Background="#00FFFFFF" Background="#00FFFFFF"
VirtualizationMode="Recycling"
IsVirtualizing="True" IsVirtualizing="True"
IsVirtualizingWhenGrouping="True" IsContainerVirtualizable="True"
ScrollUnit="Pixel" VirtualizingPanel.ScrollUnit="Pixel"
VirtualizationMode="Recycling"
Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.WindowWidth, Mode=OneWay, Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.WindowWidth, Mode=OneWay,
Converter={StaticResource GetWidthByWWConvert}, Converter={StaticResource GetWidthByWWConvert},
ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD}}" ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD}}"

View File

@@ -30,6 +30,9 @@ namespace GeekDesk.Converts
} else if (WidthTypeEnum.RIGHT_CARD_HALF_TEXT == type) } else if (WidthTypeEnum.RIGHT_CARD_HALF_TEXT == type)
{ {
return (config.WindowWidth - config.MenuCardWidth) * 0.618 - config.ImageWidth - 20; return (config.WindowWidth - config.MenuCardWidth) * 0.618 - config.ImageWidth - 20;
} else if (WidthTypeEnum.RIGHT_CARD_20 == type)
{
return (config.WindowWidth - config.MenuCardWidth) - 20;
} }
return config.WindowWidth; return config.WindowWidth;

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace GeekDesk.Util.WrpaPanel namespace GeekDesk.CustomComponent.VirtualizingWrapPanel
{ {
public struct ItemRange public struct ItemRange
{ {

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace GeekDesk.Util.WrpaPanel namespace GeekDesk.CustomComponent.VirtualizingWrapPanel
{ {
public enum ScrollDirection public enum ScrollDirection
{ {

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace GeekDesk.Util.WrpaPanel namespace GeekDesk.CustomComponent.VirtualizingWrapPanel
{ {
public enum SpacingMode public enum SpacingMode
{ {

View File

@@ -11,7 +11,7 @@ using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using System.Windows; using System.Windows;
namespace GeekDesk.Util.WrpaPanel namespace GeekDesk.CustomComponent.VirtualizingWrapPanel
{ {
public abstract class VirtualizingPanelBase : VirtualizingPanel, IScrollInfo public abstract class VirtualizingPanelBase : VirtualizingPanel, IScrollInfo
{ {
@@ -19,8 +19,17 @@ namespace GeekDesk.Util.WrpaPanel
public static readonly DependencyProperty MouseWheelDeltaProperty = DependencyProperty.Register(nameof(MouseWheelDelta), typeof(double), typeof(VirtualizingPanelBase), new FrameworkPropertyMetadata(48.0)); public static readonly DependencyProperty MouseWheelDeltaProperty = DependencyProperty.Register(nameof(MouseWheelDelta), typeof(double), typeof(VirtualizingPanelBase), new FrameworkPropertyMetadata(48.0));
public static readonly DependencyProperty ScrollLineDeltaItemProperty = DependencyProperty.Register(nameof(ScrollLineDeltaItem), typeof(int), typeof(VirtualizingPanelBase), new FrameworkPropertyMetadata(1)); public static readonly DependencyProperty ScrollLineDeltaItemProperty = DependencyProperty.Register(nameof(ScrollLineDeltaItem), typeof(int), typeof(VirtualizingPanelBase), new FrameworkPropertyMetadata(1));
public static readonly DependencyProperty MouseWheelDeltaItemProperty = DependencyProperty.Register(nameof(MouseWheelDeltaItem), typeof(int), typeof(VirtualizingPanelBase), new FrameworkPropertyMetadata(3)); public static readonly DependencyProperty MouseWheelDeltaItemProperty = DependencyProperty.Register(nameof(MouseWheelDeltaItem), typeof(int), typeof(VirtualizingPanelBase), new FrameworkPropertyMetadata(3));
private ScrollViewer scrollOwner;
public ScrollViewer? ScrollOwner { get; set; } public ScrollViewer GetScrollOwner()
{
return scrollOwner;
}
public void SetScrollOwner(ScrollViewer value)
{
scrollOwner = value;
}
public bool CanVerticallyScroll { get; set; } public bool CanVerticallyScroll { get; set; }
public bool CanHorizontallyScroll { get; set; } public bool CanHorizontallyScroll { get; set; }
@@ -88,7 +97,7 @@ namespace GeekDesk.Util.WrpaPanel
{ {
get get
{ {
if (_itemsOwner is null) if (ItemsOwner1 is null)
{ {
/* Use reflection to access internal method because the public /* Use reflection to access internal method because the public
* GetItemsOwner method does always return the itmes control instead * GetItemsOwner method does always return the itmes control instead
@@ -99,15 +108,15 @@ namespace GeekDesk.Util.WrpaPanel
null, null,
new Type[] { typeof(DependencyObject) }, new Type[] { typeof(DependencyObject) },
null null
)!; );
_itemsOwner = (DependencyObject)getItemsOwnerInternalMethod.Invoke(null, new object[] { this })!; ItemsOwner1 = (DependencyObject)getItemsOwnerInternalMethod.Invoke(null, new object[] { this });
} }
return _itemsOwner; return ItemsOwner1;
} }
} }
private DependencyObject? _itemsOwner; private DependencyObject _itemsOwner;
protected ReadOnlyCollection<object?> Items => ((ItemContainerGenerator)ItemContainerGenerator).Items; protected ReadOnlyCollection<object> Items => ((ItemContainerGenerator)ItemContainerGenerator).Items;
protected new IRecyclingItemContainerGenerator ItemContainerGenerator protected new IRecyclingItemContainerGenerator ItemContainerGenerator
{ {
@@ -123,7 +132,7 @@ namespace GeekDesk.Util.WrpaPanel
return _itemContainerGenerator; return _itemContainerGenerator;
} }
} }
private IRecyclingItemContainerGenerator? _itemContainerGenerator; private IRecyclingItemContainerGenerator _itemContainerGenerator;
public double ExtentWidth => Extent.Width; public double ExtentWidth => Extent.Width;
public double ExtentHeight => Extent.Height; public double ExtentHeight => Extent.Height;
@@ -141,6 +150,8 @@ namespace GeekDesk.Util.WrpaPanel
/// The range of items that a realized in viewport or cache. /// The range of items that a realized in viewport or cache.
/// </summary> /// </summary>
protected ItemRange ItemRange { get; set; } protected ItemRange ItemRange { get; set; }
public ScrollViewer ScrollOwner { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public DependencyObject ItemsOwner1 { get => _itemsOwner; set => _itemsOwner = value; }
private Visibility previousVerticalScrollBarVisibility = Visibility.Collapsed; private Visibility previousVerticalScrollBarVisibility = Visibility.Collapsed;
private Visibility previousHorizontalScrollBarVisibility = Visibility.Collapsed; private Visibility previousHorizontalScrollBarVisibility = Visibility.Collapsed;
@@ -174,7 +185,7 @@ namespace GeekDesk.Util.WrpaPanel
if (invalidateScrollInfo) if (invalidateScrollInfo)
{ {
ScrollOwner?.InvalidateScrollInfo(); GetScrollOwner()?.InvalidateScrollInfo();
} }
} }
@@ -245,20 +256,20 @@ namespace GeekDesk.Util.WrpaPanel
{ {
/* Sometimes when scrolling the scrollbar gets hidden without any reason. In this case the "IsMeasureValid" /* Sometimes when scrolling the scrollbar gets hidden without any reason. In this case the "IsMeasureValid"
* property of the ScrollOwner is false. To prevent a infinite circle the mesasure call is ignored. */ * property of the ScrollOwner is false. To prevent a infinite circle the mesasure call is ignored. */
if (ScrollOwner != null) if (GetScrollOwner() != null)
{ {
bool verticalScrollBarGotHidden = ScrollOwner.VerticalScrollBarVisibility == ScrollBarVisibility.Auto bool verticalScrollBarGotHidden = GetScrollOwner().VerticalScrollBarVisibility == ScrollBarVisibility.Auto
&& ScrollOwner.ComputedVerticalScrollBarVisibility != Visibility.Visible && GetScrollOwner().ComputedVerticalScrollBarVisibility != Visibility.Visible
&& ScrollOwner.ComputedVerticalScrollBarVisibility != previousVerticalScrollBarVisibility; && GetScrollOwner().ComputedVerticalScrollBarVisibility != previousVerticalScrollBarVisibility;
bool horizontalScrollBarGotHidden = ScrollOwner.HorizontalScrollBarVisibility == ScrollBarVisibility.Auto bool horizontalScrollBarGotHidden = GetScrollOwner().HorizontalScrollBarVisibility == ScrollBarVisibility.Auto
&& ScrollOwner.ComputedHorizontalScrollBarVisibility != Visibility.Visible && GetScrollOwner().ComputedHorizontalScrollBarVisibility != Visibility.Visible
&& ScrollOwner.ComputedHorizontalScrollBarVisibility != previousHorizontalScrollBarVisibility; && GetScrollOwner().ComputedHorizontalScrollBarVisibility != previousHorizontalScrollBarVisibility;
previousVerticalScrollBarVisibility = ScrollOwner.ComputedVerticalScrollBarVisibility; previousVerticalScrollBarVisibility = GetScrollOwner().ComputedVerticalScrollBarVisibility;
previousHorizontalScrollBarVisibility = ScrollOwner.ComputedHorizontalScrollBarVisibility; previousHorizontalScrollBarVisibility = GetScrollOwner().ComputedHorizontalScrollBarVisibility;
if (!ScrollOwner.IsMeasureValid && verticalScrollBarGotHidden || horizontalScrollBarGotHidden) if (!GetScrollOwner().IsMeasureValid && verticalScrollBarGotHidden || horizontalScrollBarGotHidden)
{ {
return availableSize; return availableSize;
} }
@@ -397,7 +408,7 @@ namespace GeekDesk.Util.WrpaPanel
offset = Extent.Height - Viewport.Height; offset = Extent.Height - Viewport.Height;
} }
Offset = new Point(Offset.X, offset); Offset = new Point(Offset.X, offset);
ScrollOwner?.InvalidateScrollInfo(); GetScrollOwner()?.InvalidateScrollInfo();
InvalidateMeasure(); InvalidateMeasure();
} }
@@ -412,7 +423,7 @@ namespace GeekDesk.Util.WrpaPanel
offset = Extent.Width - Viewport.Width; offset = Extent.Width - Viewport.Width;
} }
Offset = new Point(offset, Offset.Y); Offset = new Point(offset, Offset.Y);
ScrollOwner?.InvalidateScrollInfo(); GetScrollOwner()?.InvalidateScrollInfo();
InvalidateMeasure(); InvalidateMeasure();
} }

View File

@@ -11,9 +11,9 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows; using System.Windows;
using GeekDesk.Util.WrpaPanel; using GeekDesk.CustomComponent.VirtualizingWrapPanel;
namespace GeekDesk.Util.WrpaPanel namespace GeekDesk.CustomComponent.VirtualizingWrapPanel
{ {
public class VirtualizingWrapPanel : VirtualizingPanelBase public class VirtualizingWrapPanel : VirtualizingPanelBase
{ {
@@ -272,7 +272,7 @@ namespace GeekDesk.Util.WrpaPanel
} }
} }
private T ReadItemContainerStyle<T>(DependencyProperty property, T fallbackValue) where T : notnull private T ReadItemContainerStyle<T>(DependencyProperty property, T fallbackValue)
{ {
var value = ItemsControl.ItemContainerStyle?.Setters.OfType<Setter>() var value = ItemsControl.ItemContainerStyle?.Setters.OfType<Setter>()
.FirstOrDefault(setter => setter.Property == property)?.Value; .FirstOrDefault(setter => setter.Property == property)?.Value;

View File

@@ -270,8 +270,8 @@
<Compile Include="Converts\UpdateTypeConvert.cs" /> <Compile Include="Converts\UpdateTypeConvert.cs" />
<Compile Include="Converts\ReverseBoolConvert.cs" /> <Compile Include="Converts\ReverseBoolConvert.cs" />
<Compile Include="Converts\Visibility2BooleanConverter.cs" /> <Compile Include="Converts\Visibility2BooleanConverter.cs" />
<Compile Include="DraggAnimatedPanel\DraggAnimatedPanel.cs" /> <Compile Include="CustomComponent\DraggAnimatedPanel\DraggAnimatedPanel.cs" />
<Compile Include="DraggAnimatedPanel\DraggAnimatedPanel.Drag.cs" /> <Compile Include="CustomComponent\DraggAnimatedPanel\DraggAnimatedPanel.Drag.cs" />
<Compile Include="Converts\HideTypeConvert.cs" /> <Compile Include="Converts\HideTypeConvert.cs" />
<Compile Include="Interface\IWindowCommon.cs" /> <Compile Include="Interface\IWindowCommon.cs" />
<Compile Include="MyThread\RelativePathThread.cs" /> <Compile Include="MyThread\RelativePathThread.cs" />
@@ -324,13 +324,13 @@
<Compile Include="Util\StringUtil.cs" /> <Compile Include="Util\StringUtil.cs" />
<Compile Include="Util\SvgToGeometry.cs" /> <Compile Include="Util\SvgToGeometry.cs" />
<Compile Include="Util\UserActivityHook.cs" /> <Compile Include="Util\UserActivityHook.cs" />
<Compile Include="Util\WrpaPanel\ItemRange.cs" /> <Compile Include="CustomComponent\VirtualizingWrapPanel\ItemRange.cs" />
<Compile Include="Util\WrpaPanel\SpacingMode.cs" /> <Compile Include="CustomComponent\VirtualizingWrapPanel\SpacingMode.cs" />
<Compile Include="Util\WrpaPanel\VirtualizingPanelBase.cs" /> <Compile Include="CustomComponent\VirtualizingWrapPanel\VirtualizingPanelBase.cs" />
<Compile Include="Util\WrpaPanel\VirtualizingWrapPanel.cs" /> <Compile Include="CustomComponent\VirtualizingWrapPanel\VirtualizingWrapPanel.cs" />
<Compile Include="Util\WindowsThumbnailProvider.cs" /> <Compile Include="Util\WindowsThumbnailProvider.cs" />
<Compile Include="Util\WindowUtil.cs" /> <Compile Include="Util\WindowUtil.cs" />
<Compile Include="Util\WrpaPanel\ScrollDirection.cs" /> <Compile Include="CustomComponent\VirtualizingWrapPanel\ScrollDirection.cs" />
<Compile Include="ViewModel\AppConfig.cs" /> <Compile Include="ViewModel\AppConfig.cs" />
<Compile Include="ViewModel\AppData.cs" /> <Compile Include="ViewModel\AppData.cs" />
<Compile Include="ViewModel\GradientBGParam.cs" /> <Compile Include="ViewModel\GradientBGParam.cs" />