Skip to content

Commit

Permalink
Merge pull request #74 from w-ahmad/feature/gridlines
Browse files Browse the repository at this point in the history
Add Horizontal and Vertical Grid Lines
  • Loading branch information
w-ahmad authored Dec 9, 2024
2 parents ab9c45e + b98e198 commit 24903e6
Show file tree
Hide file tree
Showing 16 changed files with 787 additions and 136 deletions.
53 changes: 51 additions & 2 deletions src/WinUI.TableView/TableView.Properties.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using CommunityToolkit.WinUI.Collections;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace WinUI.TableView;
public partial class TableView
Expand All @@ -25,6 +24,12 @@ public partial class TableView
public static readonly DependencyProperty MinColumnWidthProperty = DependencyProperty.Register(nameof(MinColumnWidth), typeof(double), typeof(TableView), new PropertyMetadata(50d, OnMinColumnWidthChanged));
public static readonly DependencyProperty MaxColumnWidthProperty = DependencyProperty.Register(nameof(MaxColumnWidth), typeof(double), typeof(TableView), new PropertyMetadata(double.PositiveInfinity, OnMaxColumnWidthChanged));
public static readonly DependencyProperty SelectionUnitProperty = DependencyProperty.Register(nameof(SelectionUnit), typeof(TableViewSelectionUnit), typeof(TableView), new PropertyMetadata(TableViewSelectionUnit.CellOrRow, OnSelectionUnitChanged));
public static readonly DependencyProperty HeaderGridLinesVisibilityProperty = DependencyProperty.Register(nameof(HeaderGridLinesVisibility), typeof(TableViewGridLinesVisibility), typeof(TableView), new PropertyMetadata(TableViewGridLinesVisibility.All, OnGridLinesPropertyChanged));
public static readonly DependencyProperty GridLinesVisibilityProperty = DependencyProperty.Register(nameof(GridLinesVisibility), typeof(TableViewGridLinesVisibility), typeof(TableView), new PropertyMetadata(TableViewGridLinesVisibility.All, OnGridLinesPropertyChanged));
public static readonly DependencyProperty HorizontalGridLinesStrokeThicknessProperty = DependencyProperty.Register(nameof(HorizontalGridLinesStrokeThickness), typeof(double), typeof(TableView), new PropertyMetadata(1d, OnGridLinesPropertyChanged));
public static readonly DependencyProperty VerticalGridLinesStrokeThicknessProperty = DependencyProperty.Register(nameof(VerticalGridLinesStrokeThickness), typeof(double), typeof(TableView), new PropertyMetadata(1d, OnGridLinesPropertyChanged));
public static readonly DependencyProperty HorizontalGridLinesStrokeProperty = DependencyProperty.Register(nameof(HorizontalGridLinesStroke), typeof(Brush), typeof(TableView), new PropertyMetadata(default, OnGridLinesPropertyChanged));
public static readonly DependencyProperty VerticalGridLinesStrokeProperty = DependencyProperty.Register(nameof(VerticalGridLinesStroke), typeof(Brush), typeof(TableView), new PropertyMetadata(default, OnGridLinesPropertyChanged));

public IAdvancedCollectionView CollectionView { get; private set; } = new AdvancedCollectionView();
internal IDictionary<string, Predicate<object>> ActiveFilters { get; } = new Dictionary<string, Predicate<object>>();
Expand Down Expand Up @@ -128,6 +133,42 @@ public TableViewSelectionUnit SelectionUnit
set => SetValue(SelectionUnitProperty, value);
}

public TableViewGridLinesVisibility HeaderGridLinesVisibility
{
get => (TableViewGridLinesVisibility)GetValue(HeaderGridLinesVisibilityProperty);
set => SetValue(HeaderGridLinesVisibilityProperty, value);
}

public TableViewGridLinesVisibility GridLinesVisibility
{
get => (TableViewGridLinesVisibility)GetValue(GridLinesVisibilityProperty);
set => SetValue(GridLinesVisibilityProperty, value);
}

public double VerticalGridLinesStrokeThickness
{
get => (double)GetValue(VerticalGridLinesStrokeThicknessProperty);
set => SetValue(VerticalGridLinesStrokeThicknessProperty, value);
}

