【WPF】從普通 ItemsControl 到支持篩選的 ItemsControl:深入掌握 CollectionViewSource 用法

? 從普通 ItemsControl 到支持篩選的 ItemsControl:深入掌握 CollectionViewSource 用法

在日常 WPF 開發中,我們經常需要對數據進行篩選、排序、分組等操作,而原生的 ItemsControl 并不直接支持這些功能。本文將介紹如何通過 CollectionViewSource 給一個普通的 ItemsControl 加上 動態篩選功能,并指出其中的一些關鍵注意點


📦 一、初始結構:普通 ItemsControl 顯示列表

我們從一個最簡單的 ItemsControl 開始:

<ItemsControl ItemsSource="{Binding MBConfigList}"><ItemsControl.ItemTemplate><DataTemplate><TextBlock Text="{Binding FileName}" /></DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>

這個控件可以顯示綁定的 MBConfigList 數據,但沒有任何過濾能力。


🛠? 二、目標:支持按光源類型篩選

我們希望最終能夠讓用戶勾選光源類型,動態篩選出指定類型的數據。例如:

  • 支持“全選”
  • 多個 CheckBox 動態刷新列表
  • 用戶操作后立即生效

🧰 三、改造步驟


1?? 引入 CollectionViewSource

我們在 ViewModel 中定義一個 CollectionViewSource 并設置過濾事件:

private CollectionViewSource _viewSource;public ICollectionView FilteredMBConfigList
{get => _viewSource?.View;private set => SetProperty(ref _filteredView, value); // 實現 INotifyPropertyChanged
}public void InitializeFilteredView()
{_viewSource = new CollectionViewSource{Source = GlobalData.Instance.saveInfo.MBConfigList};_viewSource.Filter += ApplyFilter;FilteredMBConfigList = _viewSource.View;
}

FilteredMBConfigList 必須是支持通知的不然界面是不會變化的。


2?? 編寫篩選邏輯 ApplyFilter

private void ApplyFilter(object sender, FilterEventArgs e)
{if (e.Item is MBConfigInfo item){var selectedTypes = LightSourceItems.Where(x => x.IsChecked).Select(x => x.Name).ToHashSet();//ToHashSet()是為了更快的查詢// 顯示所有或匹配項e.Accepted = selectedTypes.Count == 0 || selectedTypes.Contains(item.LightSourceType);}
}

private CollectionViewSource _viewSource; 不能申明成局部變量,不然ApplyFilter只能生效一次。

e.Accepted == true 的選項才會被顯示出來。


3?? UI 綁定到新集合

<ItemsControl ItemsSource="{Binding FilteredMBConfigList}"><ItemsControl.ItemTemplate><DataTemplate><TextBlock Text="{Binding FileName}" /></DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>

這樣,控件就用上了支持篩選的視圖。


🚨 四、關鍵注意事項


?? 1. CollectionViewSource 必須緩存

不能每次 get 都創建新的 CollectionViewSource,否則不會觸發 .Refresh()

// 錯誤寫法(每次都 new):
public ICollectionView Filtered => new CollectionViewSource { Source = xxx }.View;// 正確:只創建一次

?? 2. 調用 View.Refresh() 以應用篩選

數據變化時,你必須手動調用:

FilteredMBConfigList.Refresh();

建議綁定項(如 CheckBox)中 PropertyChanged 事件或命令中執行刷新。

FilteredMBConfigList.Refresh();調用后會重新觸發ApplyFilter 以到達篩選的目的。


?? 3. 篩選邏輯不要復雜耗時

FilterEventArgs 的處理函數會在每次刷新時對 所有項 執行。避免長計算!


?? 4. UI 綁定的是 View,不是 CollectionViewSource 本身

綁定語法是:

ItemsSource="{Binding FilteredMBConfigList}"

不是 _viewSource,而是其 .View


? 五、示例:支持多選篩選項結構

使用一個簡單的模型:

public class LightSourceFilterItem : INotifyPropertyChanged
{public string Name { get; }public bool IsChecked { get; set; } // 實現通知
}

ViewModel:

public ObservableCollection<LightSourceFilterItem> LightSourceItems { get; set; }LightSourceItems = new ObservableCollection<LightSourceFilterItem>(new[] { "上光源", "下光源", "側光源" }.Select(name =>{var item = new LightSourceFilterItem(name) { IsChecked = true };item.PropertyChanged += (_, __) => FilteredMBConfigList?.Refresh();return item;}));

XAML:

<ItemsControl ItemsSource="{Binding LightSourceItems}"><ItemsControl.ItemTemplate><DataTemplate><CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked, Mode=TwoWay}" /></DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>

