【问题标题】:WPF DataGrid rows filtering using TextBox and DatePicker elements使用 TextBox 和 DatePicker 元素过滤 WPF DataGrid 行
【发布时间】:2021-12-09 04:38:06
【问题描述】:

我目前正在开发我的第一个 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 元素实现过滤器的正确(推荐)方法?尤其是在过滤器之间应该存在 AND 关系的参考上,如果是空过滤器,则根本不应该考虑它。

【问题讨论】:

  • 我认为“推荐”的方式是过滤绑定到 ItemsSource 属性的源集合,但从同一个集合中添加或删除项目或创建项目并不重要一个像你在这里做的新的。
  • 你能给我一个例子,说明如何通过过滤 ItemSource 属性来过滤 DataGrid 吗?
  • 唯一的区别是您基本上将代码移动到视图模型。您应该阅读 MVVM 设计模式。

标签: c# wpf xaml


【解决方案1】:

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

<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();

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-25
    • 2016-08-31
    • 2017-08-06
    • 2011-11-10
    • 2015-04-10
    • 2019-01-26
    • 2011-07-11
    相关资源
    最近更新 更多