c# - 如何从 SQL 进行过滤和分组 ListView

标签 c# sql-server wpf filtering grouping

我如何让我的 listview 同时进行分组和过滤,因为我一次只能让它做一件事。我几乎尝试了所有可能的方法,但没有一个奏效。当我删除

 public string SelectedParam { get { return _selectedParam; } set { _selectedParam = value; OnPropertyChanged("SelectedParam");
        if (_selectedParam == "Krydsmål") { BindData(); } else { hjuldata.ItemsSource = FilterKategori().Tables[0].DefaultView; ; } } }

然后分组有效但过滤无效

我想知道我是否可以使用 sql 来填充而不是填充和过滤,然后让 ListView 进行过滤,就像您可以手动添加的项目一样

我的过滤组合框:

 <ComboBox x:Name="Krydsmålbox" Foreground="#FFEAEAEA" Background="#FF303030" FontSize="12" 
Style="{StaticResource ComboBoxTest2}"  ItemTemplate="{StaticResource cmbTemplate2}" 
ItemsSource="{Binding}"  SelectedValuePath="Krydsmålene"
SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor, 
                  AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF303030" Height="40" DockPanel.Dock="Top" Margin="586,42,379,0"/>

ListView

 <ListView x:Name="hjuldata" BorderBrush="#FF303030" Foreground="#FF00FB0B"  ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" Background="#FF303030" ItemsSource="{Binding}" Margin="-160,242,11,22" Grid.ColumnSpan="6" Grid.Row="3" Style="{DynamicResource ListViewStyle2}" DockPanel.Dock="Bottom" Height="576">
 <ListView.View>
 <GridView>
 <GridView.ColumnHeaderContainerStyle>
 <Style TargetType="{x:Type GridViewColumnHeader}">
 <Setter Property="Background" Value="Black" />
 <Setter Property="Foreground" Value="#FFEAEAEA"/>
 <Setter Property="FontWeight" Value="Bold" />
 </Style>
 </GridView.ColumnHeaderContainerStyle>
 <GridViewColumn Header="" >
 <GridViewColumn.CellTemplate>
 <DataTemplate>
 <Image Source="{Binding Billed, Converter={StaticResource nullImageConverter}}" Width="20" Height="20" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,15,0"/>
 </DataTemplate>
 </GridViewColumn.CellTemplate>
 </GridViewColumn>
 <GridViewColumn Header="Model" Width="140" >
 <GridViewColumn.CellTemplate>
 <DataTemplate>
 <TextBlock x:Name="Txt" Text="{Binding Model}" Foreground="#FF00FB0B" />
 </DataTemplate>
 </GridViewColumn.CellTemplate>
 </GridViewColumn>
 <GridViewColumn Header="Årgang" Width="100">
 <GridViewColumn.CellTemplate>
 <DataTemplate>
 <TextBlock x:Name="Txt" Text="{Binding Årgang}" Foreground="#FF00FB0B" />
 </DataTemplate>
 </GridViewColumn.CellTemplate>
 </GridViewColumn>
 <GridViewColumn Header="Motor Type" Width="150" >
 <GridViewColumn.CellTemplate>
 <DataTemplate>
 <TextBlock x:Name="Txt" Text="{Binding [Motor Type]}" Foreground="#FF00FB0B" />
 </DataTemplate>
 </GridViewColumn.CellTemplate>
 </GridViewColumn>
 <GridViewColumn>
  <GridViewColumn.CellTemplate>
  <DataTemplate>
  <TextBlock x:Name="Txt" Text="{Binding Krydsmålet}" Foreground="#FF00FB0B" />
  </DataTemplate>
  </GridViewColumn.CellTemplate>
  </GridViewColumn>
  <GridViewColumn>
  <GridViewColumn.CellTemplate>
  <DataTemplate>
  <TextBlock x:Name="Txt" Text="{Binding Centerhul}" Foreground="#FF00FB0B" />
  </DataTemplate>
  </GridViewColumn.CellTemplate>
  </GridViewColumn>
  <GridViewColumn Header="ET" Width="auto">
  <GridViewColumn.CellTemplate>
  <DataTemplate>
  <TextBlock x:Name="Txt" Text="{Binding ET}" Foreground="#FF00FB0B" />
  </DataTemplate>
  </GridViewColumn.CellTemplate>
  </GridViewColumn>
  <GridViewColumn Header="Bolter" Width="100">
  <GridViewColumn.CellTemplate>
  <DataTemplate>
  <TextBlock x:Name="Txt" Text="{Binding Bolter}" Foreground="#FF00FB0B" />
  </DataTemplate>
  </GridViewColumn.CellTemplate>
  </GridViewColumn>
  <GridViewColumn Header="Dæk" Width="300">
  <GridViewColumn.CellTemplate>
  <DataTemplate>
  <TextBlock x:Name="Txt" Text="{Binding Dæk}" Foreground="#FF00FB0B" />
  </DataTemplate>
  </GridViewColumn.CellTemplate>
  </GridViewColumn>
  <GridViewColumn Header="Fælge" Width="200">
  <GridViewColumn.CellTemplate>
  <DataTemplate>
  <TextBlock x:Name="Txt" Text="{Binding Fælge}" Foreground="#FF00FB0B" />
  </DataTemplate>
  </GridViewColumn.CellTemplate>
  </GridViewColumn>
  </GridView>
  </ListView.View>

