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:
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!
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!