使用TextBox和DatePicker元素进行WPF DataGrid行过滤



我目前正在开发我的第一个WPF应用程序。我使用的是。net Framework 4.8。在我的WPF应用程序中,我使用了DataGrid元素。我这样定义DataGrid元素:

<DataGrid IsReadOnly="True" HeadersVisibility="Column" AutoGenerateColumns="False" Grid.Row="1" Grid.Column="0" x:Name="MyDataGrid" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="Turquoise" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="BorderThickness" Value="0,0,1,2" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="id" Binding="{Binding id}" Visibility="Hidden" Width="*"/>
<DataGridTextColumn Header="fileId" Binding="{Binding fileId}" Visibility="Hidden" Width="*"/>
<DataGridTextColumn Header="val1" Binding="{Binding val1}" Width="*"/>
<DataGridTextColumn Header="val2" Binding="{Binding val2, StringFormat={0:dd.MM.yy}}" Width="*"/>
<DataGridTextColumn Header="val3" Binding="{Binding val3, StringFormat={0:dd.MM.yy}}" Width="*"/>
</DataGrid.Columns>
</DataGrid>

此外,我还包含了两个日期拾取器和一个文本框。我将它们定义如下:

<TextBox Grid.Row="0" IsReadOnly="False" Grid.Column="1"  Name="FilterVal1" TextChanged="FilterDataGrid"/>
<DatePicker Grid.Row="1" Grid.Column="1" Name="FilterVal2" SelectedDateChanged="FilterDataGrid"/>
<DatePicker Grid.Row="2" Grid.Column="1" Name="FilterVal3" SelectedDateChanged="FilterDataGrid"/>

在我的FilterDataGrid方法中,我现在按如下方式过滤DataGrid的行:

private void FilterDataGridKampagnen(object sender, object e)
{
using (var ctx = new myEntities())
{
var query = from k in ctx.MyTbl select k;
var lstMyTbl = query.ToList();
if(this.FilterVal1.Text.Trim().Length > 0)
{
lstMyTbl = lstMyTbl.Where(x => x.val1.ToLower().Contains(this.FilterVal1.Text.ToLower())).ToList();
}
if (FilterVal2.SelectedDate != null)
{
lstMyTbl = lstMyTbl.Where(x => x.val2 >= FilterVal2.SelectedDate).ToList();
}
if (FilterVal3.SelectedDate != null)
{
lstMyTbl = lstMyTbl.Where(x => x.val3 <= FilterVal3.SelectedDate).ToList();
}
this.MyDataGrid.ItemsSource = lstMyTbl;
}
}

我现在想知道这是否是正确的(推荐的)方式来实现一个DataGrid元素的过滤器?特别是在过滤器之间应该存在与关系的参考上,并且在空过滤器的情况下,根本不应该考虑它。

感谢mm8。可能是"推荐的"。这里的解决方案将是MVVM设计模式中的实现。我根据MVVM设计模式修改了我的代码。我的DataGrid元素看起来像这样(这里重要的是ItemSource到ListData的绑定。ListData是ViewModel中根据MVVM设计模式的一个列表):

<DataGrid ItemsSource="{Binding ListData}" IsReadOnly="True" HeadersVisibility="Column" AutoGenerateColumns="False" Grid.Row="1" Grid.Column="0" x:Name="DataGridKampagnen" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="Turquoise" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="BorderThickness" Value="0,0,1,2" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="id" Binding="{Binding id}" Visibility="Hidden" Width="*"/>
<DataGridTextColumn Header="fileId" Binding="{Binding fileId}" Visibility="Hidden" Width="*"/>
<DataGridTextColumn Header="val1" Binding="{Binding val1}" Width="*"/>
<DataGridTextColumn Header="val2" Binding="{Binding val2, StringFormat={0:dd.MM.yy}}" Width="*"/>
<DataGridTextColumn Header="val3" Binding="{Binding val3, StringFormat={0:dd.MM.yy}}" Width="*"/>
</DataGrid.Columns>
</DataGrid>

我的两个日期选择器和文本框是这样的:

<TextBox Grid.Row="0" IsReadOnly="False" Grid.Column="1"  Name="FilterVal1" Style="{StaticResource FilterInput}" Text="{Binding Val1, UpdateSourceTrigger=PropertyChanged}"/>
<DatePicker Grid.Row="1" Grid.Column="1" Name="FilterVal2" Style="{StaticResource FilterInput}" SelectedDate="{Binding Val2}"/>
<DatePicker Grid.Row="2" Grid.Column="1" Name="FilterVal3" Style="{StaticResource FilterInput}" SelectedDate="{Binding Val3}"/>

提供绑定到ListData的数据的方法是这样的:

private List<MyTbl> GetMyTblLst()
{
using (var ctx = new myEntities())
{
var query = from k in ctx.MyTbl select k;
var lstMyTbl = query.ToList();
if(Val1.Trim().Length > 0)
{
lstMyTbl = lstMyTbl.Where(x => x.val1.ToLower().Contains(Val1.ToLower())).ToList();
}
if (Val2 != null)
{
lstMyTbl = lstMyTbl.Where(x => x.val2 >= Val2).ToList();
}
if (Val3 != null)
{
lstMyTbl = lstMyTbl.Where(x => x.val3 <= Val3).ToList();
}
return lstMyTbl;
}
}

到ListData的绑定是这样的:

public List<MyTbl> ListData => GetMyTblLst();

这种方法有效,是一种非常干净和可重用的解决问题的方法。