wpf xaml how to nicely stack or list multiple datagrids

42 Views Asked by At

I need to show columnar data like in a DataGrid, with an Expander to show the name of the dataset and to hide or show that dataset. Then, I need to stack several of such Expander DataGrid combinations.

The problem is that when I put all this in a StackPanel, then, vertically, the expanded Expander covers the next Expander(s). I found posts on adding events to adjust the Height of the Expander on the Expanded/Collapsed events, but had not yet success with that. But horizontally, the DataGrid nicely fits the entire width, with an asterisk in ColumnWidth, and AutoGenerateColumns set to False.

Or, if I put all this in a ListView, vertically, the expanded Expander nicely pushes the next lower Expander down, so that nothing is covered and all is displayed nicely. But now, horizontally, the asterisk in ColumnWidth does not work, instead, an extra, empty, column appears to the right which eats almost 100 percent of the entire width of the DataGrid, leaving the two intended columns very small, which is absolutely not workable.

For easier experimenting, I gave up on Data Binding and added data to the controls in code-behind, which turned out to be very simple. This is not really possible for a DataGrid inside a ListView, because such DataGrid controls are created dynamically and cannot be referenced from code-behind. The fix for this is to use a separate UserControl with one Expander and one DataGrid, and assign multiple instances of such UserControl to the ListView in code-behind. (just like we were used to do with the Tcl-Tk toolkit long ago :-)

Here is the essential part of the code for the UserControl for use inside the StackPanel or ListView:

<UserControl x:Class="Project1.Views.ExpanderDatagrid" ... >
    <Expander Name="MyExpander" IsExpanded="True" Expanded="MyExpander_Expanded" Collapsed="MyExpander_Collapsed">
        <StackPanel Name="MyPanel">
            <DataGrid Name="MyDataGrid"
                    HorizontalAlignment="Stretch"
                    AutoGenerateColumns="False"
                    ColumnWidth="*"
                    Height="300">
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="MyColumnLeft" Header="Name" Binding="{Binding Path=Name}" />
                    <DataGridTextColumn x:Name="MyColumnRight" Header="Value" Binding="{Binding Path=Value}" />
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </Expander>
</UserControl>

Code behind:

namespace Project1.Views
{
  public partial class ExpanderDatagrid : UserControl
  {
    public ExpanderDatagrid(string HeaderText, List<DatagridRow> TableData)
    {
        InitializeComponent();
        MyExpander.Header = HeaderText;
        MyDataGrid.ItemsSource = TableData;
    }
    private void MyExpander_Expanded(object sender, RoutedEventArgs e)
    {
        MyExpander.Height = 200; // new GridLength(1, GridUnitType.Auto);
    }
    private void MyExpander_Collapsed(object sender, RoutedEventArgs e)
    {
        MyExpander.Height = 30;
    }
  }//end class
}//end ns

The above UserControl is used in this XAML:

<StackPanel Name="MyPanelForListOfDatagrids" Height="200" HorizontalAlignment="Stretch" Background="Green">
</StackPanel>
<ListView Name="TheListView">
</ListView>

with this code-behind:

var TableData = DatagridRow.GetRows();
{
    var EDG_Bev = new ExpanderDatagrid("Beverages", TableData);
    var EDG_Veg = new ExpanderDatagrid("Vegetables", TableData);
    MyPanelForListOfDatagrids.Children.Add(EDG_Bev);
    MyPanelForListOfDatagrids.Children.Add(EDG_Veg);
}
{
    var EDG_Bev = new ExpanderDatagrid("Beverages", TableData);
    var EDG_Veg = new ExpanderDatagrid("Vegetables", TableData);
    TheListView.Items.Add(EDG_Bev);
    TheListView.Items.Add(EDG_Veg);
}

The result when this runs:

screenshot

Here, in the StackPanel, when you click the Show button for Beverages in the Expander with the green background, the DataGrid for Vegetables becomes invisible behind the expanded Beverages, but the columns nicely fill the entire parent width.

Contrary, the ListView shows vertically what we want, but horizontally is wrong. I think I forgot the Stretch setting, but first I must get rid of that extra, empty, third column.

My questions are:

  • How to get the StackPanel items so that all Expanders can be expanded without anything covered or hidden? Or:
  • How get rid of that extra column in the ListView? Or:
  • Am I trying to use StackPanel and ListView for the wrong purposes and is there a better way to stack a list of DataGrids?
0

There are 0 best solutions below