public double HorizontalGridLinesStrokeThickness
{
get => (double)GetValue(HorizontalGridLinesStrokeThicknessProperty);
set => SetValue(HorizontalGridLinesStrokeThicknessProperty, value);
}

public Brush VerticalGridLinesStroke
{
get => (Brush)GetValue(VerticalGridLinesStrokeProperty);
set => SetValue(VerticalGridLinesStrokeProperty, value);
}

public Brush HorizontalGridLinesStroke
{
get => (Brush)GetValue(HorizontalGridLinesStrokeProperty);
set => SetValue(HorizontalGridLinesStrokeProperty, value);
}

private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TableView tableView)
Expand Down Expand Up @@ -241,6 +282,14 @@ private static void OnSelectionUnitChanged(DependencyObject d, DependencyPropert
}
}

private static void OnGridLinesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TableView tableView)
{
tableView.EnsureGridLines();
}
}

private void OnBaseItemsSourceChanged(DependencyObject sender, DependencyProperty dp)
{
throw new InvalidOperationException("Setting this property directly is not allowed. Use TableView.ItemsSource instead.");
Expand Down
15 changes: 15 additions & 0 deletions src/WinUI.TableView/TableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,9 +1047,24 @@ private void UpdateBaseSelectionMode()

base.SelectionMode = SelectionUnit is TableViewSelectionUnit.Cell ? ListViewSelectionMode.None : SelectionMode;

foreach (var row in _rows)
{
row.EnsureLayout();
}

_shouldThrowSelectionModeChangedException = false;
}

private void EnsureGridLines()
{
_headerRow?.EnsureGridLines();

foreach (var row in _rows)
{
row.EnsureGridLines();
}
}

public event EventHandler<TableViewAutoGeneratingColumnEventArgs>? AutoGeneratingColumn;
public event EventHandler<TableViewExportContentEventArgs>? ExportAllContent;
public event EventHandler<TableViewExportContentEventArgs>? ExportSelectedContent;
Expand Down
55 changes: 47 additions & 8 deletions src/WinUI.TableView/TableViewCell.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using CommunityToolkit.WinUI;
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;
using System;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -21,6 +23,8 @@ public class TableViewCell : ContentControl
private TableViewColumn? _column;
private ScrollViewer? _scrollViewer;
private ContentPresenter? _contentPresenter;
private Border? _selectionBorder;
private Rectangle? _v_gridLine;

public TableViewCell()
{
Expand All @@ -35,6 +39,17 @@ private void OnLoaded(object sender, RoutedEventArgs e)
ApplySelectionState();
}

protected override void OnApplyTemplate()
{
base.OnApplyTemplate();

_contentPresenter = GetTemplateChild("Content") as ContentPresenter;
_selectionBorder = GetTemplateChild("SelectionBorder") as Border;
_v_gridLine = GetTemplateChild("VerticalGridLine") as Rectangle;

EnsureGridLines();
}

protected override Size MeasureOverride(Size availableSize)
{
if ((Content ?? ContentTemplateRoot) is FrameworkElement element)
Expand All @@ -53,7 +68,9 @@ protected override Size MeasureOverride(Size availableSize)
}
}

_contentPresenter ??= (ContentPresenter)GetTemplateChild("Content");
var v_GridLineStrokeThickness = TableView?.HeaderGridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
|| TableView?.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? TableView.VerticalGridLinesStrokeThickness : 0;

var contentWidth = Column?.ActualWidth ?? 0d;
contentWidth -= element.Margin.Left;
Expand All @@ -62,6 +79,9 @@ protected override Size MeasureOverride(Size availableSize)
contentWidth -= Padding.Right;
contentWidth -= BorderThickness.Left;
contentWidth -= BorderThickness.Right;
contentWidth -= _selectionBorder?.BorderThickness.Right ?? 0;
contentWidth -= _selectionBorder?.BorderThickness.Left ?? 0;
contentWidth -= v_GridLineStrokeThickness;

element.MaxWidth = double.PositiveInfinity;
#endregion
Expand All @@ -74,19 +94,25 @@ protected override Size MeasureOverride(Size availableSize)
desiredWidth += Padding.Right;
desiredWidth += BorderThickness.Left;
desiredWidth += BorderThickness.Right;
desiredWidth += _selectionBorder?.BorderThickness.Right ?? 0;
desiredWidth += _selectionBorder?.BorderThickness.Left ?? 0;
desiredWidth += v_GridLineStrokeThickness;

