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

[DataTable] Horizontal scrolling problem in DataTable #645

Open
3 of 20 tasks
HotCakeX opened this issue Feb 21, 2025 · 2 comments
Open
3 of 20 tasks

[DataTable] Horizontal scrolling problem in DataTable #645

HotCakeX opened this issue Feb 21, 2025 · 2 comments
Labels
bug 🐛 Something isn't working experiment 🧪 Used to track issues that are experiments (or their linked discussions) functional Alignment with specifications and requirements help wanted Extra attention is needed issue 🧪 Used for tracking an Issue/Bug/Feature of an open Experiment/Component labs 🧪

Comments

@HotCakeX
Copy link

Describe the bug

When we enable horizontal scrollbars in the ListView parent of DataTable, it remains always visible even when not needed.

Also, when a column has lots of content it doesn't expand property to take as much horizontal space as needed to display its content completely, it just makes the rest of the content hidden.

Steps to reproduce

Repro sample

Code Behind


using System.Collections.ObjectModel;
using Microsoft.UI.Xaml.Controls;

namespace AppControlManager.Pages;

public sealed partial class Test : Page
{
	private static Test? _instance;
	public static Test Instance => _instance ??= new Test();

	public ListView MainListViewControl => MainListView;

	public Test()
	{
		this.InitializeComponent();
		_instance = this;

		InventoryItem[] items = new InventoryItem[NumberOfRows];

		for (int i = 0; i < NumberOfRows; i++)
		{
			items[i] = new()
			{
				Id = i,
				Name = i.ToString(),
				Description = i.ToString(),
				Quantity = i,
			};
		}

		items[6].Name = "Hello, testing!";
		items[200].Description = "This is a very long description that should have been out view at the start This is a very long description that should have been out view at the start";
		items[1500].Description = "This is a very long description that should have been out of view at the start...";

		InventoryItems = [.. items];
	}
	public const int NumberOfRows = 10000;
	public ObservableCollection<InventoryItem> InventoryItems { get; set; }
}

public class InventoryItem
{
	public int Id { get; set; }
	public string? Name { get; set; }
	public string? Description { get; set; }
	public int Quantity { get; set; }
}


<br>

XAML


<Page
    x:Class="AppControlManager.Pages.Test"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AppControlManager.Pages"
    xmlns:controls="using:CommunityToolkit.WinUI.Controls"
    xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid>
        <ListView x:Name="MainListView" Height="300"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Top"
                  SelectionMode="Multiple"
                  ScrollViewer.HorizontalScrollBarVisibility="Auto"
                  ScrollViewer.HorizontalScrollMode="Enabled"
                  ItemsSource="{x:Bind InventoryItems}">
            <ListView.Header>
                <Border Padding="8,4,0,4"
                    Background="{ThemeResource SolidBackgroundFillColorTertiaryBrush}"
                    CornerRadius="4">
                    <interactivity:Interaction.Behaviors>
                        <behaviors:StickyHeaderBehavior />
                    </interactivity:Interaction.Behaviors>
                    <controls:DataTable ColumnSpacing="16">
                        <controls:DataColumn Content="Id" CanResize="True" DesiredWidth="auto" HorizontalAlignment="Stretch"/>
                        <controls:DataColumn CanResize="True"
                                         Content="Name" HorizontalAlignment="Stretch" DesiredWidth="auto"/>
                        <controls:DataColumn CanResize="True" HorizontalAlignment="Stretch" DesiredWidth="auto">
                            <TextBlock FontWeight="SemiBold"
                                   Text="Description" />
                        </controls:DataColumn>
                        <controls:DataColumn Content="Quantity" CanResize="True" HorizontalAlignment="Stretch" DesiredWidth="auto"/>
                    </controls:DataTable>
                </Border>
            </ListView.Header>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:InventoryItem">
                    <controls:DataRow HorizontalAlignment="Left">
                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Stretch"
                               Text="{x:Bind Id}" />
                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Stretch"
                               Text="{x:Bind Name}" />
                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Stretch"
                               Text="{x:Bind Description}" />
                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Stretch"
                               Text="{x:Bind Quantity}" />
                    </controls:DataRow>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style BasedOn="{StaticResource DefaultListViewItemStyle}"
                   TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
    </Grid>
</Page>


<br>

Expected behavior

I expect each column to expand wide to display its content completely so i can use the scrollbar to horizontally navigate.

I also expect the horizontal scrollbar to not be visible when it's set to "Auto" in the parent ListView, when there is nothing to horizontally scroll to.