分组方式

  <ListView.GroupStyle>
  <GroupStyle>
  <GroupStyle.ContainerStyle>
  <Style TargetType="{x:Type GroupItem}">
  <Setter Property="Template">
  <Setter.Value>
  <ControlTemplate>
  <Expander IsExpanded="False"  BorderBrush="#FFEAEAEA" BorderThickness="0,0,0,1" >
 <Expander.Header>
 <StackPanel Orientation="Horizontal" DataContext="{Binding Items}">
 <Image Source="{Binding Billed, Converter={StaticResource nullImageConverter}}" Width="20" Height="20" Stretch="Fill" VerticalAlignment="Center"  Margin="0,0,15,0"/>
 <TextBlock  Text="{Binding Mærke}" FontWeight="Bold" Foreground="#FFEAEAEA" FontSize="22" VerticalAlignment="Bottom" />
 <TextBlock Text="{Binding Krydsmålene}"  FontWeight="Bold" Foreground="#FFFBFB00" FontSize="22" VerticalAlignment="Bottom" Margin="0,0,150,0" TextAlignment="Center" />
 </StackPanel>
 </Expander.Header>
 <ItemsPresenter />
 </Expander>
 </ControlTemplate>
 </Setter.Value>
 </Setter>
 </Style>
 </GroupStyle.ContainerStyle>
 </GroupStyle>
 </ListView.GroupStyle>
 </ListView>

CS:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _selectedParam;
    public MainWindow()
    {
        InitializeComponent();
        BindData();
        ICollectionView dataView = CollectionViewSource.GetDefaultView(hjuldata.ItemsSource);
        dataView.GroupDescriptions.Add(new PropertyGroupDescription("Mærke"));

    }

     public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public string SelectedParam { get { return _selectedParam; } set { _selectedParam = value; OnPropertyChanged("SelectedParam");
    if (_selectedParam == "Krydsmål") { BindData(); } else { hjuldata.ItemsSource = FilterKategori().Tables[0].DefaultView; ; } } }

    private void BindData()
    {
        hjuldata.ItemsSource = Kategori().Tables[0].DefaultView;
    }
    public DataSet Kategori()
    {

        Data = @"Select ps.Mærket AS Mærke, P.DataID, P.Billed, P.Model, P.Årgang, P.[Motor Type], P.Krydsmålet, P.Centerhul, P.ET,P.Bolter, P.Dæk, P.Fælge ,PS.Krydsmålene from Data.Hjuldata P  inner join Data.Mærke PS on P.MærkeID = PS.MærkeID ORDER BY ps.Mærket";
        //SQL statement to fetch entries from Hjuldata
        DataSet dsdata = new DataSet();

        //Open SQL Connection
        using (conn = new SqlConnection(connStrings))
        {
            conn.Open();

            //Initialize command object                
            using (cmd = new SqlCommand(Data, conn))
            {                
                SqlDataAdapter adapters = new SqlDataAdapter(cmd);

                //Fill the result set

                adapters.Fill(dsdata);
                conn.Close();
            }
        }
        return dsdata;
    }

    public DataSet FilterKategori()
    {
        Data = @"Select ps.Mærket AS Mærke, P.DataID, P.Billed, P.Model, P.Årgang, P.[Motor Type], P.Krydsmålet, P.Centerhul, P.ET,P.Bolter, P.Dæk, P.Fælge ,PS.Krydsmålene from Data.Hjuldata P  inner join Data.Mærke PS on P.MærkeID = PS.MærkeID WHERE Krydsmålet = @param1";

        //SQL statement to fetch entries from products
        DataSet dsdata = new DataSet();

        //Open SQL Connection
        using (conn = new SqlConnection(connStrings))
        {
            conn.Open();

            //Initialize command object

            using (cmd = new SqlCommand(Data, conn))
            {
                cmd.Parameters.AddWithValue("@param1", SelectedParam);
                SqlDataAdapter adapters = new SqlDataAdapter(cmd);
                //Fill the result set
                adapters.Fill(dsdata);
                conn.Close();
            }
        }  
        return dsdata;
    }

