翼度科技»论坛 编程开发 mysql 查看内容

让WPF中的DataGrid像Excel一样可以筛选

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
在默认情况下,WPF提供的DataGrid仅拥有数据展示等简单功能,如果要实现像Excel一样复杂的筛选过滤功能,则相对比较麻烦。本文以一个简单的小例子,简述如何通过WPF实话DataGrid的筛选功能,仅供学习分享使用,如有不足之处,还请指正。
涉及知识点

在本示例中,从数据绑定,到数据展示,涉及知识点如下所示:

  • DataGrid,要WPF提供的进行二维数据展示在列表控件,默认功能非常简单,但是可以通过数据模板或者控件模板进行扩展和美化,可伸缩性很强。
  • MVVM,是Model-View-ViewModel的简写,主要进行数据和UI进行前后端分离,在本示例中,主要用到的MVVM第三方库为CommunityToolkit.Mvvm,大大简化原生MVVM的实现方式。
  • 集合视图, 要对 DataGrid 中的数据进行分组、排序和筛选,可以将其绑定到支持这些函数的 CollectionView。 然后,可以在不影响基础源数据的情况下处理 CollectionView 中的数据。 集合视图中的更改反映在 DataGrid 用户界面 (UI) 中。
  • Popup控件,直接继承FrameworkElement,提供了一种在单独的窗口中显示内容的方法,该窗口相对于指定的元素或屏幕坐标,浮动在当前Popup应用程序窗口上,可用于悬浮窗口。
示例截图

本示例主要模仿Excel的筛选功能进行实现,右键标题栏打开浮动窗口,悬浮于标题栏下方,既可以通过文本框进行筛选,也可以通过筛选按钮弹出右键菜单,选择具体筛选方式,截图如下所示:

 
选择筛选方式,弹出窗口,如下所示:

 
 输入筛选条件,点击确定,或者取消筛选。如筛选学号里面包含2的,效果如下所示:

 
 注意:以上筛选都是客户端筛选,不会修改数据源,也不会重连数据库。
核心源码