🏁 六、總結

優點 ?注意點 ??
支持篩選、排序、分組.Refresh() 要手動調用
ItemsControl, ListBox, DataGrid 搭配無縫Filter 邏輯要快
不改變原始集合不要頻繁 new CollectionViewSource

使用 CollectionViewSource 是 WPF 中實現數據視圖分離的經典方式,非常適合構建支持過濾的 UI。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908083.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908083.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908083.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mybatis Plus JSqlParser解析sql語句及JSqlParser安裝步驟

MyBatis Plus與JSqlParser&#xff1a;SQL語句解析與實戰指南 在現代Java開發中&#xff0c;SQL解析和動態SQL生成是數據庫操作中不可或缺的一部分。MyBatis Plus作為MyBatis的增強工具&#xff0c;通過JSqlParser庫實現了對SQL語句的深度解析和修改能力。本文將詳細介紹如何在…

學習路之PHP--easyswoole使用視圖和模板

學習路之PHP--easyswoole使用視圖和模板 一、安裝依賴插件二、 實現渲染引擎三、注冊渲染引擎四、測試調用寫的模板五、優化六、最后補充 一、安裝依賴插件 composer require easyswoole/template:1.1.* composer require topthink/think-template相關版本&#xff1a; "…

設計模式——享元設計模式(結構型)

摘要 享元設計模式是一種結構型設計模式&#xff0c;旨在通過共享對象減少內存占用和提升性能。其核心思想是將對象狀態分為內部狀態&#xff08;可共享&#xff09;和外部狀態&#xff08;不可共享&#xff09;&#xff0c;并通過享元工廠管理共享對象池。享元模式包含抽象享…

互聯網大廠Java求職面試:云原生微服務架構設計與AI大模型集成實戰

互聯網大廠Java求職面試&#xff1a;云原生微服務架構設計與AI大模型集成實戰 面試場景設定 人物設定&#xff1a; 李明&#xff08;技術總監&#xff09;&#xff1a;擁有15年分布式系統架構經驗&#xff0c;主導過多個億級用戶系統的重構&#xff0c;對云原生和AI融合有深…

nginx+tomcat動靜分離、負載均衡

一、理論 nginx用于處理靜態頁面以及做調度器&#xff0c;tomcat用于處理動態頁面 lvs&#xff08;四層&#xff09; 輪詢&#xff08;rr&#xff09; 加權輪詢&#xff08;wrr&#xff09; 最小連接&#xff08;lc&#xff09; 加權最小連接&#xff08;wlc&#xff09; ngi…

什么是AI芯片?

首先&#xff0c;我們要了解一下&#xff1a;什么是芯片&#xff1f;芯片的本質就是在半導體襯底上制作能實現一系列特定功能的集成電路。 其次&#xff0c;來看一下AI的概念。AI是研究如何使計算機能夠模擬和執行人類智能任務的科學和技術領域&#xff0c;致力于開發能夠感知…

PostgreSQL數據庫配置SSL操作說明書

背景&#xff1a; 因為postgresql或者mysql目前通過docker安裝&#xff0c;只需要輸入主機IP、用戶名、密碼即可訪問成功&#xff0c;這樣其實是不安全的&#xff0c;可能會通過一些手段獲取到用戶名密碼導致數據被竊取。而ES、kafka等也是通過用戶名/密碼方式連接&#xff0c;…

k8s更新證書

[rootk8s-master01 ~]# sudo kubeadm certs renew all [renew] Reading configuration from the cluster… [renew] FYI: You can look at this config file with ‘kubectl -n kube-system get cm kubeadm-config -o yaml’ certificate embedded in the kubeconfig file for…

正點原子lwIP協議的學習筆記

正點原子lwIP協議的學習筆記 正點原子lwIP學習筆記——lwIP入門 正點原子lwIP學習筆記——MAC簡介 正點原子lwIP學習筆記——PHY芯片簡介 正點原子lwIP學習筆記——以太網DMA描述符 正點原子lwIP學習筆記——裸機移植lwIP 正點原子lwIP學習筆記——裸機lwIP啟動流程 正點…

MongoTemplate常用api學習

