Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/EventArgs/TableViewColumnPropertyChangedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace WinUI.TableView;
/// <summary>
/// Provides data for the ColumnPropertyChanged event.
/// </summary>
internal class TableViewColumnPropertyChangedEventArgs : EventArgs
public class TableViewColumnPropertyChangedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the TableViewColumnPropertyChanged class.
Expand Down
41 changes: 41 additions & 0 deletions src/ITableViewColumnsCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace WinUI.TableView;

/// <summary>
/// Represents a collection of columns in a <see cref="WinUI.TableView.TableView"/>, providing functionality to manage and interact with the columns.
/// </summary>
/// <remarks>This interface extends <see cref="IList{T}"/> to provide standard list operations for <see
/// cref="TableViewColumn"/> objects. It also implements <see cref="INotifyCollectionChanged"/> to notify subscribers of
/// changes to the collection, such as additions or removals.</remarks>
public interface ITableViewColumnsCollection : IList<TableViewColumn>, INotifyCollectionChanged
{
/// <summary>
/// Occurs when a property of a column changes.
/// </summary>
/// <remarks>
/// This event is triggered to notify subscribers about changes to column properties, such as width, visibility, or other attributes.
/// Handlers can use the <see cref="TableViewColumnPropertyChangedEventArgs"/> parameter to access details about the specific property that changed.
/// </remarks>
event EventHandler<TableViewColumnPropertyChangedEventArgs>? ColumnPropertyChanged;

/// <summary>
/// Gets the list of visible <see cref="TableViewColumn"/>s.
/// </summary>
/// <remarks>
/// The result is a list of columns that are currently visible in the table view, meaning their <see cref="TableViewColumn.Visibility"/> is set to <see cref="Visibility.Visible"/>.
/// The result is also ordered by the <see cref="TableViewColumn.Order"/> property, allowing for a consistent display order of the columns.
/// </remarks>
IList<TableViewColumn> VisibleColumns { get; }

/// <summary>
/// Gets or sets the <see cref="WinUI.TableView.TableView"/> associated with the collection.
/// </summary>
/// <remarks>
/// This property allows access to the <see cref="WinUI.TableView.TableView"/> that owns this collection of columns.
/// </remarks>
TableView? TableView { get; }
}
2 changes: 1 addition & 1 deletion src/TableView.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public TableViewCellSlot? CurrentCellSlot
/// <summary>
/// Gets the collection of columns in the TableView.
/// </summary>
public TableViewColumnsCollection Columns { get; } = [];
public ITableViewColumnsCollection Columns { get; }

/// <summary>
/// Gets or sets the height of the header row.
Expand Down
2 changes: 1 addition & 1 deletion src/TableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public TableView()
{
DefaultStyleKey = typeof(TableView);

Columns.TableView = this;
Columns = new TableViewColumnsCollection(this);
FilterHandler = new ColumnFilterHandler(this);
base.ItemsSource = _collectionView;
base.SelectionMode = SelectionMode;
Expand Down
164 changes: 128 additions & 36 deletions src/TableViewColumnsCollection.cs
Original file line number Diff line number Diff line change
@@ -1,70 +1,162 @@
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using Windows.Foundation.Collections;

namespace WinUI.TableView;

/// <summary>
/// Represents a collection of columns in a TableView.
/// Represents a collection of <see cref="TableViewColumn"/> objects used in a <see cref="WinUI.TableView.TableView"/>.
/// </summary>
public partial class TableViewColumnsCollection : ObservableCollection<TableViewColumn>
/// <remarks>This collection provides functionality for managing columns in a <see cref="WinUI.TableView.TableView"/>, including adding,
/// removing, and tracking changes to column properties. It supports notifications for collection changes and column
/// property changes, enabling dynamic updates to the <see cref="WinUI.TableView.TableView"/>.</remarks>
public partial class TableViewColumnsCollection : DependencyObjectCollection, ITableViewColumnsCollection
{
private TableViewColumn[] _itemsCopy = []; // To keep a copy of the items to keep track of removed items
/// <inheritdoc/>
public event EventHandler<TableViewColumnPropertyChangedEventArgs>? ColumnPropertyChanged;
/// <inheritdoc/>
public event NotifyCollectionChangedEventHandler? CollectionChanged;

/// <summary>
/// Occurs when a property of a column in the collection changes.
/// The constructor for the <see cref="TableViewColumnsCollection"/> class.
/// </summary>
internal event EventHandler<TableViewColumnPropertyChangedEventArgs>? ColumnPropertyChanged;
/// <param name="tableView">
/// The <see cref="WinUI.TableView.TableView"/> that owns this collection.
/// </param>
public TableViewColumnsCollection(TableView tableView)
{
TableView = tableView ?? throw new ArgumentNullException(nameof(tableView));
VectorChanged += OnVectorChanged;
}

/// <summary>
/// Gets the list of visible columns in the collection.
/// Handles changes to the underlying vector of <see cref="DependencyObject"/> items.
/// </summary>
internal IList<TableViewColumn> VisibleColumns =>
[.. Items.Where(x => x.Visibility == Visibility.Visible)
.OrderBy(x => x.Order ?? 0)];

/// <inheritdoc/>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
private void OnVectorChanged(IObservableVector<DependencyObject> sender, IVectorChangedEventArgs args)
{
base.OnCollectionChanged(e);
var index = (int)args.Index;

if (e.NewItems != null)
switch (args.CollectionChange)
{
foreach (var column in e.NewItems.OfType<TableViewColumn>())
{
column.SetOwningCollection(this);
column.SetOwningTableView(TableView!);
}
case CollectionChange.ItemInserted:
if (args.Index < Count)
{
var column = (TableViewColumn)sender[index];
column.SetOwningCollection(this);
column.SetOwningTableView(((ITableViewColumnsCollection)this).TableView!);
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, column, (int)args.Index));
}
break;
case CollectionChange.ItemRemoved:
if (args.Index < _itemsCopy.Length)
{
var column = _itemsCopy[index];
column.SetOwningCollection(null!);
column.SetOwningTableView(null!);
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, column, (int)args.Index));
}
break;
case CollectionChange.Reset:
foreach (var item in _itemsCopy)
{
item.SetOwningCollection(null!);
item.SetOwningTableView(null!);
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
break;
}

