如何在C# WinForms中保留UserControl多站点数据并避免重复加载?
解决方案
核心思路
- 以站点标识作为唯一缓存键,实现不同站点数据的隔离缓存
- 点击菜单时优先检查缓存,存在则直接复用,不存在才执行加载逻辑并缓存
具体实现
方案1:缓存整个Panel实例
在主窗体类中定义缓存容器,修改菜单点击逻辑:
// 主窗体私有字段,存储各站点的ComputersPanel实例 private Dictionary<int, ComputersPanel> _panelCache = new Dictionary<int, ComputersPanel>(); // 「computers」菜单点击事件处理 if (_panelCache.TryGetValue(site, out var cachedPanel)) { ContentPanel.Controls.Clear(); ContentPanel.Controls.Add(cachedPanel); } else { var newPanel = new ComputersPanel(site); _panelCache.Add(site, newPanel); ContentPanel.Controls.Clear(); ContentPanel.Controls.Add(newPanel); }
方案2:仅缓存计算机数据(更灵活)
在ComputersPanel类内部实现数据缓存,分离数据加载与UI渲染:
public class ComputersPanel : Panel { // 静态缓存字典,按站点隔离存储数据 private static Dictionary<int, List<ComputerEntity>> _dataCache = new Dictionary<int, List<ComputerEntity>>(); private int _currentSite; public ComputersPanel(int site) { _currentSite = site; InitUI(); LoadComputersData(); } private void LoadComputersData() { if (_dataCache.TryGetValue(_currentSite, out var cachedData)) { BindDataToUI(cachedData); return; } // 从数据库加载数据 var freshData = ExecuteSQLToGetComputers(_currentSite); // 存入缓存 _dataCache.Add(_currentSite, freshData); BindDataToUI(freshData); } // 省略UI初始化、SQL查询、数据绑定的具体实现 private void InitUI() { /* ... */ } private List<ComputerEntity> ExecuteSQLToGetComputers(int site) { /* ... */ } private void BindDataToUI(List<ComputerEntity> data) { /* ... */ } }
补充说明
- 若站点数据存在更新需求,需添加缓存失效逻辑,比如数据更新后手动移除对应站点的缓存项,或定时清理过期缓存
- 多线程环境下,需使用
ConcurrentDictionary替代普通Dictionary,避免线程安全问题
内容的提问来源于stack exchange,提问作者Jordan Riley
相关产品推荐
相关产品推荐

