Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] 🧪 DataTable Initial Prototype #418

Merged
merged 38 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
01f8685
Initial commit of DataTable experiment with some intial setup
michael-hawker Apr 7, 2023
f49f99a
Bring over HeaderedItemsControl from Toolkit, show 'Tradtional' setup…
michael-hawker Apr 7, 2023
5c98d72
Simplify HeaderedItemsControl, give it Footer support as well
michael-hawker Apr 8, 2023
d4664bc
Implement intial test implementation of DataTable coordinated panel
michael-hawker Apr 10, 2023
3ad8a3e
Rename DataTable to DataRow, setup another example for target experie…
michael-hawker Apr 11, 2023
51b151f
Setup initial placeholder classes and move to Folder
michael-hawker Apr 12, 2023
02613a0
Initial setup of DataTable as a panel for the Header and its logic
michael-hawker Apr 12, 2023
456973e
Initial Prototype is working for DataRow coordination with new DataTa…
michael-hawker Apr 12, 2023
a3ebca2
Add discussion-id to DataTable doc
michael-hawker Apr 12, 2023
4fb678e
Add HeaderedTreeView and test of DataTable + TreeView in Samples
michael-hawker May 4, 2023
8171c0f
Add ability to show/hide a column sizer in header
michael-hawker Jun 14, 2023
246cb59
Initial test to resize item columns based on header column
michael-hawker Jun 14, 2023
b347044
Rename sample page to call out 'Hybrid' scenario to help identify
michael-hawker Jun 15, 2023
e83b989
Initial implementation of auto layout columns which size to their con…
michael-hawker Jun 16, 2023
2dcca73
Apply XAML Styler
michael-hawker Jun 16, 2023
3ad7c12
Add virtualization example, set DataColumn to Auto size by default
michael-hawker Jun 19, 2023
5bb3ba0
Add virtualization example, set DataColumn to Auto size by default
michael-hawker Jun 21, 2023
a7ee617
Try and make test more generic (not sure if working or not, but wasn'…
michael-hawker Jun 21, 2023
7a0d9bd
Better connect the DataRow and DataTable elements with a HashSet
michael-hawker Jun 21, 2023
b3c0a7d
Simplify DataColumn resizer with new optimizations from DataTable/Dat…
michael-hawker Jun 23, 2023
61549a4
Add ability to resize columns and them to react in realtime
michael-hawker Jun 23, 2023
649801a
Scope to just UWP/WASDK for now
michael-hawker Jun 23, 2023
d47bf3d
Rename DataColumn private method for clarity against DataTable method…
michael-hawker Jun 30, 2023
28fdb5a
TODO: Bug when resizing columns and going out of range of size of con…
michael-hawker Jun 30, 2023
c209eaa
Add initial code to support a 'TreeTable' scenario with TreeView + Da…
michael-hawker Jun 30, 2023
7a93d68
Add ColumnSpacing property to DataTable
michael-hawker Jul 1, 2023
b1aac74
Design related (sample) tweaks
niels9001 Jul 10, 2023
186133a
XAML styling
niels9001 Jul 10, 2023
bac1629
Switch to Toolkit components
niels9001 Jul 11, 2023
8db98a8
Update Generic.xaml
niels9001 Jul 11, 2023
977ee2a
Move HeaderedControls dependency to samples only
michael-hawker Jul 17, 2023
6728a74
Clean-up multitarget.props to see if CI can be fixed
michael-hawker Jul 17, 2023
a1885cb
Update tooling, added missing icon
Arlodotexe Jul 17, 2023
3a70794
Add StickyHeaderBehavior to DataTable Virtualization sample
michael-hawker Jul 17, 2023
4c921f4
Upgrade extensions to be in-sync across sub-module updated version
michael-hawker Jul 24, 2023
78b1a08
Add 'No/Blank Header' sample to DataTable for simple data table scena…
michael-hawker Aug 1, 2023
ddab333
Update components/DataTable/src/CommunityToolkit.WinUI.Controls.DataT…
Arlodotexe Aug 2, 2023
da6fa9c
Update components/DataTable/src/CommunityToolkit.WinUI.Controls.DataT…
Arlodotexe Aug 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions components/DataTable/OpenSolution.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@ECHO OFF

powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %*
Binary file added components/DataTable/samples/Assets/DataTable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions components/DataTable/samples/DataTable.Samples.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="MSBuild.Sdk.Extras/3.0.23">
<PropertyGroup>
<ToolkitComponentName>DataTable</ToolkitComponentName>
</PropertyGroup>

<!-- Sets this up as a toolkit component's sample project -->
<Import Project="$(ToolingDirectory)\ToolkitComponent.SampleProject.props" />
</Project>
104 changes: 104 additions & 0 deletions components/DataTable/samples/DataTable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: DataTable
author: michael-hawker
description: DataTable provides a set of components which can transform an ItemsControl or ListView into a simple table like experience.
keywords: DataTable, Control, Layout
dev_langs:
- csharp
category: Controls
subcategory: Layout
discussion-id: 415
issue-id: 0
icon: Assets/DataTable.png
---

# DataTable

DataTable provides a set of components which can transform an ItemsControl or ListView into a simple table
like experience. It is an intermediary between a list and a full-blown `DataGrid` experience.

It provides resizable columns and allows for complete styling control out-of-the-box.

It is useful in scenarios where:

- A simplified/modern style is required as more of a table of data
- Cell-level selection isn't required
- Editing every piece of data in the table isn't required

## Traditional Method

To compare how the DataTable works, we'll start with the traditional example of how a `ListView` (or `HeaderedItemsControl`)
can be made to look like a table of data:

> [!Sample ListViewTableSample]

There are limitations here with having fixed column sizes that can be difficult to align. Their definitions are
also duplicated, and every item is recreating this layout and duplicating it within the Visual Tree.

## DataRow Hybrid Setup

As a first step, moving to **DataTable** is easy, just replace the `Grid` in your `ItemsTemplate` with the `DataRow` panel
and remove the Column attributes from your controls. `DataRow` automatically will lay each subsequent control in the next column
for you automatically:

> [!Sample DataTableHybridSample]

## DataTable Setup

The `DataTable` setup provides an easier way to define and manage your columns within your header for this coordinated effort
to layout items as a table within a `ListView` or `ItemsControl`.

A _"DataTable"_ is actually made of three components a `DataTable` component in the `Header` of an `HeaderedItemsControl` or
`ListView` control. There you can define `DataColumn`s within the table and configure their size and other settings.
Finally, as you saw above, the `DataRow` panel itself is within the `DataTemplate` of your `ItemTemplate` for the items control
you use. For example:

> [!Sample DataTableSample]

### Simple Table

If you don't need headers and want to show a simple table of data, just don't provide any content to the `DataColumn` headers:

> [!Sample DataTableBlankHeaderSample]

### Virtualization

Since `DataTable` is just built on top of `ListView` it can handle many data rows just the same as a ListView can.

> [!Sample DataTableVirtualizationSample]

## DataTable + TreeView (Test)

The `DataTable` setup works with other types of views as well, like `TreeView`. This enables a "TreeGrid" like experience, if required.

An example here with the `HeaderedTreeView` is for testing this scenario:

> [!Sample TreeTableSample]

## Comparison of DataTable to DataGrid

Benefits/Similarities:

- Easier to use/more intuitive to setup/customize as using base XAML building blocks without complex templating/styling
- Therefore Styling/Look-and-feel much more in developer's control, based off common controls
- Usable with `ItemsControl` (static) and `ListView` (for selection)
- Grouping provided by `ItemsControl` itself
- More light-weight of a component in-general for Visual Tree
- Support row virtualization via `ItemsStackPanel`
- Still provides column resizing via header

Limitations:

- No Row Headers
- No Built-in Cell Editing
- No Built-in Cell Selection
- No Built-in Sorting
- No Detail Template
- No Grid lines

However, most of these limitations can still be enabled by the developer to an extent with modifications to templates or
with additional code.

For instance, sorting can be provided like so:

TODO: Add Header based Sorting sample
43 changes: 43 additions & 0 deletions components/DataTable/samples/DataTableBlankHeaderSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Page x:Class="DataTableExperiment.Samples.DataTableBlankHeaderSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DataTableExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<controls:HeaderedItemsControl ItemsSource="{x:Bind InventoryItems}">
<controls:HeaderedItemsControl.Header>
<controls:DataTable ColumnSpacing="16">
<controls:DataColumn />
<controls:DataColumn />
<controls:DataColumn DesiredWidth="80" />
<controls:DataColumn />
</controls:DataTable>
</controls:HeaderedItemsControl.Header>
<controls:HeaderedItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:InventoryItem">
<controls:DataRow>
<TextBlock VerticalAlignment="Top"
Text="{x:Bind Id}" />
<TextBlock VerticalAlignment="Top"
Text="{x:Bind Name}" />
<TextBlock VerticalAlignment="Top"
Text="{x:Bind Description}"
TextWrapping="WrapWholeWords" />
<TextBlock VerticalAlignment="Top"
Text="{x:Bind Quantity}" />
</controls:DataRow>
</DataTemplate>
</controls:HeaderedItemsControl.ItemTemplate>
<controls:HeaderedItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!-- Add some Row Spacing -->
<Setter Property="Margin" Value="0,4,0,4" />
</Style>
</controls:HeaderedItemsControl.ItemContainerStyle>
</controls:HeaderedItemsControl>
</Page>
49 changes: 49 additions & 0 deletions components/DataTable/samples/DataTableBlankHeaderSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using CommunityToolkit.WinUI.Controls;

namespace DataTableExperiment.Samples;

[ToolkitSample(id: nameof(DataTableBlankHeaderSample), "DataTable Blank Header Example", description: $"A sample for showing how to create and use a {nameof(DataRow)} control without a header.")]
public sealed partial class DataTableBlankHeaderSample : Page
{
public ObservableCollection<InventoryItem> InventoryItems { get; set; } = new()
{
new()
{
Id = 1002,
Name = "Hydra",
Description = "Multiple Launch Rocket System-2 Hydra",
Quantity = 1,
},
new()
{
Id = 3456,
Name = "MA40 AR",
Description = "Regular assault rifle - updated version of MA5B or MA37 AR",
Quantity = 4,
},
new()
{
Id = 5698,
Name = "Needler",
Description = "Alien weapon well-known for its iconic design with pink crystals",
Quantity = 2,
},
new()
{
Id = 7043,
Name = "Ravager",
Description = "An incendiary plasma launcher",
Quantity = 1,
},
// TODO: Add more items, maybe abstract these to a helper for other samples?
};

public DataTableBlankHeaderSample()
{
this.InitializeComponent();
}
}
50 changes: 50 additions & 0 deletions components/DataTable/samples/DataTableHybridSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Page x:Class="DataTableExperiment.Samples.DataTableHybridSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DataTableExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<controls:HeaderedItemsControl ItemsSource="{x:Bind InventoryItems}">
<controls:HeaderedItemsControl.Header>
<Grid Padding="0,8"
ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Id" />
<TextBlock Grid.Column="1"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Name" />
<TextBlock Grid.Column="2"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Description" />
<TextBlock Grid.Column="3"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Quantity" />
</Grid>
</controls:HeaderedItemsControl.Header>
<controls:HeaderedItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:InventoryItem">
<controls:DataRow>
<TextBlock Text="{x:Bind Id}" />
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Description}" />
<TextBlock Text="{x:Bind Quantity}" />
</controls:DataRow>
</DataTemplate>
</controls:HeaderedItemsControl.ItemTemplate>
<controls:HeaderedItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</controls:HeaderedItemsControl.ItemContainerStyle>
</controls:HeaderedItemsControl>
</Page>
48 changes: 48 additions & 0 deletions components/DataTable/samples/DataTableHybridSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using CommunityToolkit.WinUI.Controls;

