From 49b8561666e7fe718c8103ca508fa4fe42e3f05e Mon Sep 17 00:00:00 2001 From: iamqiz Date: Mon, 1 Apr 2024 09:38:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86ShellList=E7=94=A8=E7=9A=84=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=BC=93=E5=AD=98=E8=B5=B7=E6=9D=A5,=E5=90=8E?= =?UTF-8?q?=E7=BB=AD=E9=87=8D=E5=A4=8D=E4=BD=BF=E7=94=A8,=E6=8F=90?= =?UTF-8?q?=E9=AB=98=E5=88=87=E6=8D=A2=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=80=9F?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BluePointLilac.Controls/MyListBox.cs | 53 ++++++++++++++++++- ContextMenuManager/ContextMenuManager.csproj | 3 +- ContextMenuManager/Controls/ShellExItem.cs | 6 +++ ContextMenuManager/Controls/ShellItem.cs | 7 ++- ContextMenuManager/Controls/ShellList.cs | 37 +++++++++++-- ContextMenuManager/Methods/MyUtils.cs | 24 +++++++++ 6 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 ContextMenuManager/Methods/MyUtils.cs diff --git a/ContextMenuManager/BluePointLilac.Controls/MyListBox.cs b/ContextMenuManager/BluePointLilac.Controls/MyListBox.cs index 1aeea2a..89e55cd 100644 --- a/ContextMenuManager/BluePointLilac.Controls/MyListBox.cs +++ b/ContextMenuManager/BluePointLilac.Controls/MyListBox.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; +using ContextMenuManager.Methods; namespace BluePointLilac.Controls { @@ -42,7 +43,46 @@ public MyList() this.DoubleBuffered = true; this.AutoSizeMode = AutoSizeMode.GrowAndShrink; } - + // MyList 基类 控件仓库(缓存) + private Dictionary> itemRepo = new Dictionary>(); + // 重置仓库的 Idx + protected void ResetRepo() + { + foreach (string className in itemRepo.Keys) + itemRepo[className].Idx = 0; + } + // 从仓库获取控件 + protected bool GetFromRepo(string itemClassName,out MyListItem ret) + { + if (itemRepo.TryGetValue(itemClassName, out MyCustomList itemlist)) + { + for (int i = itemlist.Idx; i < itemlist.Count; i++) + { + MyListItem ctr = itemlist[i]; + if (ctr.Parent == null) + { + ret = ctr; + itemlist.Idx = i + 1; + return true; + } + } + itemlist.Idx = itemlist.Count; + } + ret = null; + return false; + } + // 保存控件到缓存 + protected void SaveToRepo(string itemClassName,MyListItem ctr) + { + if (!itemRepo.TryGetValue(itemClassName, out MyCustomList itemlist)||itemlist==null) + { + itemlist = new MyCustomList(); + itemRepo[itemClassName] = itemlist; + } + itemlist.Add(ctr); + // 表示控件可重用 + ctr.Reuse = true; + } private MyListItem hoveredItem; public MyListItem HoveredItem { @@ -117,6 +157,14 @@ public virtual void ClearItems() { Control ctr = this.Controls[i]; this.Controls.Remove(ctr); + // 不销毁 Reuse=true的控件 + if (ctr is MyListItem myListItem) + { + if (myListItem.Reuse) + { + continue; + } + } ctr.Dispose(); } this.ResumeLayout(); @@ -168,7 +216,8 @@ public MyListItem() AddCtr(pnlScrollbar, 0); this.ResumeLayout(); } - + // 需要重用,不能销毁(Dispose) + public bool Reuse { get; set; } = false; public Image Image { get => picImage.Image; diff --git a/ContextMenuManager/ContextMenuManager.csproj b/ContextMenuManager/ContextMenuManager.csproj index 6482a48..0080306 100644 --- a/ContextMenuManager/ContextMenuManager.csproj +++ b/ContextMenuManager/ContextMenuManager.csproj @@ -8,7 +8,7 @@ WinExe ContextMenuManager ContextMenuManager - v4.0 + v4.8 512 true true @@ -196,6 +196,7 @@ Component + diff --git a/ContextMenuManager/Controls/ShellExItem.cs b/ContextMenuManager/Controls/ShellExItem.cs index b91bacc..25837e0 100644 --- a/ContextMenuManager/Controls/ShellExItem.cs +++ b/ContextMenuManager/Controls/ShellExItem.cs @@ -49,6 +49,12 @@ public ShellExItem(Guid guid, string regPath) this.Guid = guid; this.RegPath = regPath; } + public void ReInit(Guid guid, string regPath1) + { + // InitializeComponents(); + this.Guid = guid; + this.RegPath = regPath1; + } private string regPath; public string RegPath diff --git a/ContextMenuManager/Controls/ShellItem.cs b/ContextMenuManager/Controls/ShellItem.cs index a3b9bf3..ffffee8 100644 --- a/ContextMenuManager/Controls/ShellItem.cs +++ b/ContextMenuManager/Controls/ShellItem.cs @@ -36,7 +36,12 @@ public ShellItem(string regPath) InitializeComponents(); this.RegPath = regPath; } - + // 重新初始化 + public void ReInit(string regPath1) + { + // InitializeComponents(); + this.RegPath = regPath1; + } private string regPath; public string RegPath { diff --git a/ContextMenuManager/Controls/ShellList.cs b/ContextMenuManager/Controls/ShellList.cs index f573761..bcda347 100644 --- a/ContextMenuManager/Controls/ShellList.cs +++ b/ContextMenuManager/Controls/ShellList.cs @@ -171,9 +171,37 @@ private static string CurrentExtensionPerceivedType private static string GetPerceivedType(string extension) => Registry.GetValue($@"{RegistryEx.CLASSES_ROOT}\{extension}", "PerceivedType", null)?.ToString(); public Scenes Scene { get; set; } - + // 获取一个实例,可能是新建的或重用的; 先从仓库(缓存)中获取,没有则新建 + private void Gen_ShellItem(out ShellItem ret,string regPath) + { + if (this.GetFromRepo("ShellItem",out MyListItem myListItem)) + { + ret = (ShellItem)myListItem; + // 更新控件信息 + ret.ReInit(regPath); + } + else + { + ret = new ShellItem(regPath); + this.SaveToRepo("ShellItem", ret); + } + } + private void Gen_ShellExItem(out ShellExItem ret,Guid guid, string regPath) + { + if (this.GetFromRepo("ShellExItem",out MyListItem myListItem)) + { + ret = (ShellExItem)myListItem; + ret.ReInit(guid,regPath); + } + else + { + ret = new ShellExItem(guid,regPath); + this.SaveToRepo( "ShellExItem", ret); + } + } public void LoadItems() { + ResetRepo(); string scenePath = null; switch(Scene) { @@ -296,7 +324,9 @@ private void LoadShellItems(string shellPath) RegTrustedInstaller.TakeRegTreeOwnerShip(shellKey.Name); foreach(string keyName in shellKey.GetSubKeyNames()) { - this.AddItem(new ShellItem($@"{shellPath}\{keyName}")); + // this.AddItem(new ShellItem($@"{shellPath}\{keyName}")); + this.Gen_ShellItem(out ShellItem shellItem,$@"{shellPath}\{keyName}"); + this.AddItem(shellItem); } } } @@ -321,7 +351,8 @@ private void LoadShellExItems(string shellExPath) string keyName = RegistryEx.GetKeyName(path); if(!names.Contains(keyName)) { - ShellExItem item = new ShellExItem(dic[path], path); + // ShellExItem item = new ShellExItem(dic[path], path); + this.Gen_ShellExItem(out ShellExItem item, dic[path], path); if(groupItem != null) { item.FoldGroupItem = groupItem; diff --git a/ContextMenuManager/Methods/MyUtils.cs b/ContextMenuManager/Methods/MyUtils.cs new file mode 100644 index 0000000..88dbf5f --- /dev/null +++ b/ContextMenuManager/Methods/MyUtils.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace ContextMenuManager.Methods +{ + // List带一个Idx属性 + public class MyCustomList: List + { + + public MyCustomList():base(100) + { + } + public MyCustomList(int n):base(n) + { + } + // 列表迭代时起点索引 + private int idx=0; + + public int Idx + { + get => idx; + set => idx = value; + } + } +} \ No newline at end of file