Search code examples
wpfsqlitedatagrid

Add a Control to autogenerated ColumnHeader of DataGrid in WPF getting data from SQLite database


I need to create an excel like filter for my data imported from SQLite database.

Importing and showing data from database is doing well with

private void UpdateDataGrid(SQLiteConnection con, string sql)
{
    DataSet dataSet = new DataSet();
    SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(sql, con);
    dataAdapter.Fill(dataSet);

    dgMaterials.ItemsSource = dataSet.Tables[0].DefaultView;
}

AutoGenerateColumns is true so that I get something like this:

enter image description here

Data are shown in left side datagrid. In right side listbox I collect the generated column headers with

private void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    lb.Items.Add(e.Column.Header.ToString());
}

As I said, I want to create excel like filter buttons in header row beside every header text like this

enter image description here

On XAML site I started like this

<DataGrid x:Name="dgMaterials"
          IsReadOnly="True"
          CanUserReorderColumns="False"
          CanUserResizeColumns="False"
          CanUserSortColumns="False"
          DockPanel.Dock="Left" AutoGeneratingColumn="dg_AutoGeneratingColumn"
          AlternatingRowBackground="LightGray">

    ... input a button next to every header text ...


</DataGrid>

Autocreating of buttons in Headers is working with:

private void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    ////string headertext = e.Column.Header.ToString();

    //StackPanel sp = new StackPanel();
    //TextBlock tb = new TextBlock();
    //tb.Text = e.Column.Header.ToString();
    //sp.Children.Add(tb);

    dgMaterials.AutoGeneratingColumn += (ss, ee) =>
    {
        Button b = new Button() { Content = "...", Name = "btn_" + ee.PropertyName };
        b.Click += HeaderFilterButtonClick;
        StackPanel stackPanel = new StackPanel() { Orientation = Orientation.Horizontal };
        stackPanel.Children.Add(new TextBlock() { Text = ee.PropertyName, VerticalAlignment = VerticalAlignment.Center });
        //stackPanel.Children.Add(new Button() { Content = "...", Name = "btn_" + ee.PropertyName });
        stackPanel.Children.Add(b);
        ee.Column.Header = stackPanel;
    };

    lb.Items.Add(e.Column.Header.ToString());
}

thanks @mm8

last problem:

no button is created for the first column header and I don't know why:

enter image description here

ideas?


Solution

  • You could set the Header property of the column to a Panel in the AutoGeneratingColumn event handler:

    dgMaterials.AutoGeneratingColumn += (ss, ee) => 
    {
        StackPanel stackPanel = new StackPanel() { Orientation = Orientation.Horizontal };
        stackPanel.Children.Add(new TextBlock() { Text = ee.PropertyName, VerticalAlignment = VerticalAlignment.Center });
        stackPanel.Children.Add(new Button() { Content = "..." });
        ee.Column.Header = stackPanel;
    };