在本示例中,核心源码主要包含以下几个部分:
前端视图【MainWindow.xaml】源码
主要实现了按学号,姓名,年龄三列进行筛选,既可以单列筛选,又可以组合筛选。且三列的筛选实现方式一致,仅是绑定列有差异。
  1.   1 <Window x:Class="DemoDataGrid.MainWindow"
  2.   2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.   3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.   4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.   5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.   6         xmlns:local="clr-namespace:DemoDataGrid"
  7.   7         mc:Ignorable="d"
  8.   8         Title="DataGrid筛选示例" Height="650" Width="800">
  9.   9     <Window.Resources>
  10. 10         <ResourceDictionary>
  11. 11             <CollectionViewSource x:Key="ItemsSource" Source="{Binding Path=Students}"></CollectionViewSource>
  12. 12             <CollectionViewSource x:Key="Names" Source="{Binding Path=Names}"></CollectionViewSource>
  13. 13             <CollectionViewSource x:Key="Nos" Source="{Binding Path=Nos}"></CollectionViewSource>
  14. 14             <CollectionViewSource x:Key="Ages" Source="{Binding Path=Ages}"></CollectionViewSource>
  15. 15            
  16. 27             <Geometry x:Key="Icon_Filter">
  17. 28                 M608 864C588.8 864 576 851.2 576 832L576 448c0-6.4 6.4-19.2 12.8-25.6L787.2 256c6.4-6.4 6.4-19.2 0-19.2 0-6.4-6.4-12.8-19.2-12.8L256 224c-12.8 0-19.2 6.4-19.2 12.8 0 6.4-6.4 12.8 6.4 19.2l198.4 166.4C441.6 428.8 448 441.6 448 448l0 256c0 19.2-12.8 32-32 32S384 723.2 384 704L384 460.8 198.4 307.2c-25.6-25.6-32-64-19.2-96C185.6 179.2 217.6 160 256 160L768 160c32 0 64 19.2 76.8 51.2 12.8 32 6.4 70.4-19.2 89.6l-192 160L633.6 832C640 851.2 627.2 864 608 864z
  18. 29             </Geometry>
  19. 30             <ContextMenu x:Key="queryConditionMenu" MouseLeave="ContextMenu_MouseLeave" MenuItem.Click="ContextMenu_Click">
  20. 31                 <MenuItem FontSize="12" Header="等于" Tag="Equal"></MenuItem>
  21. 32                 <MenuItem FontSize="12" Header="不等于"  Tag="NotEqual"></MenuItem>
  22. 33                 <MenuItem FontSize="12" Header="开头"  Tag="Begin"></MenuItem>
  23. 34                 <MenuItem FontSize="12" Header="结尾"  Tag="End"></MenuItem>
  24. 35                 <MenuItem FontSize="12" Header="包含"  Tag="In"></MenuItem>
  25. 36                 <MenuItem FontSize="12" Header="不包含"  Tag="NotIn"></MenuItem>
  26. 37             </ContextMenu>
  27. 38         </ResourceDictionary>
  28. 39         
  29. 40     </Window.Resources>
  30. 41     <Grid Margin="10">
  31. 42         <Grid.RowDefinitions>
  32. 43             <RowDefinition Height="20"></RowDefinition>
  33. 44             <RowDefinition Height="*"></RowDefinition>
  34. 45         </Grid.RowDefinitions>
  35. 46         <DataGrid Grid.Row="1" x:Name="dgStudents" ItemsSource="{Binding Source={StaticResource ItemsSource} }" AutoGenerateColumns="False"
  36. 47                               CanUserReorderColumns="True" CanUserDeleteRows="False" CanUserAddRows="False" HeadersVisibility="Column"
  37. 48                               CanUserSortColumns="True"
  38. 49                               VirtualizingPanel.VirtualizationMode="Recycling"
  39. 50                               EnableColumnVirtualization="True" VirtualizingPanel.IsVirtualizingWhenGrouping="True" GridLinesVisibility="All" RowHeight="25"
  40. 51                               SelectionUnit="FullRow" SelectionMode="Single" IsReadOnly="True" FontSize="12"
  41. 52                               SelectedIndex="{Binding SelectTaskItemIndex}" SelectedItem="{Binding SelectTaskItem}"
  42. 53                               CanUserResizeColumns="True">
  43. 54             <DataGrid.Columns>
  44. 55                 <DataGridTextColumn Binding="{Binding Id}" Header="Id" Width="*">
  45. 56                     
  46. 57                 </DataGridTextColumn>
  47. 58                 <DataGridTextColumn Binding="{Binding No}" Width="*">
  48. 59                     <DataGridTextColumn.Header>
  49. 60                         <TextBlock Text="学号" FontWeight="Regular" MouseRightButtonDown="TextBlock_MouseRightButtonDown" Tag="No"></TextBlock>
  50. 61                     </DataGridTextColumn.Header>
  51. 62                 </DataGridTextColumn>
  52. 63                 <DataGridTextColumn Binding="{Binding Name}" Width="*">
  53. 64                     <DataGridTextColumn.Header>
  54. 65                         <TextBlock Text="姓名" FontWeight="Regular" MouseRightButtonDown="TextBlock_MouseRightButtonDown" Tag="Name"></TextBlock>
  55. 66                     </DataGridTextColumn.Header>
  56. 67                 </DataGridTextColumn>
  57. 68                 <DataGridTextColumn Binding="{Binding Age}" Width="*">
  58. 69                     <DataGridTextColumn.Header>
  59. 70                         <TextBlock Text="年龄" FontWeight="Regular" MouseRightButtonDown="TextBlock_MouseRightButtonDown" Tag="Age"></TextBlock>
  60. 71                     </DataGridTextColumn.Header>
  61. 72                 </DataGridTextColumn>
  62. 73             </DataGrid.Columns>
  63. 74         </DataGrid>
  64. 75         <Popup x:Name="popupNo" Width="135" MaxHeight="500" Height="Auto" PopupAnimation="Slide" AllowsTransparency="False" MouseLeave="popup_MouseLeave">
  65. 76             <Border BorderBrush="LightBlue" BorderThickness="1" Padding="5" Background="AliceBlue">
  66. 77                 <Grid>
  67. 78                     <Grid.ColumnDefinitions>
  68. 79                         <ColumnDefinition></ColumnDefinition>
  69. 80                         <ColumnDefinition></ColumnDefinition>
  70. 81                     </Grid.ColumnDefinitions>
  71. 82                     <Grid.RowDefinitions>
  72. 83                         <RowDefinition></RowDefinition>
  73. 84                         <RowDefinition></RowDefinition>
  74. 85                         <RowDefinition></RowDefinition>
  75. 86                     </Grid.RowDefinitions>
  76. 87                     <StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal">
  77. 88                         <TextBox Height="25" x:Name="txtNo" MinWidth="60" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Tag="No" TextChanged="TextBox_TextChanged"></TextBox>
  78. 89                         <Button x:Name="btnNoFilter"  Tag="No" ClickMode="Press" Click="ButtonFilter_Click" ContextMenu="{StaticResource queryConditionMenu}">
  79. 90                             <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
  80. 91                                 <Path Data="{StaticResource Icon_Filter}" Stroke="Gray" StrokeThickness="1"
  81. 92                        Height="12" Width="12" Stretch="Fill"></Path>
  82. 93                                 <TextBlock Margin="2,0" Text="筛选" FontSize="12"></TextBlock>
  83. 94                             </StackPanel>
  84. 95                         </Button>
  85. 96                     </StackPanel>
  86. 97                     <ListBox x:Name="lbNos" ItemsSource="{Binding Source={StaticResource Nos}}" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True" Style="{StaticResource ListBoxStyle}">
  87. 98                         <ListBox.ItemTemplate>
  88. 99                             <DataTemplate>
  89. 100                                 <CheckBox Content="{Binding FilterText}" IsChecked="{Binding IsChecked}"></CheckBox>
  90. 101                             </DataTemplate>
  91. 102                         </ListBox.ItemTemplate>
  92. 103                     </ListBox>
  93. 104
  94. 105                     <Button Tag="No" Content="取消" Width="60" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="0" Click="btnCancel_Click"></Button>
  95. 106                     <Button Content="确定" Width="60" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1" Click="btnOk_Click"></Button>
  96. 107                 </Grid>
  97. 108             </Border>
  98. 109         </Popup>
  99. 110         <Popup x:Name="popupName" Width="135" MaxHeight="500" Height="Auto" PopupAnimation="Slide" AllowsTransparency="False" MouseLeave="popup_MouseLeave">
  100. 111             <Border BorderBrush="LightBlue" BorderThickness="1" Padding="5" Background="AliceBlue">
  101. 112                 <Grid>
  102. 113                     <Grid.ColumnDefinitions>
  103. 114                         <ColumnDefinition></ColumnDefinition>
  104. 115                         <ColumnDefinition></ColumnDefinition>
  105. 116                     </Grid.ColumnDefinitions>
  106. 117                     <Grid.RowDefinitions>
  107. 118                         <RowDefinition></RowDefinition>
  108. 119                         <RowDefinition></RowDefinition>
  109. 120                         <RowDefinition></RowDefinition>
  110. 121                     </Grid.RowDefinitions>
  111. 122                     <StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal">
  112. 123                         <TextBox Height="25" x:Name="txtName" MinWidth="60" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Tag="Name" TextChanged="TextBox_TextChanged"></TextBox>
  113. 124                         <Button x:Name="btnNameFilter"  Tag="Name" Click="ButtonFilter_Click" ContextMenu="{StaticResource queryConditionMenu}">
  114. 125                             <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
  115. 126                                 <Path Data="{StaticResource Icon_Filter}" Stroke="Gray" StrokeThickness="1"
  116. 127                        Height="12" Width="12" Stretch="Fill"></Path>
  117. 128                                 <TextBlock Margin="2,0" Text="筛选" FontSize="12"></TextBlock>
  118. 129                             </StackPanel>
  119. 130                         </Button>
  120. 131                     </StackPanel>
  121. 132                     <ListBox x:Name="lbNames" ItemsSource="{Binding Source={StaticResource Names}}" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True" Style="{StaticResource ListBoxStyle}">
  122. 133                         <ListBox.ItemTemplate>
  123. 134                             <DataTemplate>
  124. 135                                 <CheckBox Content="{Binding FilterText}" IsChecked="{Binding IsChecked}"></CheckBox>
  125. 136                             </DataTemplate>
  126. 137                         </ListBox.ItemTemplate>
  127. 138                     </ListBox>
  128. 139
  129. 140                     <Button Tag="No" Content="取消" Width="60" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="0" Click="btnCancel_Click"></Button>
  130. 141                     <Button Content="确定" Width="60" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1" Click="btnOk_Click"></Button>
  131. 142                 </Grid>
  132. 143             </Border>
  133. 144         </Popup>
  134. 145         <Popup x:Name="popupAge" Width="135" MaxHeight="500" Height="Auto" PopupAnimation="Slide" AllowsTransparency="False" MouseLeave="popup_MouseLeave">
  135. 146             <Border BorderBrush="LightBlue" BorderThickness="1" Padding="5" Background="AliceBlue">
  136. 147                 <Grid>
  137. 148                     <Grid.ColumnDefinitions>
  138. 149                         <ColumnDefinition></ColumnDefinition>
  139. 150                         <ColumnDefinition></ColumnDefinition>
  140. 151                     </Grid.ColumnDefinitions>
  141. 152                     <Grid.RowDefinitions>
  142. 153                         <RowDefinition></RowDefinition>
  143. 154                         <RowDefinition></RowDefinition>
  144. 155                         <RowDefinition></RowDefinition>
  145. 156                     </Grid.RowDefinitions>
  146. 157                     <StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal">
  147. 158                         <TextBox Height="25" x:Name="txtAge" MinWidth="60" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Tag="Age" TextChanged="TextBox_TextChanged"></TextBox>
  148. 159                         <Button x:Name="btnAgeFilter"  Tag="Age" Click="ButtonFilter_Click" ContextMenu="{StaticResource queryConditionMenu}">
  149. 160                             <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
  150. 161                                 <Path Data="{StaticResource Icon_Filter}" Stroke="Gray" StrokeThickness="1"
  151. 162                        Height="12" Width="12" Stretch="Fill"></Path>
  152. 163                                 <TextBlock Margin="2,0" Text="筛选" FontSize="12"></TextBlock>
  153. 164                             </StackPanel>
  154. 165                         </Button>
  155. 166                     </StackPanel>
  156. 167                     <ListBox x:Name="lbAges" ItemsSource="{Binding Source={StaticResource Ages}}" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True" Style="{StaticResource ListBoxStyle}">
  157. 168                         <ListBox.ItemTemplate>
  158. 169                             <DataTemplate>
  159. 170                                 <CheckBox Content="{Binding FilterText}" IsChecked="{Binding IsChecked}"></CheckBox>
  160. 171                             </DataTemplate>
  161. 172                         </ListBox.ItemTemplate>
  162. 173                     </ListBox>
  163. 174
  164. 175                     <Button Tag="No" Content="取消" Width="60" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="0" Click="btnCancel_Click"></Button>
  165. 176                     <Button Content="确定" Width="60" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1" Click="btnOk_Click"></Button>
  166. 177                 </Grid>
  167. 178             </Border>
  168. 179         </Popup>
  169. 180
  170. 181         <Popup x:Name="popupNoMenu" Width="300" MaxHeight="500" Height="200" PopupAnimation="Slide" AllowsTransparency="False" Tag="">
  171. 182             <Border BorderThickness="1" BorderBrush="Beige" Padding="15" Background="AliceBlue">
  172. 183                 <Grid>
  173. 184                     <Grid.ColumnDefinitions>
  174. 185                         <ColumnDefinition></ColumnDefinition>
  175. 186                         <ColumnDefinition></ColumnDefinition>
  176. 187                     </Grid.ColumnDefinitions>
  177. 188                     <Grid.RowDefinitions>
  178. 189                         <RowDefinition Height="Auto"></RowDefinition>
  179. 190                         <RowDefinition Height="Auto"></RowDefinition>
  180. 191                         <RowDefinition Height="Auto"></RowDefinition>
  181. 192                         <RowDefinition></RowDefinition>
  182. 193                     </Grid.RowDefinitions>
  183. 194                     <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
  184. 195                         <TextBlock Text="学号" VerticalAlignment="Center"></TextBlock>
  185. 196                         <ComboBox x:Name="combNoMenu1" Height="28" Width="100" Margin="4" VerticalContentAlignment="Center">
  186. 197                             <ComboBoxItem Content="等于" ></ComboBoxItem>
  187. 198                             <ComboBoxItem Content="不等于"></ComboBoxItem>
  188. 199                             <ComboBoxItem Content="开头"></ComboBoxItem>
  189. 200                             <ComboBoxItem Content="结尾"></ComboBoxItem>
  190. 201                             <ComboBoxItem Content="包含"></ComboBoxItem>
  191. 202                             <ComboBoxItem Content="不包含"></ComboBoxItem>
  192. 203                         </ComboBox>
  193. 204                         <TextBox x:Name="txtNoMenu1" Height="28" Width="100" VerticalContentAlignment="Center"></TextBox>
  194. 205                     </StackPanel>
  195. 206                     <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0"  Grid.ColumnSpan="2">
  196. 207                         <RadioButton x:Name="rbNoAnd" Content="与" IsChecked="True" Margin="4" Background="AliceBlue" VerticalAlignment="Center" VerticalContentAlignment="Center"></RadioButton>
  197. 208                         <RadioButton x:Name="rbNoOr" Content="或" Background="AliceBlue" VerticalAlignment="Center" VerticalContentAlignment="Center"></RadioButton>
  198. 209                     </StackPanel>
  199. 210                     <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="0"  Grid.ColumnSpan="2">
  200. 211                         <TextBlock Text="学号" VerticalAlignment="Center"></TextBlock>
  201. 212                         <ComboBox x:Name="combNoMenu2" Height="28" Margin="4" Width="100" VerticalContentAlignment="Center">
  202. 213                             <ComboBoxItem Content="等于" ></ComboBoxItem>
  203. 214                             <ComboBoxItem Content="不等于"></ComboBoxItem>
  204. 215                             <ComboBoxItem Content="开头"></ComboBoxItem>
  205. 216                             <ComboBoxItem Content="结尾"></ComboBoxItem>
  206. 217                             <ComboBoxItem Content="包含"></ComboBoxItem>
  207. 218                             <ComboBoxItem Content="不包含"></ComboBoxItem>
  208. 219                         </ComboBox>
  209. 220                         <TextBox x:Name="txtNoMenu2" Height="28" Width="100" VerticalContentAlignment="Center"></TextBox>
  210. 221                     </StackPanel>
  211. 222                     <Button Tag="No" Content="取消" Width="100" Height="28" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="0" Click="btnCancelFilter_Click"></Button>
  212. 223                     <Button Tag="No" Content="确定" Width="100" Height="28" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="1" Click="btnOkFilter_Click"></Button>
  213. 224                 </Grid>
  214. 225             </Border>
  215. 226         </Popup>
  216. 227         <Popup x:Name="popupNameMenu" Width="300" MaxHeight="500" Height="200" PopupAnimation="Slide" AllowsTransparency="False" Tag="">
  217. 228             <Border BorderThickness="1" BorderBrush="Beige" Padding="15" Background="AliceBlue">
  218. 229                 <Grid>
  219. 230                     <Grid.RowDefinitions>
  220. 231                         <RowDefinition Height="Auto"></RowDefinition>
  221. 232                         <RowDefinition Height="Auto"></RowDefinition>
  222. 233                         <RowDefinition Height="Auto"></RowDefinition>
  223. 234                         <RowDefinition Height="Auto"></RowDefinition>
  224. 235                     </Grid.RowDefinitions>
  225. 236                     <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
  226. 237                         <TextBlock Text="姓名" VerticalAlignment="Center"></TextBlock>
  227. 238                         <ComboBox x:Name="combNameMenu1" Height="28" Width="100" Margin="4" VerticalContentAlignment="Center">
  228. 239                             <ComboBoxItem Content="等于" ></ComboBoxItem>
  229. 240                             <ComboBoxItem Content="不等于"></ComboBoxItem>
  230. 241                             <ComboBoxItem Content="开头"></ComboBoxItem>
  231. 242                             <ComboBoxItem Content="结尾"></ComboBoxItem>
  232. 243                             <ComboBoxItem Content="包含"></ComboBoxItem>
  233. 244                             <ComboBoxItem Content="不包含"></ComboBoxItem>
  234. 245                         </ComboBox>
  235. 246                         <TextBox x:Name="txtNameMenu1" Height="28" Width="100" VerticalContentAlignment="Center"></TextBox>
  236. 247                     </StackPanel>
  237. 248                     <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0">
  238. 249                         <RadioButton x:Name="rbNameAnd" Content="与" IsChecked="True" Margin="4" Background="AliceBlue" VerticalAlignment="Center" VerticalContentAlignment="Center"></RadioButton>
  239. 250                         <RadioButton x:Name="rbNameOr" Content="或" Background="AliceBlue" VerticalAlignment="Center" VerticalContentAlignment="Center"></RadioButton>
  240. 251                     </StackPanel>
  241. 252                     <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="0">
  242. 253                         <TextBlock Text="姓名" VerticalAlignment="Center"></TextBlock>
  243. 254                         <ComboBox x:Name="combNameMenu2" Height="28" Width="100" Margin="4" VerticalContentAlignment="Center">
  244. 255                             <ComboBoxItem Content="等于" ></ComboBoxItem>
  245. 256                             <ComboBoxItem Content="不等于"></ComboBoxItem>
  246. 257                             <ComboBoxItem Content="开头"></ComboBoxItem>
  247. 258                             <ComboBoxItem Content="结尾"></ComboBoxItem>
  248. 259                             <ComboBoxItem Content="包含"></ComboBoxItem>
  249. 260                             <ComboBoxItem Content="不包含"></ComboBoxItem>
  250. 261                         </ComboBox>
  251. 262                         <TextBox x:Name="txtNameMenu2" Height="28" Width="100" VerticalContentAlignment="Center"></TextBox>
  252. 263                     </StackPanel>
  253. 264                     <Button Tag="Name" Content="取消" Width="100" Height="28" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="0" Click="btnCancelFilter_Click"></Button>
  254. 265                     <Button Tag="Name" Content="确定" Width="100" Height="28" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="1" Click="btnOkFilter_Click"></Button>
  255. 266                 </Grid>
  256. 267             </Border>
  257. 268         </Popup>
  258. 269         <Popup x:Name="popupAgeMenu" Width="300" MaxHeight="500" Height="200" PopupAnimation="Slide" AllowsTransparency="False" Tag="">
  259. 270             <Border BorderThickness="1" BorderBrush="Beige" Padding="15" Background="AliceBlue">
  260. 271                 <Grid>
  261. 272                     <Grid.RowDefinitions>
  262. 273                         <RowDefinition Height="Auto"></RowDefinition>
  263. 274                         <RowDefinition Height="Auto"></RowDefinition>
  264. 275                         <RowDefinition Height="Auto"></RowDefinition>
  265. 276                         <RowDefinition Height="Auto"></RowDefinition>
  266. 277                     </Grid.RowDefinitions>
  267. 278                     <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
  268. 279                         <TextBlock Text="年龄" VerticalAlignment="Center"></TextBlock>
  269. 280                         <ComboBox x:Name="combAgeMenu1" Height="28" Width="100" Margin="4" VerticalContentAlignment="Center">
  270. 281                             <ComboBoxItem Content="等于" ></ComboBoxItem>
  271. 282                             <ComboBoxItem Content="不等于"></ComboBoxItem>
  272. 283                             <ComboBoxItem Content="开头"></ComboBoxItem>
  273. 284                             <ComboBoxItem Content="结尾"></ComboBoxItem>
  274. 285                             <ComboBoxItem Content="包含"></ComboBoxItem>
  275. 286                             <ComboBoxItem Content="不包含"></ComboBoxItem>
  276. 287                         </ComboBox>
  277. 288                         <TextBox x:Name="txtAgeMenu1" Height="28" Width="100" VerticalContentAlignment="Center"></TextBox>
  278. 289                     </StackPanel>
  279. 290                     <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0">
  280. 291                         <RadioButton x:Name="rbAgeAnd" Content="与"  IsChecked="True" Margin="4" Background="AliceBlue" VerticalAlignment="Center" VerticalContentAlignment="Center"></RadioButton>
  281. 292                         <RadioButton x:Name="rbAgeOr" Content="或" Background="AliceBlue" VerticalAlignment="Center" VerticalContentAlignment="Center"></RadioButton>
  282. 293                     </StackPanel>
  283. 294                     <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="0">
  284. 295                         <TextBlock Text="年龄" VerticalAlignment="Center"></TextBlock>
  285. 296                         <ComboBox x:Name="combAgeMenu2" Height="28" Width="100" Margin="4" VerticalContentAlignment="Center">
  286. 297                             <ComboBoxItem Content="等于" ></ComboBoxItem>
  287. 298                             <ComboBoxItem Content="不等于"></ComboBoxItem>
  288. 299                             <ComboBoxItem Content="开头"></ComboBoxItem>
  289. 300                             <ComboBoxItem Content="结尾"></ComboBoxItem>
  290. 301                             <ComboBoxItem Content="包含"></ComboBoxItem>
  291. 302                             <ComboBoxItem Content="不包含"></ComboBoxItem>
  292. 303                         </ComboBox>
  293. 304                         <TextBox x:Name="txtAgeMenu2" Height="28" Width="100" VerticalContentAlignment="Center"></TextBox>
  294. 305                     </StackPanel>
  295. 306                     <Button Tag="Age" Content="取消" Width="100" Height="28" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="0" Click="btnCancelFilter_Click"></Button>
  296. 307                     <Button Tag="Age" Content="确定" Width="100" Height="28" HorizontalAlignment="Right" Grid.Row="3" Grid.Column="1" Click="btnOkFilter_Click"></Button>
  297. 308                 </Grid>
  298. 309             </Border>
  299. 310         </Popup>
  300. 311     </Grid>
  301. 312 </Window>
