🚀 减少everything搜索卡顿

This commit is contained in:
BookerLiu
2023-04-13 16:39:24 +08:00
parent eba6d4770a
commit a7181f6973
10 changed files with 930 additions and 651 deletions

View File

@@ -0,0 +1,198 @@
<UserControl x:Class="GeekDesk.Control.Other.SearchResControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:GeekDesk.Control.Other"
xmlns:temp="clr-namespace:GeekDesk.ViewModel.Temp"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:cvt="clr-namespace:GeekDesk.Converts"
xmlns:cst="clr-namespace:GeekDesk.Constant"
xmlns:DraggAnimatedPanel="clr-namespace:DraggAnimatedPanel"
xmlns:xf="clr-namespace:XamlFlair;assembly=XamlFlair.WPF"
xmlns:viewmodel="clr-namespace:GeekDesk.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
>
<UserControl.Resources>
<Style x:Key="SearchListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border>
<Border.Style>
<Style TargetType="Border">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</Border.Style>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ImageStyle" TargetType="Image">
<Setter Property="Width" Value="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.ImageWidth, Mode=OneWay}"/>
<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.ImageHeight, Mode=OneWay}"/>
<Setter Property="Source" Value="{Binding BitmapImage}"/>
</Style>
<Style x:Key="ImageStyleNoWrite" TargetType="Image">
<Setter Property="Width" Value="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.ImageWidth, Mode=OneWay}"/>
<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.ImageHeight, Mode=OneWay}"/>
<Setter Property="Source" Value="{Binding BitmapImage_NoWrite}"/>
</Style>
<cvt:OpcityConvert x:Key="OpcityConvert"/>
<cvt:GetWidthByWWConvert x:Key="GetWidthByWWConvert"/>
<cvt:Visibility2BooleanConverter x:Key="Visibility2BooleanConverter"/>
</UserControl.Resources>
<Grid>
<Grid>
<WrapPanel Orientation="Horizontal"
Margin="10"
Panel.ZIndex="1"
>
<UniformGrid x:Name="VerticalUFG"
xf:Animations.Primary="{xf:Animate BasedOn={StaticResource FadeIn}, Event=Loaded}"
xf:Animations.Secondary="{xf:Animate BasedOn={StaticResource FadeOut}, Event=None}"
xf:Animations.SecondaryBinding="{Binding Visibility,
Converter={StaticResource Visibility2BooleanConverter}, ConverterParameter='reverse',
ElementName=VerticalUFG}"
>
<!--<hc:TransitioningContentControl TransitionMode="Left2RightWithFade">-->
<ListBox VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.ScrollUnit="Pixel"
ItemsSource="{Binding}"
BorderThickness="0"
Padding="0,10,0,0"
x:Name="SearchListBox"
SelectionChanged="SearchListBox_SelectionChanged"
>
<ListBox.Template>
<ControlTemplate TargetType="ListBox">
<hc:ScrollViewer
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Auto"
IsInertiaEnabled="True"
CanContentScroll="True"
PreviewMouseWheel="VerticalIconList_PreviewMouseWheel"
ScrollChanged="VerticalCard_ScrollChanged"
>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderBrush}">
<ItemsPresenter/>
</Border>
</hc:ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<ListBox.Background>
<SolidColorBrush Opacity="0"/>
</ListBox.Background>
<ListBox.Resources>
<!--<ContextMenu x:Key="IconDialog" Width="200">
<MenuItem Header="管理员方式运行" Click="IconAdminStart" Tag="{Binding}"/>
<MenuItem Header="打开文件所在位置" Click="ShowInExplore" Tag="{Binding}"/>
<MenuItem Header="添加URL项目" Click="AddUrlIcon"/>
<MenuItem Header="添加系统项目" Click="AddSystemIcon"/>
<MenuItem Header="资源管理器菜单" Click="SystemContextMenu" Tag="{Binding}"/>
<MenuItem Header="属性" Click="PropertyConfig" Tag="{Binding}"/>
</ContextMenu>-->
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource SearchListBoxItemStyle}">
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
Orientation="Vertical"
Background="#00FFFFFF"
VirtualizationMode="Recycling"
IsVirtualizing="True"
IsContainerVirtualizable="True"
VirtualizingPanel.ScrollUnit="Pixel"
Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.WindowWidth, Mode=OneWay,
Converter={StaticResource GetWidthByWWConvert},
ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD}}"
/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="8">
<Border.Style>
<Style TargetType="Border">
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="White" Opacity="0.68"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<WrapPanel Tag="{Binding}"
Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.WindowWidth, Mode=OneWay,
Converter={StaticResource GetWidthByWWConvert},
ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD_HALF}}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
hc:Poptip.HitMode="None"
hc:Poptip.Placement="BottomLeft"
Background="#00FFFFFF"
MouseEnter="SearchIcon_MouseEnter"
MouseLeave="SearchIcon_MouseLeave"
MouseLeftButtonDown="Icon_MouseLeftButtonDown"
MouseLeftButtonUp="Icon_MouseLeftButtonUp"
MouseMove="SearchIcon_MouseMove"
Margin="25,10,0,10"
>
<Image Style="{StaticResource ImageStyleNoWrite}" RenderOptions.BitmapScalingMode="HighQuality"/>
<StackPanel Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.WindowWidth, Mode=OneWay,
Converter={StaticResource GetWidthByWWConvert},
ConverterParameter={x:Static cst:WidthTypeEnum.RIGHT_CARD_HALF_TEXT}}" >
<TextBlock
Margin="10,5,0,0"
MaxHeight="40"
FontSize="13"
TextTrimming="CharacterEllipsis"
TextAlignment="Left"
VerticalAlignment="Center"
Foreground="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.TextColor}"
Text="{Binding Name}"/>
<TextBlock
Margin="10,10,0,0"
MaxHeight="40"
FontSize="11"
TextTrimming="CharacterEllipsis"
TextAlignment="Left"
VerticalAlignment="Center"
Foreground="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.AppConfig.TextColor}"
Text="{Binding Path}"/>
</StackPanel>
</WrapPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--</hc:TransitioningContentControl>-->
</UniformGrid>
</WrapPanel>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,282 @@
using GeekDesk.Constant;
using GeekDesk.Plugins.EveryThing;
using GeekDesk.Util;
using GeekDesk.ViewModel;
using GeekDesk.ViewModel.Temp;
using HandyControl.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
namespace GeekDesk.Control.Other
{
/// <summary>
/// SearchResControl.xaml 的交互逻辑
/// </summary>
public partial class SearchResControl : UserControl
{
public SearchResControl(ObservableCollection<IconInfo> iconList)
{
this.DataContext = iconList;
InitializeComponent();
}
public void SearchListBoxIndexAdd()
{
//控制移动后 鼠标即使在图标上也不显示popup
RunTimeStatus.MOUSE_MOVE_COUNT = 0;
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = false;
if (SearchListBox.Items.Count > 0)
{
if (SearchListBox.SelectedIndex < SearchListBox.Items.Count - 1)
{
SearchListBox.SelectedIndex += 1;
}
}
}
public void SearchListBoxIndexSub()
{
//控制移动后 鼠标即使在图标上也不显示popup
RunTimeStatus.MOUSE_MOVE_COUNT = 0;
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = false;
if (SearchListBox.Items.Count > 0)
{
if (SearchListBox.SelectedIndex > 0)
{
SearchListBox.SelectedIndex -= 1;
}
}
}
public void StartupSelectionItem()
{
if (SearchListBox.SelectedItem != null)
{
IconInfo icon = SearchListBox.SelectedItem as IconInfo;
if (icon.AdminStartUp)
{
ProcessUtil.StartIconApp(icon, IconStartType.ADMIN_STARTUP);
}
else
{
ProcessUtil.StartIconApp(icon, IconStartType.DEFAULT_STARTUP);
}
}
}
private void SearchListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SearchListBox.ScrollIntoView(SearchListBox.SelectedItem);
}
/// <summary>
/// 查询结果ICON鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SearchIcon_MouseMove(object sender, MouseEventArgs e)
{
//控制首次刷新搜索结果后, 鼠标首次移动后显示popup
RunTimeStatus.MOUSE_MOVE_COUNT++;
//防止移动后不刷新popup content
IconInfo info = (sender as Panel).Tag as IconInfo;
MainWindow.mainWindow.RightCard.MyPoptipContent.Text = info.Content;
MainWindow.mainWindow.RightCard.MyPoptip.VerticalOffset = 30;
if (RunTimeStatus.MOUSE_MOVE_COUNT > 1 && !RunTimeStatus.ICONLIST_MOUSE_WHEEL)
{
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = true;
}
}
/// <summary>
/// 查询结果 ICON 鼠标进入事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SearchIcon_MouseEnter(object sender, MouseEventArgs e)
{
//显示popup
RunTimeStatus.MOUSE_ENTER_ICON = true;
if (!RunTimeStatus.ICONLIST_MOUSE_WHEEL)
{
new Thread(() =>
{
this.Dispatcher.BeginInvoke(new Action(() =>
{
IconInfo info = (sender as Panel).Tag as IconInfo;
MainWindow.mainWindow.RightCard.MyPoptipContent.Text = info.Content;
MainWindow.mainWindow.RightCard.MyPoptip.VerticalOffset = 30;
Thread.Sleep(100);
if (!RunTimeStatus.ICONLIST_MOUSE_WHEEL && RunTimeStatus.MOUSE_MOVE_COUNT > 1)
{
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = true;
}
}));
}).Start();
}
}
/// <summary>
/// 查询结果ICON鼠标离开事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SearchIcon_MouseLeave(object sender, MouseEventArgs e)
{
RunTimeStatus.MOUSE_ENTER_ICON = false;
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = false;
}
/// <summary>
/// 搜索结果icon 列表鼠标滚轮预处理时间
/// 主要使用自定义popup解决卡顿问题解决卡顿问题
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void VerticalIconList_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
//控制在滚动时不显示popup 否则会在低GPU性能机器上造成卡顿
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = false;
if (RunTimeStatus.ICONLIST_MOUSE_WHEEL)
{
RunTimeStatus.MOUSE_WHEEL_WAIT_MS = 500;
}
else
{
RunTimeStatus.ICONLIST_MOUSE_WHEEL = true;
new Thread(() =>
{
while (RunTimeStatus.MOUSE_WHEEL_WAIT_MS > 0)
{
Thread.Sleep(1);
RunTimeStatus.MOUSE_WHEEL_WAIT_MS -= 1;
}
if (RunTimeStatus.MOUSE_ENTER_ICON)
{
this.Dispatcher.BeginInvoke(new Action(() =>
{
MainWindow.mainWindow.RightCard.MyPoptip.IsOpen = true;
}));
}
RunTimeStatus.MOUSE_WHEEL_WAIT_MS = 100;
RunTimeStatus.ICONLIST_MOUSE_WHEEL = false;
}).Start();
}
}
private void Icon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (MainWindow.appData.AppConfig.DoubleOpen)
{
IconClick(sender, e);
}
}
private void Icon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (!MainWindow.appData.AppConfig.DoubleOpen)
{
IconClick(sender, e);
}
}
/// <summary>
/// 图标点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IconClick(object sender, MouseButtonEventArgs e)
{
if (MainWindow.appData.AppConfig.DoubleOpen && e.ClickCount >= 2)
{
IconInfo icon = (IconInfo)((Panel)sender).Tag;
if (icon.AdminStartUp)
{
ProcessUtil.StartIconApp(icon, IconStartType.ADMIN_STARTUP);
}
else
{
ProcessUtil.StartIconApp(icon, IconStartType.DEFAULT_STARTUP);
}
}
else if (!MainWindow.appData.AppConfig.DoubleOpen && e.ClickCount == 1)
{
IconInfo icon = (IconInfo)((Panel)sender).Tag;
if (icon.AdminStartUp)
{
ProcessUtil.StartIconApp(icon, IconStartType.ADMIN_STARTUP);
}
else
{
ProcessUtil.StartIconApp(icon, IconStartType.DEFAULT_STARTUP);
}
}
}
private static volatile bool EveryThingRuning = false;
private void VerticalCard_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (MainWindow.appData.AppConfig.EnableEveryThing == true && EveryThingUtil.HasNext())
{
HandyControl.Controls.ScrollViewer sv = sender as HandyControl.Controls.ScrollViewer;
if (sv.ExtentHeight - (sv.ActualHeight + sv.VerticalOffset) < 100
&& EveryThingUtil.HasNext()
&& !EveryThingRuning)
{
EveryThingRuning = true;
MainWindow.mainWindow.RightCard.Loading_RightCard.Visibility = Visibility.Visible;
string[] split = MainWindow.mainWindow.TotalMsgBtn.Content.ToString().Split(' ');
long count = Convert.ToInt64(split[0]);
ObservableCollection<IconInfo> resList = this.DataContext as ObservableCollection<IconInfo>;
ThreadPool.QueueUserWorkItem(state =>
{
ObservableCollection<IconInfo> searchRes = EveryThingUtil.NextPage();
this.Dispatcher.Invoke(() =>
{
count += searchRes.Count;
MainWindow.mainWindow.TotalMsgBtn.Content = count + " of " + split[split.Length - 1];
foreach (IconInfo info in searchRes)
{
resList.Add(info);
}
MainWindow.mainWindow.RightCard.Loading_RightCard.Visibility = Visibility.Collapsed;
EveryThingRuning = false;
});
});
}
}
}
}
}