2

I'm trying to load dynamic data with rows and columns to a GridView or ListView control so it looks like a table with headers and rows. My aim is to do something like this:

ListView table layout

I've found that layout explanation on this site : ListView but the problem is I've tried it out for dynamic columns but nothing worked...

My code so far looks like this:

<ListView ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" 
              Name="GridViewList" Margin="0,20,0,0" HorizontalAlignment="Stretch" IsHitTestVisible="False" SelectedIndex="-1">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="localVM:GridViewRow">
                <Grid>
                    <ItemsControl ItemsSource="{x:Bind Columns}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate x:DataType="localVM:GridViewColumn">
                                <Grid x:Name="ColumnsViewGrid">
                                    <TextBlock Grid.Row="0" Text="{x:Bind Title}" TextWrapping="WrapWholeWords" FontWeight="Bold" TextTrimming="CharacterEllipsis"
                                               Visibility="{Binding IsHeader, Converter={StaticResource BoolToVisibilityConverter}}"/>
                                    <TextBlock Grid.Row="1" Text="{x:Bind Value}" TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis"/>
                                </Grid>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Columns are populated dynamically and everytime they have a different count.

Columns are stored in GridViewRow class:

public int RowIndex { get; private set; }

    public List<GridViewColumn> Columns { get; }

    /// <summary>
    /// Initialized a new instance of <see cref="GridViewRow"/> class
    /// </summary>
    /// <param name="rowIndex">Row index</param>
    /// <param name="isHeader">If row is header it's true</param>
    /// <param name="columns">Columns </param>
    /// <param name="headers">Table headers </param>
    public GridViewRow(int rowIndex, List<GridViewColumn> columns)
    {
        this.RowIndex = rowIndex;

        this.Columns = columns;
    }

And GridViewColumn class looks like this:

public string Value { get; private set; }

    public string Title { get; private set; }

    public bool IsHeader { get; private set; }

    public GridViewColumn(string title, string value, bool isHeader)
    {
        this.Title = title;
        this.Value = value;
        this.IsHeader = IsHeader;
    }

Many thanks for your help!

marczulajtis
  • 127
  • 2
  • 15
  • If this is pure UWP, maybe this would be a better solution? https://learn.microsoft.com/en-us/windows/uwpcommunitytoolkit/controls/datagrid – Depechie Jun 21 '18 at 11:43
  • What "dynamic columns" actually you mean here? Could you please detail it or for example? Since I cannot see out "dynamic" from the above image. – Sunteen Wu Jun 22 '18 at 06:15
  • By dynamic columns I mean the number of columns that has always different count, so I cannot directly specify how many of them will be in xaml. I have GridViewRow class that has List as Columns. And GridViewColumn class has Title, Value and IsHeader properties. – marczulajtis Jun 22 '18 at 06:53
  • Depechie - thanks for your reply, but I cannot use the DataGrid control because of the customer windows version, which at some point will have to be updated, and for some customers it's not an option.. SO I have to figure out the other way around. – marczulajtis Jun 22 '18 at 06:57

1 Answers1

1

All,

I managed to solve the issue with below example:

<ListView Grid.Row="2" ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" ItemContainerStyle="{StaticResource ListViewItemStyle}"
              Name="ListViewTemp" Margin="0,20,0,0" HorizontalAlignment="Stretch" IsHitTestVisible="False" BorderBrush="DimGray" BorderThickness="0,0,0,1">>
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="localVM:Row">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <ItemsControl Grid.Row="0" ItemsSource="{x:Bind Columns}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate x:DataType="localVM:Column">
                                <ScrollViewer>
                                    <Grid Padding="10" Background="{x:Bind IsHeader, Converter={StaticResource BoolToBackgroundConverter}}"
                                            BorderBrush="DimGray" BorderThickness="0,0,1,0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="{x:Bind Size}"/>
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Text="{x:Bind Title}" TextWrapping="WrapWholeWords" FontWeight="Bold" TextTrimming="CharacterEllipsis"
                                               Visibility="{Binding IsHeader, Converter={StaticResource BoolToVisibilityConverter}}" Foreground="White"/>
                                        <TextBlock Text="{x:Bind Value}" TextWrapping="WrapWholeWords" TextTrimming="CharacterEllipsis"/>
                                    </Grid>
                                </ScrollViewer>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                    </ItemsControl>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

And I'm calculating a Size of a column like this:

double listViewWidth = ListViewTemp.ActualWidth;

        double columnWidth = listViewWidth / (rows[0].Columns.Count);

        foreach (var row in rows)
        {
            foreach (var column in row.Columns)
            {
                column.Size = new GridLength(columnWidth);
            }
        }

Thanks for all your help!

marczulajtis
  • 127
  • 2
  • 15