本文只介紹常用的api&#xff0c;盡量以最簡單的形式學會mongoTemplate基礎api的使用 一、新增 主要包含三個api&#xff1a;insert&#xff08;一個或遍歷插多個&#xff09;、insertAll&#xff08;批量多個&#xff09;、save&#xff08;插入或更新&#xff09; //這里簡…

006網上訂餐系統技術解析:打造高效便捷的餐飲服務平臺

網上訂餐系統技術解析&#xff1a;打造高效便捷的餐飲服務平臺 在數字化生活方式普及的當下&#xff0c;網上訂餐系統成為連接餐飲商家與消費者的重要橋梁。該系統以菜品分類、訂單管理等模塊為核心&#xff0c;通過前臺展示與后臺錄入的分工協作&#xff0c;為管理員和會員提…

網絡攻防技術五:網絡掃描技術

文章目錄 一、網絡掃描的基礎概念二、主機發現三、端口掃描1、端口號2、端口掃描技術3、端口掃描隱秘策略 四、操作系統識別五、漏洞掃描六、簡答題1. 主機掃描的目的是什么&#xff1f;請簡述主機掃描方法。2. 端口掃描的目的是什么&#xff1f;請簡述端口掃描方法及掃描策略。…

生成JavaDoc文檔

生成 JavaDoc 文檔 1、快速生成 文檔 注解 2、常見的文檔注解 3、腳本生成 doc 文檔 4、IDEA工具欄生成 doc 文檔 第一章 快速入門 第01節 使用插件 在插件工具當中&#xff0c;找到插件 javaDoc 使用方式&#xff0c;在代碼區域&#xff0c;直接點擊右鍵。選擇 第02節 常用注…

大數據-276 Spark MLib - 基礎介紹 機器學習算法 Bagging和Boosting區別 GBDT梯度提升樹

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; 大模型篇章已經開始&#xff01; 目前已經更新到了第 22 篇&#xff1a;大語言模型 22 - MCP 自動操作 FigmaCursor 自動設計原型 Java篇開…

【HarmonyOS 5】如何優化 Harmony-Cordova 應用的性能?

以下是針對 ?Harmony-Cordova 應用性能優化?的完整方案&#xff0c;結合鴻蒙原生特性和Cordova框架優化策略&#xff1a; ??一、渲染性能優化? ?減少布局嵌套層級? 使用扁平化布局&#xff08;如 Grid、GridRow&#xff09;替代多層 Column/Row 嵌套&#xff0c;避免冗…

數據庫管理-第332期 大數據已死,那什么當立?(20250602)

數據庫管理332期 2025-06-02 數據庫管理-第332期 大數據已死&#xff0c;那什么當立&#xff1f;&#xff08;20250602&#xff09;1 概念還是技術2 必然的大數據量3 離線到實時4 未來總結 數據庫管理-第332期 大數據已死&#xff0c;那什么當立&#xff1f;&#xff08;202506…

相機--RGBD相機

教程 分類原理和標定 原理 視頻總結 雙目相機和RGBD相機原理 作用 RGBD相機RGB相機深度&#xff1b; RGB-D相機同時獲取兩種核心數據&#xff1a;RGB彩色圖像和深度圖像&#xff08;Depth Image&#xff09;。 1. RGB彩色圖像 數據格式&#xff1a; 標準三通道矩陣&#…

神經符號集成-三篇綜述

講解三篇神經符號集成的綜述&#xff0c;這些綜述沒有針對推薦系統的&#xff0c;所以大致過一下&#xff0c;下一篇帖子會介紹針對KG的兩篇綜述。綜述1關注的是系統集成和數據流的宏觀模式“是什么”&#xff1b;綜述3關注的是與人類理解直接相關的中間過程和決策邏輯的透明度…

window/linux ollama部署模型

模型部署 模型下載表: deepseek-r1 win安裝ollama 注意去官網下載ollama,這個win和linux差別不大,win下載exe linux安裝ollama 采用docker方式進行安裝: OLLAMA_HOST=0.0.0.0:11434 \ docker run -d \--gpus all \-p 11434:11434 \--name ollama \-v ollama:/root/.ol…

計算A圖片所有顏色占B圖片紅色區域的百分比

import cv2 import numpy as npdef calculate_overlap_percentage(a_image_path, b_image_path):# 讀取A組和B組圖像a_image cv2.imread(a_image_path)b_image cv2.imread(b_image_path)# 將圖像從BGR轉為HSV色彩空間&#xff0c;便于顏色篩選a_hsv cv2.cvtColor(a_image, c…