复制代码
业务逻辑【MainWindowViewModel】
业务逻辑处理主要复责数据初始化等业务相关内容,和UI无关,如下所示:
  1. 1 using CommunityToolkit.Mvvm.ComponentModel;
  2. 2 using System;
  3. 3 using System.Collections.Generic;
  4. 4 using System.Linq;
  5. 5 using System.Text;
  6. 6 using System.Threading.Tasks;
  7. 7
  8. 8 namespace DemoDataGrid
  9. 9 {
  10. 10     public class MainWindowViewModel:ObservableObject
  11. 11     {
  12. 12         #region 属性及构造函数
  13. 13
  14. 14         private List<Student> students;
  15. 15
  16. 16         public List<Student> Students
  17. 17         {
  18. 18             get { return students; }
  19. 19             set { SetProperty(ref students, value); }
  20. 20         }
  21. 21
  22. 22         private List<FilterInfo> names;
  23. 23
  24. 24         public List<FilterInfo> Names
  25. 25         {
  26. 26             get { return names; }
  27. 27             set { SetProperty(ref names, value); }
  28. 28         }
  29. 29
  30. 30         private List<FilterInfo> nos;
  31. 31
  32. 32         public List<FilterInfo> Nos
  33. 33         {
  34. 34             get { return nos; }
  35. 35             set {SetProperty(ref nos , value); }
  36. 36         }
  37. 37
  38. 38         private List<FilterInfo> ages;
  39. 39
  40. 40         public List<FilterInfo> Ages
  41. 41         {
  42. 42             get { return ages; }
  43. 43             set {SetProperty(ref ages , value); }
  44. 44         }
  45. 45
  46. 46
  47. 47
  48. 48         public MainWindowViewModel()
  49. 49         {
  50. 50             this.Students= new List<Student>();
  51. 51             for (int i = 0; i < 20; i++) {
  52. 52                 this.Students.Add(new Student()
  53. 53                 {
  54. 54                     Id = i,
  55. 55                     Name = $"张{i}牛",
  56. 56                     Age = (i % 10) + 10,
  57. 57                     No = i.ToString().PadLeft(4, '0'),
  58. 58                 });
  59. 59             }
  60. 60             this.Nos= new List<FilterInfo>();
  61. 61             this.Names= new List<FilterInfo>();
  62. 62             this.Ages= new List<FilterInfo>();
  63. 63             this.Students.ForEach(s => {
  64. 64                 this.Nos.Add(new FilterInfo() { FilterText=s.No,IsChecked=false });
  65. 65                 this.Names.Add(new FilterInfo() { FilterText = s.Name, IsChecked = false });
  66. 66                 this.Ages.Add(new FilterInfo() { FilterText = s.Age.ToString(), IsChecked = false });
  67. 67             });
  68. 68             this.Ages=this.Ages.Distinct().ToList();//去重
  69. 69         }
  70. 70
  71. 71         #endregion
  72. 72
  73. 73
  74. 74     }
  75. 75 }
