From 001270e4adbd1a26717480c83fc445037ab7865a Mon Sep 17 00:00:00 2001 From: BookerLiu Date: Tue, 2 Aug 2022 17:28:09 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20=E4=BC=98=E5=8C=96=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=9D=A1=E5=8A=A8=E7=94=BB=20:boom:=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=A7=A6=E5=BA=95=E5=88=87=E6=8D=A2=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Constant/RunTimeStatus.cs | 18 ++ Constant/WidthTypeEnum.cs | 15 ++ .../PannelCard/LeftCardControl.xaml.cs | 47 ++-- .../PannelCard/RightCardControl.xaml | 201 ++++++++++----- .../PannelCard/RightCardControl.xaml.cs | 238 +++++++++++++++++- Converts/GetWidthByWWConvert.cs | 40 +++ Converts/SearchResWidth.cs | 29 --- GeekDesk.csproj | 4 +- MainWindow.xaml.cs | 5 + Update.json | 2 +- Util/ListBoxDragDropManager.cs | 1 + Util/ScrollUtil.cs | 75 ++++++ 12 files changed, 561 insertions(+), 114 deletions(-) create mode 100644 Constant/WidthTypeEnum.cs create mode 100644 Converts/GetWidthByWWConvert.cs delete mode 100644 Converts/SearchResWidth.cs create mode 100644 Util/ScrollUtil.cs diff --git a/Constant/RunTimeStatus.cs b/Constant/RunTimeStatus.cs index 82df63b..ffb5b27 100644 --- a/Constant/RunTimeStatus.cs +++ b/Constant/RunTimeStatus.cs @@ -40,5 +40,23 @@ /// public static bool IS_MENU_EDIT = false; + + /// + /// 图标card 鼠标滚轮是否正在工作 + /// 用来控制popup的显示 否则低性能机器会造成卡顿 + /// + public static bool ICONLIST_MOUSE_WHEEL = false; + /// + /// 控制多少毫秒后 关闭(ICONLIST_MOUSE_WHEEL)鼠标滚轮运行状态 + /// + public static int MOUSE_WHEEL_WAIT_MS = 100; + /// + /// 与关闭popup 配合使用, 避免线程结束后不显示popup + /// + public static bool MOUSE_ENTER_ICON = false; + /// + /// 控制每次刷新搜索结果 鼠标移动后显示popup + /// + public static int MOUSE_MOVE_COUNT = 0; } } diff --git a/Constant/WidthTypeEnum.cs b/Constant/WidthTypeEnum.cs new file mode 100644 index 0000000..0c032f8 --- /dev/null +++ b/Constant/WidthTypeEnum.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GeekDesk.Constant +{ + public enum WidthTypeEnum + { + LEFT_CARD = 0, //左侧托盘宽度 + RIGHT_CARD = 1, //右侧托盘宽度 + RIGHT_CARD_HALF = 2 //右侧托盘宽度的一半 + } +} diff --git a/Control/UserControls/PannelCard/LeftCardControl.xaml.cs b/Control/UserControls/PannelCard/LeftCardControl.xaml.cs index 28da321..8107ec3 100644 --- a/Control/UserControls/PannelCard/LeftCardControl.xaml.cs +++ b/Control/UserControls/PannelCard/LeftCardControl.xaml.cs @@ -333,7 +333,6 @@ namespace GeekDesk.Control.UserControls.PannelCard appData.AppConfig.SelectedMenuIcons = null; RunTimeStatus.SHOW_MENU_PASSWORDBOX = true; MainWindow.mainWindow.RightCard.PDDialog.Title.Text = "输入密码"; - MainWindow.mainWindow.RightCard.PDDialog.type = PasswordType.INPUT; MainWindow.mainWindow.RightCard.PDDialog.Visibility = Visibility.Visible; } else @@ -426,32 +425,46 @@ namespace GeekDesk.Control.UserControls.PannelCard private void Menu_MouseWheel(object sender, MouseWheelEventArgs e) { if (RunTimeStatus.IS_MENU_EDIT) return; + + ScrollViewer scrollViewer = ScrollUtil.FindSimpleVisualChild(MenuListBox); if (e.Delta < 0) { - int index = MenuListBox.SelectedIndex; - if (index < MenuListBox.Items.Count - 1) + //判断是否到了最底部 + if (ScrollUtil.IsBootomScrollView(scrollViewer)) { - index ++; - } else - { - index = 0; + int index = MenuListBox.SelectedIndex; + if (index < MenuListBox.Items.Count - 1) + { + index++; + } + else + { + index = 0; + } + MenuListBox.SelectedIndex = index; } - MenuListBox.SelectedIndex = index; } else if (e.Delta > 0) { - int index = MenuListBox.SelectedIndex; - if (index > 0) + if (ScrollUtil.IsTopScrollView(scrollViewer)) { - index --; + int index = MenuListBox.SelectedIndex; + if (index > 0) + { + index--; + } + else + { + index = MenuListBox.Items.Count - 1; + } + MenuListBox.SelectedIndex = index; } - else - { - index = MenuListBox.Items.Count - 1; - } - MenuListBox.SelectedIndex = index; } + + //滚动到选中项 + MenuListBox.ScrollIntoView(MenuListBox.SelectedItem); + } - + private void Menu_PreviewDragLeave(object sender, DragEventArgs e) { diff --git a/Control/UserControls/PannelCard/RightCardControl.xaml b/Control/UserControls/PannelCard/RightCardControl.xaml index ae9d41a..865ef56 100644 --- a/Control/UserControls/PannelCard/RightCardControl.xaml +++ b/Control/UserControls/PannelCard/RightCardControl.xaml @@ -6,9 +6,11 @@ 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: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}" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" > @@ -58,6 +60,25 @@ + + @@ -82,11 +103,23 @@ - + + + + + + + + + @@ -118,72 +152,95 @@ IsVisibleChanged="PDDialog_IsVisibleChanged" Margin="0,-100,0,0"/> - - - - - - - - - - - - - - - - - - - - - - + + + - - - + + + + + + + + + + + - - + + + - - - - - + - - - - - + + + + + + @@ -234,7 +292,23 @@ x:Name="SearchListBox" SelectionChanged="SearchListBox_SelectionChanged" > - + + + + + + + + + + + @@ -258,7 +332,9 @@ @@ -283,16 +359,19 @@ diff --git a/Control/UserControls/PannelCard/RightCardControl.xaml.cs b/Control/UserControls/PannelCard/RightCardControl.xaml.cs index 8de7128..38a352f 100644 --- a/Control/UserControls/PannelCard/RightCardControl.xaml.cs +++ b/Control/UserControls/PannelCard/RightCardControl.xaml.cs @@ -9,6 +9,7 @@ using System; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; +using System.Reflection; using System.Threading; using System.Windows; using System.Windows.Controls; @@ -453,8 +454,28 @@ namespace GeekDesk.Control.UserControls.PannelCard } } - private void StackPanel_MouseEnter(object sender, MouseEventArgs e) + private void MenuIcon_MouseEnter(object sender, MouseEventArgs e) { + 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; + MyPoptipContent.Text = info.Content; + MyPoptip.VerticalOffset = 30; + Thread.Sleep(100); + if (!RunTimeStatus.ICONLIST_MOUSE_WHEEL) + { + MyPoptip.IsOpen = true; + } + })); + }).Start(); + } + + double width = appData.AppConfig.ImageWidth; double height = appData.AppConfig.ImageHeight; @@ -469,12 +490,12 @@ namespace GeekDesk.Control.UserControls.PannelCard }); t.IsBackground = true; t.Start(); - } - private void StackPanel_MouseLeave(object sender, MouseEventArgs e) + private void MenuIcon_MouseLeave(object sender, MouseEventArgs e) { - + RunTimeStatus.MOUSE_ENTER_ICON = false; + MyPoptip.IsOpen = false; Thread t = new Thread(() => { this.Dispatcher.BeginInvoke(new Action(() => @@ -484,7 +505,6 @@ namespace GeekDesk.Control.UserControls.PannelCard }); t.IsBackground = true; t.Start(); - } @@ -758,6 +778,10 @@ namespace GeekDesk.Control.UserControls.PannelCard public void SearchListBoxIndexAdd() { + //控制移动后 鼠标即使在图标上也不显示popup + RunTimeStatus.MOUSE_MOVE_COUNT = 0; + MyPoptip.IsOpen = false; + if (SearchListBox.Items.Count > 0) { if (SearchListBox.SelectedIndex < SearchListBox.Items.Count - 1) @@ -769,6 +793,10 @@ namespace GeekDesk.Control.UserControls.PannelCard public void SearchListBoxIndexSub() { + //控制移动后 鼠标即使在图标上也不显示popup + RunTimeStatus.MOUSE_MOVE_COUNT = 0; + MyPoptip.IsOpen = false; + if (SearchListBox.Items.Count > 0) { if (SearchListBox.SelectedIndex > 0) @@ -818,5 +846,205 @@ namespace GeekDesk.Control.UserControls.PannelCard MainWindow.mainWindow.Focus(); } } + + /// + /// 菜单结果icon 列表鼠标滚轮预处理时间 + /// 主要使用自定义popup解决卡顿问题解决卡顿问题 + /// 以及滚动条收尾切换菜单 + /// + /// + /// + private void IconListBox_MouseWheel(object sender, MouseWheelEventArgs e) + { + + //控制在滚动时不显示popup 否则会在低GPU性能机器上造成卡顿 + 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(() => + { + MyPoptip.IsOpen = true; + })); + } + RunTimeStatus.MOUSE_WHEEL_WAIT_MS = 100; + RunTimeStatus.ICONLIST_MOUSE_WHEEL = false; + }).Start(); + } + + //修改菜单时不切换菜单 + if (RunTimeStatus.IS_MENU_EDIT) return; + + + //切换菜单 + System.Windows.Controls.ScrollViewer scrollViewer = sender as System.Windows.Controls.ScrollViewer; + if (scrollViewer == null) + { + //在card 上获取的事件 + scrollViewer = ScrollUtil.FindSimpleVisualChild(IconListBox); + } + if (e.Delta < 0) + { + int index = MainWindow.mainWindow.LeftCard.MenuListBox.SelectedIndex; + if (ScrollUtil.IsBootomScrollView(scrollViewer)) + { + if (index < MainWindow.mainWindow.LeftCard.MenuListBox.Items.Count - 1) + { + index++; + } + else + { + index = 0; + } + Console.WriteLine("进入"); + MainWindow.mainWindow.LeftCard.MenuListBox.SelectedIndex = index; + scrollViewer.ScrollToVerticalOffset(0); + } + } + else if (e.Delta > 0) + { + if (ScrollUtil.IsTopScrollView(scrollViewer)) + { + int index = MainWindow.mainWindow.LeftCard.MenuListBox.SelectedIndex; + if (index > 0) + { + index--; + } + else + { + index = MainWindow.mainWindow.LeftCard.MenuListBox.Items.Count - 1; + } + MainWindow.mainWindow.LeftCard.MenuListBox.SelectedIndex = index; + scrollViewer.ScrollToVerticalOffset(0); + } + } + + + } + + /// + /// 搜索结果icon 列表鼠标滚轮预处理时间 + /// 主要使用自定义popup解决卡顿问题解决卡顿问题 + /// + /// + /// + private void VerticalIconList_PreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + //控制在滚动时不显示popup 否则会在低GPU性能机器上造成卡顿 + 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(() => + { + MyPoptip.IsOpen = true; + })); + } + RunTimeStatus.MOUSE_WHEEL_WAIT_MS = 100; + RunTimeStatus.ICONLIST_MOUSE_WHEEL = false; + }).Start(); + } + } + + /// + /// 查询结果 ICON 鼠标进入事件 + /// + /// + /// + 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; + MyPoptipContent.Text = info.Content; + MyPoptip.VerticalOffset = 30; + Thread.Sleep(100); + if (!RunTimeStatus.ICONLIST_MOUSE_WHEEL && RunTimeStatus.MOUSE_MOVE_COUNT > 1) + { + MyPoptip.IsOpen = true; + } + })); + }).Start(); + } + } + + /// + /// 查询结果ICON鼠标离开事件 + /// + /// + /// + private void SearchIcon_MouseLeave(object sender, MouseEventArgs e) + { + RunTimeStatus.MOUSE_ENTER_ICON = false; + MyPoptip.IsOpen = false; + } + + /// + /// 查询结果ICON鼠标移动事件 + /// + /// + /// + private void SearchIcon_MouseMove(object sender, MouseEventArgs e) + { + //控制首次刷新搜索结果后, 鼠标首次移动后显示popup + RunTimeStatus.MOUSE_MOVE_COUNT++; + + //防止移动后不刷新popup content + IconInfo info = (sender as Panel).Tag as IconInfo; + MyPoptipContent.Text = info.Content; + MyPoptip.VerticalOffset = 30; + + if (RunTimeStatus.MOUSE_MOVE_COUNT > 1 && !RunTimeStatus.ICONLIST_MOUSE_WHEEL) + { + MyPoptip.IsOpen = true; + } + } + + /// + /// menu结果ICON鼠标移动事件 + /// + /// + /// + private void MenuIcon_MouseMove(object sender, MouseEventArgs e) + { + //防止移动后不刷新popup content + IconInfo info = (sender as Panel).Tag as IconInfo; + MyPoptipContent.Text = info.Content; + MyPoptip.VerticalOffset = 30; + } } } diff --git a/Converts/GetWidthByWWConvert.cs b/Converts/GetWidthByWWConvert.cs new file mode 100644 index 0000000..3469296 --- /dev/null +++ b/Converts/GetWidthByWWConvert.cs @@ -0,0 +1,40 @@ +using GeekDesk.Constant; +using GeekDesk.ViewModel; +using System; +using System.Globalization; +using System.Windows.Data; + +namespace GeekDesk.Converts +{ + /// + /// 根据主窗口width 和传入类型 获取其它宽度 + /// + class GetWidthByWWConvert : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + WidthTypeEnum type = (WidthTypeEnum)parameter; + + AppConfig config = MainWindow.appData.AppConfig; + + if (WidthTypeEnum.LEFT_CARD == type) + { + return config.MenuCardWidth; + } + else if (WidthTypeEnum.RIGHT_CARD == type) + { + return config.WindowWidth - config.MenuCardWidth; + } else if (WidthTypeEnum.RIGHT_CARD_HALF == type) + { + return (config.WindowWidth - config.MenuCardWidth) / 2; + } + + return config.WindowWidth; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + } +} diff --git a/Converts/SearchResWidth.cs b/Converts/SearchResWidth.cs deleted file mode 100644 index 48b63d4..0000000 --- a/Converts/SearchResWidth.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; - -namespace GeekDesk.Converts -{ - class SearchResWidth : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - string param = parameter as string; - if ("1".Equals(param)) - { - double menuLeftWidth = double.Parse(value.ToString()); - return MainWindow.mainWindow.Width - menuLeftWidth; - } - else - { - double menuLeftWidth = double.Parse(value.ToString()); - return (MainWindow.mainWindow.Width - menuLeftWidth) / 2; - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - return null; - } - } -} diff --git a/GeekDesk.csproj b/GeekDesk.csproj index ca8715f..6e1e2b7 100644 --- a/GeekDesk.csproj +++ b/GeekDesk.csproj @@ -172,6 +172,7 @@ + GlobalMsgNotification.xaml @@ -253,7 +254,7 @@ - + @@ -298,6 +299,7 @@ + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index c026193..4ae4b84 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -107,6 +107,11 @@ namespace GeekDesk if (!RunTimeStatus.SEARCH_BOX_SHOW) ShowSearchBox(); + //刷新搜索后 鼠标移动次数置为0 + RunTimeStatus.MOUSE_MOVE_COUNT = 0; + //隐藏popup + RightCard.MyPoptip.IsOpen = false; + string inputText = SearchBox.Text.ToLower(); RightCard.VerticalUFG.Visibility = Visibility.Collapsed; if (!string.IsNullOrEmpty(inputText)) diff --git a/Update.json b/Update.json index d479d3b..d98275d 100644 --- a/Update.json +++ b/Update.json @@ -2,7 +2,7 @@ "title": "GeekDesk版本更新", "subTitle": "V2.5.12", "msgTitle": "本次更新内容如下", - "msg": "['求Star,求Star', '添加Win11显秒插件', '崩溃问题修复', '其它已知问题修复']", + "msg": "['求Star,求Star', '添加Win11显秒插件', '崩溃问题修复', '现在在右侧栏(快捷图标区域)也可以鼠标滚轮切换菜单了', '缩放屏幕截图问题修复(感谢@1062406901提的PR)', '其它已知问题修复']", "githubUrl": "https://github.com/BookerLiu/GeekDesk/releases", "giteeUrl": "https://gitee.com/BookerLiu/GeekDesk/releases", "version": "2.5.12" diff --git a/Util/ListBoxDragDropManager.cs b/Util/ListBoxDragDropManager.cs index 5772529..c1017f3 100644 --- a/Util/ListBoxDragDropManager.cs +++ b/Util/ListBoxDragDropManager.cs @@ -490,6 +490,7 @@ namespace GeekDesk.Util return false; ListBoxItem item = this.GetListBoxItem( this.indexToSelect ); + if (item == null) return false; Rect bounds = VisualTreeHelper.GetDescendantBounds( item ); Point ptInItem = this.listBox.TranslatePoint( this.ptMouseDown, item ); diff --git a/Util/ScrollUtil.cs b/Util/ScrollUtil.cs new file mode 100644 index 0000000..c14e0da --- /dev/null +++ b/Util/ScrollUtil.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace GeekDesk.Util +{ + public class ScrollUtil + { + + public static bool IsBootomScrollView(ScrollViewer view) + { + try + { + bool isBottom = false; + double dVer = view.VerticalOffset; + double vViewport = view.ViewportHeight; + double eextent = view.ExtentHeight; + if (dVer + vViewport >= eextent) + { + isBottom = true; + } + else + { + isBottom = false; + } + return isBottom; + } catch (Exception e) + { + return false; + } + + } + + public static bool IsTopScrollView(ScrollViewer view) + { + try + { + return (int)view.VerticalOffset == 0; + } + catch (Exception e) + { + return false; + } + } + + public static T FindSimpleVisualChild(DependencyObject element) where T : class + { + try + { + while (element != null) + { + + if (element is T) + return element as T; + if (VisualTreeHelper.GetChildrenCount(element) > 0) + { + element = VisualTreeHelper.GetChild(element, 0); + } + } + return null; + } + catch (Exception e) + { + return null; + } + + } + + } +}