Column.DesiredWidth = Math.Max(Column.DesiredWidth, desiredWidth);
}

#region TEMP_FIX_FOR_ISSUE https://github.com/microsoft/microsoft-ui-xaml/issues/9860
if (contentWidth < 0)
if (_contentPresenter is not null)
{
_contentPresenter.Visibility = Visibility.Collapsed;
}
else
{
element.MaxWidth = contentWidth;
_contentPresenter.Visibility = Visibility.Visible;
if (contentWidth < 0)
{
_contentPresenter.Visibility = Visibility.Collapsed;
}
else
{
element.MaxWidth = contentWidth;
_contentPresenter.Visibility = Visibility.Visible;
}
}
#endregion
}
Expand Down Expand Up @@ -302,6 +328,19 @@ private void OnColumnChanged()
}
}

internal void EnsureGridLines()
{
if (_v_gridLine is not null && TableView is not null)
{
_v_gridLine.Fill = TableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? TableView.VerticalGridLinesStroke : new SolidColorBrush(Colors.Transparent);
_v_gridLine.Width = TableView.VerticalGridLinesStrokeThickness;
_v_gridLine.Visibility = TableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
|| TableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? Visibility.Visible : Visibility.Collapsed;
}
}

public bool IsReadOnly => TableView?.IsReadOnly is true || Column is TableViewTemplateColumn { EditingTemplate: null } or { IsReadOnly: true };

internal TableViewCellSlot Slot => new(Row?.Index ?? -1, Index);
Expand Down
62 changes: 58 additions & 4 deletions src/WinUI.TableView/TableViewCellsPresenter.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,69 @@
using Microsoft.UI.Xaml.Controls;
using CommunityToolkit.WinUI;
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;
using System.Collections.Generic;
using System.Linq;

namespace WinUI.TableView;

public class TableViewCellsPresenter : StackPanel
public class TableViewCellsPresenter : Control
{
private StackPanel? _stackPanel;
private Rectangle? _v_gridLine;
private Rectangle? _h_gridLine;

public TableViewCellsPresenter()
{
Orientation = Orientation.Horizontal;
DefaultStyleKey = typeof(TableViewCellsPresenter);
}

protected override void OnApplyTemplate()
{
base.OnApplyTemplate();

_stackPanel = GetTemplateChild("StackPanel") as StackPanel;
_v_gridLine = GetTemplateChild("VerticalGridLine") as Rectangle;
_h_gridLine = GetTemplateChild("HorizontalGridLine") as Rectangle;

TableViewRow = this.FindAscendant<TableViewRow>();
TableView = TableViewRow?.TableView;

EnsureGridLines();
}

internal void EnsureGridLines()
{
if (TableView is null) return;

if (_h_gridLine is not null)
{
_h_gridLine.Fill = TableView.HorizontalGridLinesStroke;
_h_gridLine.Height = TableView.HorizontalGridLinesStrokeThickness;
_h_gridLine.Visibility = TableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Horizontal
? Visibility.Visible : Visibility.Collapsed;

if (_v_gridLine is not null)
{
_v_gridLine.Fill = TableView.HeaderGridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? TableView.VerticalGridLinesStroke : new SolidColorBrush(Colors.Transparent);
_v_gridLine.Width = TableView.VerticalGridLinesStrokeThickness;
_v_gridLine.Visibility = TableView.HeaderGridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
|| TableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? Visibility.Visible : Visibility.Collapsed;
}
}

foreach (var cell in Cells)
{
cell.EnsureGridLines();
}
}

public IList<TableViewCell> Cells => Children.OfType<TableViewCell>().ToList().AsReadOnly();
internal UIElementCollection Children => _stackPanel?.Children!;
public IList<TableViewCell> Cells => _stackPanel?.Children.OfType<TableViewCell>().ToList()!;
public TableViewRow? TableViewRow { get; private set; }
public TableView? TableView { get; private set; }
}
39 changes: 35 additions & 4 deletions src/WinUI.TableView/TableViewColumnHeader.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
using CommunityToolkit.WinUI;
using CommunityToolkit.WinUI.Collections;
using Microsoft.UI;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.System;
using Windows.UI.Core;
using WinUI.TableView.Extensions;
Expand All @@ -33,6 +35,7 @@ public partial class TableViewColumnHeader : ContentControl
private Button? _optionsButton;
private MenuFlyout? _optionsFlyout;
private ContentPresenter? _contentPresenter;
private Rectangle? _v_gridLine;
private CheckBox? _selectAllCheckBox;
private OptionsFlyoutViewModel _optionsFlyoutViewModel = default!;
private string _propertyPath = default!;
Expand Down Expand Up @@ -161,6 +164,7 @@ protected override void OnApplyTemplate()
_optionsButton = GetTemplateChild("OptionsButton") as Button;
_optionsFlyout = GetTemplateChild("OptionsFlyout") as MenuFlyout;
_contentPresenter = GetTemplateChild("ContentPresenter") as ContentPresenter;
_v_gridLine = GetTemplateChild("VerticalGridLine") as Rectangle;