namespace DataTableExperiment.Samples;

[ToolkitSample(id: nameof(DataTableHybridSample), "Hybrid DataTable Example", description: $"A sample for showing how to create and use a {nameof(DataRow)} control alongside an existing traditional setup with Grid.")]
public sealed partial class DataTableHybridSample : Page
{
public ObservableCollection<InventoryItem> InventoryItems { get; set; } = new()
{
new()
{
Id = 1002,
Name = "Hydra",
Description = "Multiple Launch Rocket System-2 Hydra",
Quantity = 1,
},
new()
{
Id = 3456,
Name = "MA40 AR",
Description = "Regular assault rifle - updated version of MA5B or MA37 AR",
Quantity = 4,
},
new()
{
Id = 5698,
Name = "Needler",
Description = "Alien weapon well-known for its iconic design with pink crystals",
Quantity = 2,
},
new()
{
Id = 7043,
Name = "Ravager",
Description = "An incendiary plasma launcher",
Quantity = 1,
},
};

public DataTableHybridSample()
{
this.InitializeComponent();
}
}
49 changes: 49 additions & 0 deletions components/DataTable/samples/DataTableSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Page x:Class="DataTableExperiment.Samples.DataTableSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DataTableExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<ListView ItemsSource="{x:Bind InventoryItems}">
<ListView.Header>
<controls:DataTable Margin="12,0,0,0">
<controls:DataColumn Content="Id"
DesiredWidth="80" />
<controls:DataColumn MinWidth="120"
CanResize="True"
Content="Name" />
<!-- Each column can be text or quickly customized by containing any content or restyled of course -->
<controls:DataColumn DesiredWidth="*">
<TextBlock FontWeight="SemiBold"
Text="Description" />
</controls:DataColumn>
<controls:DataColumn Content="Quantity"
DesiredWidth="100" />
</controls:DataTable>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:InventoryItem">
<controls:DataRow>
<TextBlock VerticalAlignment="Center"
Text="{x:Bind Id}" />
<TextBlock VerticalAlignment="Center"
Text="{x:Bind Name}" />
<TextBlock VerticalAlignment="Center"
Text="{x:Bind Description}" />
<TextBlock VerticalAlignment="Center"
Text="{x:Bind Quantity}" />
</controls:DataRow>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style BasedOn="{StaticResource DefaultListViewItemStyle}"
TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Page>
Loading