Screenshots

Image

Image

Code Platform

  • UWP
  • WinAppSDK / WinUI 3
  • Web Assembly (WASM)
  • Android
  • iOS
  • MacOS
  • Linux / GTK

Windows Build Number

  • Windows 10 1809 (Build 17763)
  • Windows 10 1903 (Build 18362)
  • Windows 10 1909 (Build 18363)
  • Windows 10 2004 (Build 19041)
  • Windows 10 20H2 (Build 19042)
  • Windows 10 21H1 (Build 19043)
  • Windows 11 21H2 (Build 22000)
  • Other (specify)

Other Windows Build number

Windows 11 build 26120.3281

App minimum and target SDK version

  • Windows 10, version 1809 (Build 17763)
  • Windows 10, version 1903 (Build 18362)
  • Windows 10, version 1909 (Build 18363)
  • Windows 10, version 2004 (Build 19041)
  • Other (specify)

Other SDK version

Windows 11 build 22621

Visual Studio Version

Preview

Visual Studio Build Number

17.14.0 Preview 1.0

Device form factor

Desktop

Additional context

No response

Help us help you

No, I'm unable to contribute a solution.

@HotCakeX HotCakeX added the bug 🐛 Something isn't working label Feb 21, 2025
@michael-hawker
Copy link
Member

Thanks for the report and discussion on Discord about this. I took a look the other day, and realized this was a gap in the original design of the control. Bubbling up some notes here for tracking.

Basically, the initial design assumed we'd only be taking away from the provided width of the parent container (e.g. ListView) for the columns, vs. ever providing a size greater based on desired size of larger columns (e.g. with a lot of text). So, the starting point is this bit of code here in the measure of DataRow:

// Otherwise, return our parent's size as the desired size.
return new(_parentPanel?.DesiredSize.Width ?? availableSize.Width, maxHeight);

As I was testing just enabling the horizontal scroll properties on the ListView, I did see some wiggle, so the parent size may also not be correct here, but that's a separate issue, or maybe coming from the DataTable header itself.

Basically, to also prevent re-calculating constantly, with the existing paradigm is to call here to ColumnResized in DataTable:

// TODO: Do we want this to ever shrink back?
var prev = col.MaxChildDesiredWidth;
col.MaxChildDesiredWidth = Math.Max(col.MaxChildDesiredWidth, Children[i].DesiredSize.Width + padding);
if (col.MaxChildDesiredWidth != prev)
{
// If our measure has changed, then we have to invalidate the arrange of the DataTable
_parentTable.ColumnResized();
}

This says that something is different than our last state and we should re-layout the table. So I think in the method here, we should calculate the desired width of the columns (based on the desired layout behavior) and return that as a value:

internal void ColumnResized()
{
InvalidateArrange();
foreach (var row in Rows)
{
row.InvalidateArrange();
}
}

That way we can use that to return back to the measure result and provide the ability for the size to expand. Though that also points to the same TODO note in the code around how should columns shrink back down after. And then how do columns coordinate with each other. Part of that probably depends on if your table is set to stretch vs. being aligned or if a user manipulates a column, etc...

I think part of the issue is this just started as a prototype to lead us to some of these scenarios and questions. So, I think we need to go back and gather all these questions and figure out what the answers/behaviors are for these different scenarios and interactions and ensure we can fit them in the existing setup or adjust the code to accommodate them.

But for this specific scenario, there's a bit more we could try and add to see how things behave (or not) maybe within the current setup, without hopefully too much more code (at least to see if it does work or not).

@michael-hawker michael-hawker added experiment 🧪 Used to track issues that are experiments (or their linked discussions) labs 🧪 issue 🧪 Used for tracking an Issue/Bug/Feature of an open Experiment/Component help wanted Extra attention is needed labels Feb 25, 2025
@michael-hawker michael-hawker moved this to 🆕 New in Toolkit 8.x Feb 25, 2025
@HotCakeX
Copy link
Author

Thank you for the detailed comment ^^
The foundation of Data Table is great and by eliminating these small bugs i'm hopeful it will be able to quit Labs and become production ready.

@Arlodotexe Arlodotexe added the functional Alignment with specifications and requirements label Apr 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something isn't working experiment 🧪 Used to track issues that are experiments (or their linked discussions) functional Alignment with specifications and requirements help wanted Extra attention is needed issue 🧪 Used for tracking an Issue/Bug/Feature of an open Experiment/Component labs 🧪
Projects
Status: 🆕 New
Development

No branches or pull requests

3 participants