if (e.OldItems != null)
{
foreach (var column in e.OldItems.OfType<TableViewColumn>())
{
column.SetOwningCollection(null!);
column.SetOwningTableView(null!);
}
}
_itemsCopy = new TableViewColumn[Count];
CopyTo(_itemsCopy, 0);
}

/// <summary>
/// Handles the property changed event for a column.
/// </summary>
/// <param name="column">The column that changed.</param>
/// <param name="propertyName">The name of the property that changed.</param>
internal void HandleColumnPropertyChanged(TableViewColumn column, string propertyName)
{
if (Items.Contains(column))
if (Contains(column) && this is ITableViewColumnsCollection d)
{
var index = IndexOf(column);
ColumnPropertyChanged?.Invoke(this, new TableViewColumnPropertyChangedEventArgs(column, propertyName, index));
}
}

/// <summary>
/// Gets or sets the TableView associated with the collection.
/// </summary>
public TableView? TableView { get; internal set; }
}
/// <inheritdoc/>
public TableView? TableView { get; }

/// <inheritdoc/>
public IList<TableViewColumn> VisibleColumns => [.. this.OfType<TableViewColumn>()
.Where(x => x.Visibility == Visibility.Visible)
.OrderBy(x => x.Order ?? 0)];

TableViewColumn IList<TableViewColumn>.this[int index]
{
get => (TableViewColumn)base[index];
set => base[index] = value;
}

int ICollection<TableViewColumn>.Count => Count;

bool ICollection<TableViewColumn>.IsReadOnly => IsReadOnly;

void ICollection<TableViewColumn>.Add(TableViewColumn item)
{
Add(item);
}

void ICollection<TableViewColumn>.Clear()
{
Clear();
}

bool ICollection<TableViewColumn>.Contains(TableViewColumn item)
{
return Contains(item);
}

void ICollection<TableViewColumn>.CopyTo(TableViewColumn[] array, int arrayIndex)
{
CopyTo(array, arrayIndex);
}

IEnumerator<TableViewColumn> IEnumerable<TableViewColumn>.GetEnumerator()
{
foreach (var item in this)
{
yield return (TableViewColumn)item;
}
}

int IList<TableViewColumn>.IndexOf(TableViewColumn item)
{
return IndexOf(item);
}

void IList<TableViewColumn>.Insert(int index, TableViewColumn item)
{
Insert(index, item);
}

bool ICollection<TableViewColumn>.Remove(TableViewColumn item)
{
var index = IndexOf(item);

if (index >= 0)
{
RemoveAt(index);
return true;
}

return false;
}

void IList<TableViewColumn>.RemoveAt(int index)
{
RemoveAt(index);
}
}
Loading