复制代码
筛选功能实现【MainWindow.xaml.cs】
本示例为了简化实现,筛选功能处理主要在cs后端实现,如下所示:
  1.   1 using System;
  2.   2 using System.Collections.Generic;
  3.   3 using System.Linq;
  4.   4 using System.Text;
  5.   5 using System.Threading.Tasks;
  6.   6 using System.Windows;
  7.   7 using System.Windows.Controls;
  8.   8 using System.Windows.Data;
  9.   9 using System.Windows.Documents;
  10. 10 using System.Windows.Input;
  11. 11 using System.Windows.Media;
  12. 12 using System.Windows.Media.Imaging;
  13. 13 using System.Windows.Navigation;
  14. 14 using System.Windows.Shapes;
  15. 15
  16. 16 namespace DemoDataGrid
  17. 17 {
  18. 18     /// <summary>
  19. 19     /// Interaction logic for MainWindow.xaml
  20. 20     /// </summary>
  21. 21     public partial class MainWindow : Window
  22. 22     {
  23. 23         private MainWindowViewModel viewModel;
  24. 24
  25. 25         public MainWindow()
  26. 26         {
  27. 27             InitializeComponent();
  28. 28             viewModel = new MainWindowViewModel();
  29. 29             this.DataContext = viewModel;
  30. 30         }
  31. 31
  32. 32
  33. 33         #region 筛选
  34. 34
  35. 35         private void TextBlock_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
  36. 36         {
  37. 37             if (sender != null && sender is TextBlock)
  38. 38             {
  39. 39                 var textBlock = sender as TextBlock;
  40. 40                 var tag = textBlock.Tag.ToString();
  41. 41                 var pop = this.FindName($"popup{tag}");
  42. 42                 if (pop != null)
  43. 43                 {
  44. 44                     var popup = pop as System.Windows.Controls.Primitives.Popup;
  45. 45                     if (popup != null)
  46. 46                     {
  47. 47                         popup.IsOpen = true;
  48. 48                         popup.PlacementTarget = textBlock;
  49. 49                         popup.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
  50. 50                         popup.VerticalOffset = 10;
  51. 51                         popup.HorizontalOffset = 10;
  52. 52                     }
  53. 53                 }
  54. 54             }
  55. 55         }
  56. 56
  57. 57         private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
  58. 58         {
  59. 59             TextBox textBox = e.OriginalSource as TextBox;
  60. 60             var tag = textBox.Tag;//条件
  61. 61             var text = textBox.Text;
  62. 62             if (tag != null)
  63. 63             {
  64. 64                 if (tag.ToString() == "No")
  65. 65                 {
  66. 66                     Filter(this.lbNos.ItemsSource, this.txtNo.Text);
  67. 67                 }
  68. 68                 if (tag.ToString() == "Name")
  69. 69                 {
  70. 70                     Filter(this.lbNames.ItemsSource, this.txtName.Text);
  71. 71                 }
  72. 72                 if (tag.ToString() == "Age")
  73. 73                 {
  74. 74                     Filter(this.lbAges.ItemsSource, this.txtAge.Text);
  75. 75                 }
  76. 76             }
  77. 77
  78. 78         }
  79. 79
  80. 80         private void Filter(object source, string filter)
  81. 81         {
  82. 82             var cv = CollectionViewSource.GetDefaultView(source);
  83. 83             if (cv != null && cv.CanFilter)
  84. 84             {
  85. 85                 cv.Filter = new Predicate<object>((obj) => {
  86. 86                     bool flag = true;
  87. 87                     var t = obj as FilterInfo;
  88. 88                     if (t != null)
  89. 89                     {
  90. 90                         flag = t.FilterText.Contains(filter);
  91. 91                     }
  92. 92                     return flag;
  93. 93                 });
  94. 94             }
  95. 95         }
  96. 96
  97. 97         private void popup_MouseLeave(object sender, MouseEventArgs e)
  98. 98         {
  99. 99             var popup = e.OriginalSource as System.Windows.Controls.Primitives.Popup;
  100. 100             var showContext = (this.FindResource("queryConditionMenu") as ContextMenu)?.IsOpen;
  101. 101             if (popup != null && showContext==false)
  102. 102             {
  103. 103                 popup.IsOpen = false;
  104. 104             }
  105. 105         }
  106. 106
  107. 107         private void btnCancel_Click(object sender, RoutedEventArgs e)
  108. 108         {
  109. 109             var btn = e.OriginalSource as Button;
  110. 110             if (btn != null)
  111. 111             {
  112. 112                 var tag = btn.Tag;
  113. 113                 if (tag.ToString() == "No")
  114. 114                 {
  115. 115                     ClearFilter(this.txtNo, this.viewModel.Nos);
  116. 116                 }
  117. 117                 if (tag.ToString() == "Name")
  118. 118                 {
  119. 119                     ClearFilter(this.txtName, this.viewModel.Names);
  120. 120
  121. 121                 }
  122. 122                 if (tag.ToString() == "Age")
  123. 123                 {
  124. 124                     ClearFilter(this.txtAge, this.viewModel.Ages);
  125. 125                 }
  126. 126                 FilterTask();//清除以后,重新刷新
  127. 127             }
  128. 128         }
  129. 129
  130. 130         private void ClearFilter(TextBox textBox, List<FilterInfo> collection)
  131. 131         {
  132. 132             textBox.Clear();
  133. 133             foreach (var f in collection)
  134. 134             {
  135. 135                 f.IsChecked = false;
  136. 136             }
  137. 137         }
  138. 138
  139. 139         private void btnOk_Click(object sender, RoutedEventArgs e)
  140. 140         {
  141. 141             //
  142. 142             FilterTask();
  143. 143         }
  144. 144
  145. 145
  146. 146         private void FilterTask()
  147. 147         {
  148. 148             var cv = CollectionViewSource.GetDefaultView(this.dgStudents.ItemsSource);
  149. 149             if (cv != null && cv.CanFilter)
  150. 150             {
  151. 151                 cv.Filter = new Predicate<object>((obj) =>
  152. 152                 {
  153. 153                     bool flag = true;
  154. 154                     var t = obj as Student;
  155. 155                     if (t != null)
  156. 156                     {
  157. 157                         var nos = this.viewModel.Nos.Where(r => r.IsChecked == true).ToList();
  158. 158                         var names = this.viewModel.Names.Where(r => r.IsChecked == true).ToList();
  159. 159                         var ages = this.viewModel.Ages.Where(r => r.IsChecked == true).ToList();
  160. 160                         if (nos.Count() > 0)
  161. 161                         {
  162. 162                             flag = flag && nos.Select(r => r.FilterText).Contains(t.No);
  163. 163                         }
  164. 164                         if (names.Count() > 0)
  165. 165                         {
  166. 166                             flag = flag && names.Select(r => r.FilterText).Contains(t.Name);
  167. 167                         }
  168. 168                         if (ages.Count() > 0)
  169. 169                         {
  170. 170                             flag = flag && ages.Select(r => r.FilterText).Contains(t.Age.ToString());
  171. 171                         }
  172. 172                     }
  173. 173                     return flag;
  174. 174                 });
  175. 175             }
  176. 176         }
  177. 177
  178. 178         #endregion
  179. 179
  180. 180         private List<string> condition = new List<string>() { "Equal", "NotEqual", "Begin", "End", "In", "NotIn" };
  181. 181
  182. 182         private void ButtonFilter_Click(object sender, RoutedEventArgs e)
  183. 183         {
  184. 184             var btn = e.OriginalSource as Button;
  185. 185             if (btn != null)
  186. 186             {
  187. 187                 var tag = btn.Tag;
  188. 188                 var popup = this.FindName($"popup{tag}") as System.Windows.Controls.Primitives.Popup;
  189. 189                 if (popup != null)
  190. 190                 {
  191. 191                     popup.IsOpen = true;
  192. 192                 }
  193. 193                 if (btn.ContextMenu.IsOpen)
  194. 194                 {
  195. 195                     btn.ContextMenu.IsOpen = false;
  196. 196                 }
  197. 197                 else
  198. 198                 {
  199. 199                     btn.ContextMenu.Tag = tag;
  200. 200                     btn.ContextMenu.Width = 100;
  201. 201                     btn.ContextMenu.Height = 150;
  202. 202                     btn.ContextMenu.IsOpen = true;
  203. 203                     btn.ContextMenu.PlacementTarget = btn;
  204. 204                     btn.ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
  205. 205                 }
  206. 206             }
  207. 207         }
  208. 208
  209. 209         private void ContextMenu_MouseLeave(object sender, MouseEventArgs e)
  210. 210         {
  211. 211             var menu = e.OriginalSource as ContextMenu;
  212. 212             if (menu != null)
  213. 213             {
  214. 214                 menu.IsOpen = false;
  215. 215             }
  216. 216         }
  217. 217
  218. 218         private void ContextMenu_Click(object sender, RoutedEventArgs e)
  219. 219         {
  220. 220             var contextMenu = sender as ContextMenu;
  221. 221             if (contextMenu == null)
  222. 222             {
  223. 223                 return;
  224. 224             }
  225. 225             var menuItem = e.OriginalSource as MenuItem;
  226. 226             if (menuItem == null)
  227. 227             {
  228. 228                 return;
  229. 229             }
  230. 230             var tag1 = contextMenu.Tag.ToString();//点击的哪一个按钮
  231. 231             var tag2 = menuItem.Tag.ToString();//点击的是哪一个菜单
  232. 232             var pop = this.FindName($"popup{tag1}Menu");
  233. 233             var comb = this.FindName($"comb{tag1}Menu1");
  234. 234             HideParentPopup(tag1);//隐藏父Popup
  235. 235             if (comb != null)
  236. 236             {
  237. 237                 var combMenu = comb as ComboBox;
  238. 238                 combMenu.SelectedIndex = condition.IndexOf(tag2);
  239. 239             }
  240. 240             if (pop != null)
  241. 241             {
  242. 242                 var popup = pop as System.Windows.Controls.Primitives.Popup;
  243. 243                 popup.IsOpen = true;
  244. 244                 popup.PlacementTarget = dgStudents;
  245. 245                 popup.Placement = System.Windows.Controls.Primitives.PlacementMode.Center;
  246. 246             }
  247. 247         }
  248. 248
  249. 249         private void btnCancelFilter_Click(object sender, RoutedEventArgs e)
  250. 250         {
  251. 251             if (sender == null)
  252. 252             {
  253. 253                 return;
  254. 254             }
  255. 255             var btn = sender as System.Windows.Controls.Button;
  256. 256             if (btn != null)
  257. 257             {
  258. 258                 var tag = btn.Tag.ToString();
  259. 259                 HidePopupMenu(tag);//隐藏Popup控件
  260. 260                 if (tag == "No")
  261. 261                 {
  262. 262                     ClearMenuFilter(this.txtNoMenu1, this.txtNoMenu2);
  263. 263                 }
  264. 264                 if (tag == "Name")
  265. 265                 {
  266. 266                     ClearMenuFilter(this.txtNameMenu1, this.txtNameMenu2);
  267. 267                 }
  268. 268                 if (tag == "Age")
  269. 269                 {
  270. 270                     ClearMenuFilter(this.txtAgeMenu1, this.txtAgeMenu2);
  271. 271                 }
  272. 272                 FilterMenuTask();
  273. 273             }
  274. 274         }
  275. 275
  276. 276
  277. 277         private void btnOkFilter_Click(object sender, RoutedEventArgs e)
  278. 278         {
  279. 279             if (sender == null)
  280. 280             {
  281. 281                 return;
  282. 282             }
  283. 283             var btn = sender as System.Windows.Controls.Button;
  284. 284             if (btn != null)
  285. 285             {
  286. 286                 var tag = btn.Tag.ToString();
  287. 287                 HidePopupMenu(tag);
  288. 288                 FilterMenuTask();
  289. 289             }
  290. 290         }
  291. 291
  292. 292         /// <summary>
  293. 293         /// 隐藏父Popup
  294. 294         /// </summary>
  295. 295         /// <param name="tag"></param>
  296. 296         private void HideParentPopup(string tag)
  297. 297         {
  298. 298             //点击右键菜单时,隐藏父Popup控件
  299. 299             if (tag == "No")
  300. 300             {
  301. 301                 this.popupNo.IsOpen = false;
  302. 302             }
  303. 303             if (tag == "Name")
  304. 304             {
  305. 305                 this.popupName.IsOpen = false;
  306. 306             }
  307. 307             if (tag == "Age")
  308. 308             {
  309. 309                 this.popupAge.IsOpen = false;
  310. 310             }
  311. 311         }
  312. 312
  313. 313         /// <summary>
  314. 314         /// 隐藏菜单弹出的Popup控件
  315. 315         /// </summary>
  316. 316         /// <param name="tag"></param>
  317. 317         private void HidePopupMenu(string tag)
  318. 318         {
  319. 319             var pop = this.FindName($"popup{tag}Menu");
  320. 320             if (pop != null)
  321. 321             {
  322. 322                 var popup = pop as System.Windows.Controls.Primitives.Popup;
  323. 323                 popup.IsOpen = false;
  324. 324             }
  325. 325         }
  326. 326
  327. 327         /// <summary>
  328. 328         /// 清除菜单中的文本过滤条件
  329. 329         /// </summary>
  330. 330         /// <param name="txt1"></param>
  331. 331         /// <param name="txt2"></param>
  332. 332         private void ClearMenuFilter(TextBox txt1, TextBox txt2)
  333. 333         {
  334. 334             txt1?.Clear();
  335. 335             txt2?.Clear();
  336. 336         }
  337. 337
  338. 338         /// <summary>
  339. 339         ///
  340. 340         /// </summary>
  341. 341         private void FilterMenuTask()
  342. 342         {
  343. 343             var cv = CollectionViewSource.GetDefaultView(this.dgStudents.ItemsSource);
  344. 344             if (cv != null && cv.CanFilter)
  345. 345             {
  346. 346                 cv.Filter = new Predicate<object>((obj) =>
  347. 347                 {
  348. 348                     bool flag = true;
  349. 349                     var t = obj as Student;
  350. 350                     if (t != null)
  351. 351                     {
  352. 352                         string noText1 = this.txtNoMenu1.Text.Trim();
  353. 353                         string noText2 = this.txtNoMenu2.Text.Trim();
  354. 354                         int noConditionType1 = this.combNoMenu1.SelectedIndex;
  355. 355                         int noConditionType2 = this.combNoMenu2.SelectedIndex;
  356. 356                         string nameText1 = this.txtNameMenu1.Text.Trim();
  357. 357                         string nameText2 = this.txtNameMenu2.Text.Trim();
  358. 358                         int nameConditionType1 = this.combNameMenu1.SelectedIndex;
  359. 359                         int nameConditionType2 = this.combNameMenu2.SelectedIndex;
  360. 360                         string ageText1 = this.txtAgeMenu1.Text.Trim();
  361. 361                         string ageText2 = this.txtAgeMenu2.Text.Trim();
  362. 362                         int ageConditionType1 = this.combAgeMenu1.SelectedIndex;
  363. 363                         int ageConditionType2 = this.combAgeMenu2.SelectedIndex;
  364. 364                         bool? isNoAnd = this.rbNoAnd.IsChecked;
  365. 365                         bool? isNoOr = this.rbNoOr.IsChecked;
  366. 366                         bool? isNameAnd = this.rbNameAnd.IsChecked;
  367. 367                         bool? isNameOr = this.rbNameOr.IsChecked;
  368. 368                         bool? isAgeAnd = this.rbAgeAnd.IsChecked;
  369. 369                         bool? isAgeOr = this.rbAgeOr.IsChecked;
  370. 370                         bool flagNo = true;
  371. 371                         bool flagName = true;
  372. 372                         bool flagAge = true;
  373. 373                         flagNo = CheckConditions(noConditionType1, noConditionType2, t.No, noText1, noText2, isNoAnd, isNoOr);
  374. 374                         flagName = CheckConditions(nameConditionType1, nameConditionType2, t.Name, nameText1, nameText2, isNameAnd, isNameOr);
  375. 375                         flagAge = CheckConditions(ageConditionType1, ageConditionType2, t.Age.ToString(), ageText1, ageText2, isAgeAnd, isAgeOr);
  376. 376                         flag = flag && flagNo && flagName && flagAge;
  377. 377                     }
  378. 378                     return flag;
  379. 379                 });
  380. 380             }
  381. 381         }
  382. 382
  383. 383         private bool CheckConditions(int conditionIndex1, int conditionIndex2, string source, string condition1, string condition2, bool? isAnd, bool? isOr)
  384. 384         {
  385. 385             bool flag = true;
  386. 386             bool flag1 = true;
  387. 387             bool flag2 = true;
  388. 388             if (!string.IsNullOrEmpty(condition1) && !string.IsNullOrWhiteSpace(condition1) && conditionIndex1 != -1)
  389. 389             {
  390. 390                 flag1 = CheckCondition(conditionIndex1, source, condition1);
  391. 391             }
  392. 392             if (!string.IsNullOrEmpty(condition2) && !string.IsNullOrWhiteSpace(condition2) && conditionIndex2 != -1)
  393. 393             {
  394. 394                 flag2 = CheckCondition(conditionIndex2, source, condition2);
  395. 395             }
  396. 396             if (isAnd == true)
  397. 397             {
  398. 398                 flag = flag1 && flag2;
  399. 399             }
  400. 400             if (isOr == true)
  401. 401             {
  402. 402                 flag = flag1 || flag2;
  403. 403             }
  404. 404             return flag;
  405. 405         }
  406. 406
  407. 407         private bool CheckCondition(int condtionIndex, string source, string condition)
  408. 408         {
  409. 409             bool flag = true;
  410. 410             if (condtionIndex == 0)
  411. 411             {
  412. 412                 flag = flag && source == condition;
  413. 413             }
  414. 414             if (condtionIndex == 1)
  415. 415             {
  416. 416                 flag = flag && source != condition;
  417. 417             }
  418. 418             if (condtionIndex == 2)
  419. 419             {
  420. 420                 flag = flag && source.StartsWith(condition);
  421. 421             }
  422. 422             if (condtionIndex == 3)
  423. 423             {
  424. 424                 flag = flag && source.EndsWith(condition);
  425. 425             }
  426. 426             if (condtionIndex == 4)
  427. 427             {
  428. 428                 flag = flag && source.Contains(condition);
  429. 429             }
  430. 430             if (condtionIndex == 5)
  431. 431             {
  432. 432                 flag = flag && !source.Contains(condition);
  433. 433             }
  434. 434             return flag;
  435. 435         }
  436. 436     }
  437. 437 }