有人可以帮我解决这个问题吗?

最佳答案

我认为您的问题是您使用的是 ADO.NET 数据 View 抽象,而不是应该更易于使用的 WPF 数据 View 抽象。在 WPF 中,当您将一个集合或 DataTable 绑定(bind)到一个 ItemsControl 时,会创建一个数据 View 对象,该对象基本上用作您的集合或 DataTable 上的一层.通过这样做,您可以潜在地将同一个集合绑定(bind)到多个 ItemsControls,但通过对为同一个集合创建的两个不同数据 View 进行不同的过滤和分组,从而获得该数据的不同“ View ”。

在您的情况下,您要绑定(bind)到 DataTable,这比仅绑定(bind)到实现 IList 的集合更困惑。对于 DataTable 有一个 DataView 类,它是 ADO.NET 的一部分,您的 WPF 数据 View 基本上将作为一个层,这个 DataView功能更有限(此 ADO.NET DataView 是您当前在代码中使用的内容)。

无论哪种方式,要获取 WPF 数据 View ,您只需像这样向 ItemsSource 请求它:

ICollectionView dataView = CollectionViewSource.GetDefaultView(myListView.ItemsSource);

现在您需要将 ICollectionView 转换为对设置过滤器和分组更有用的东西。在您的情况下,您有一个 DataTable,因此您需要将其转换为 BindingListCollectionView。不幸的是,这比您为 IList(它是一个 ListCollectionView)获得的数据 View 更受限制,但是您有一个 DataTable,所以我们暂时使用它(我总是使用 IList,所以我以前从未在生产中实际实现过 DataTable 绑定(bind))。

BindingListCollectionView 没有可操作的 Filter 属性,因此您必须使用其 CustomFilter 属性来指定您想要的部分 SQL用于过滤您的集合(基本上是您将放在 WHERE 子句中的内容)。就分组而言,我从未在 DataTable 绑定(bind)上使用过它,但我希望它只是通过更新数据 View 上的 GroupDescriptions 来工作。

所以基本上总而言之,我会获取 WPF 数据 View 抽象而不是您当前正在使用的 ADO.NET 数据 View 抽象,并在其上设置过滤器和分组。此外,我建议只将您的数据作为 IList 引入,或者将其转换为 IList,因为这些在 WPF 中更容易使用。

关于c# - 如何从 SQL 进行过滤和分组 ListView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37223123/

相关文章:

c# - 无法让 Antlr4 解析器遵循隐式乘法的运算顺序

c# - Azure webjob 如何访问托管站点文件夹

java - 集成身份验证错误 Microsoft SQL Server 2017 和 Knime

wpf - 如何处理父控件中的子事件

c# - wpf 窗口刷新首先起作用,然后停止

wpf - 在 WPF 用户控件上使用非简单类型的依赖属性的模式

c# - 在 C# 中,我应该使用 Enum、static Class、Dictionary 还是 Struct 来表示这些 "labeled floats"?

c# - 在C#中创建类时缩进时出现几个错误

php - 如何在数据库中写入字符

SQL Server存储过程插入多个表