if (_tableView is null || _optionsButton is null || _optionsFlyout is null)
{
Expand Down Expand Up @@ -195,6 +199,7 @@ protected override void OnApplyTemplate()
}

SetFilterButtonVisibility();
EnsureGridLines();
}

private void OnSearchBoxKeyDown(object sender, KeyRoutedEventArgs e)
Expand Down Expand Up @@ -309,7 +314,11 @@ private void SetFilterButtonVisibility()

if (_contentPresenter is not null)
{
_contentPresenter.Margin = CanFilter ? new Thickness(0, 0, 8, 0) : new Thickness(0);
_contentPresenter.Margin = CanFilter ? new Thickness(
Padding.Left,
Padding.Top,
Padding.Right + 8,
0) : Padding;
}
}

Expand Down Expand Up @@ -338,15 +347,24 @@ protected override void OnDoubleTapped(DoubleTappedRoutedEventArgs e)
}

var position = e.GetPosition(this);
var v_GridLineStrokeThickness = _tableView.HeaderGridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
|| _tableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? _tableView.VerticalGridLinesStrokeThickness : 0;

if (position.X <= 8 && _headerRow?.GetPreviousHeader(this) is { Column: { } } header)
{
var width = Math.Clamp(header.Column.DesiredWidth, header.Column.MinWidth ?? _tableView.MinColumnWidth, header.Column.MaxWidth ?? _tableView.MaxColumnWidth);
var width = Math.Clamp(
header.Column.DesiredWidth,
header.Column.MinWidth ?? _tableView.MinColumnWidth,
header.Column.MaxWidth ?? _tableView.MaxColumnWidth);
header.Column.Width = new GridLength(width, GridUnitType.Pixel);
}
else if (Column is not null)
{
var width = Math.Clamp(Column.DesiredWidth, Column.MinWidth ?? _tableView.MinColumnWidth, Column.MaxWidth ?? _tableView.MaxColumnWidth);
var width = Math.Clamp(
Column.DesiredWidth,
Column.MinWidth ?? _tableView.MinColumnWidth,
Column.MaxWidth ?? _tableView.MaxColumnWidth);
Column.Width = new GridLength(width, GridUnitType.Pixel);
}
}
Expand Down Expand Up @@ -443,6 +461,19 @@ protected override async void OnPointerReleased(PointerRoutedEventArgs e)
}
}

internal void EnsureGridLines()
{
if (_v_gridLine is not null && _tableView is not null)
{
_v_gridLine.Fill = _tableView.HeaderGridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? _tableView.VerticalGridLinesStroke : new SolidColorBrush(Colors.Transparent);
_v_gridLine.Width = _tableView.VerticalGridLinesStrokeThickness;
_v_gridLine.Visibility = _tableView.HeaderGridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
|| _tableView.GridLinesVisibility is TableViewGridLinesVisibility.All or TableViewGridLinesVisibility.Vertical
? Visibility.Visible : Visibility.Collapsed;
}
}

public SD? SortDirection
{
get => _sortDirection;
Expand Down
Loading

0 comments on commit 24903e6

Please sign in to comment.