复制代码
学号,姓名,年龄三列过滤列表绑定内容模型一致,为FilterInfo,如下所示:
  1. using CommunityToolkit.Mvvm.ComponentModel;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace DemoDataGrid
  8. {
  9.     public class FilterInfo : ObservableObject
  10.     {
  11.         private string filterText;
  12.         public string FilterText
  13.         {
  14.             get { return filterText; }
  15.             set { SetProperty(ref filterText, value); }
  16.         }
  17.         private bool isChecked;
  18.         public bool IsChecked
  19.         {
  20.             get { return isChecked; }
  21.             set { SetProperty(ref isChecked, value); }
  22.         }
  23.     }
  24. }
复制代码
不足与思考

上述筛选实现方式,并非唯一实现,也并非最优实现,同样存在许多可以优化的地方。
在本示例中,存在许多冗余代码,如视图页面,对三列的弹出窗口,内容虽然相对统一,只是列名和绑定内容不同而已,却堆积了三大段代码,是否可以从控件模块或者数据模板的角度,进行简化呢?
筛选功能实现上,同样存在许多冗余代码,是否可以进行简化呢?以上是我们需要思考的地方,希望可以集思广益,共同学习,一起进步。

来源:https://www.cnblogs.com/hsiang/archive/2023/02/28/17162319.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具