Skip to content

Commit 916cd9b

Browse files
authored
Merge pull request #203 from w-ahmad/columns_collection
Improve Columns Collection to work with XAML Hot Reload
2 parents 7141477 + 5416d51 commit 916cd9b

6 files changed

+361
-39
lines changed

src/EventArgs/TableViewColumnPropertyChangedEventArgs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace WinUI.TableView;
55
/// <summary>
66
/// Provides data for the ColumnPropertyChanged event.
77
/// </summary>
8-
internal class TableViewColumnPropertyChangedEventArgs : EventArgs
8+
public class TableViewColumnPropertyChangedEventArgs : EventArgs
99
{
1010
/// <summary>
1111
/// Initializes a new instance of the TableViewColumnPropertyChanged class.

src/ITableViewColumnsCollection.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Microsoft.UI.Xaml;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Collections.Specialized;
5+
6+
namespace WinUI.TableView;
7+
8+
/// <summary>
9+
/// Represents a collection of columns in a <see cref="WinUI.TableView.TableView"/>, providing functionality to manage and interact with the columns.
10+
/// </summary>
11+
/// <remarks>This interface extends <see cref="IList{T}"/> to provide standard list operations for <see
12+
/// cref="TableViewColumn"/> objects. It also implements <see cref="INotifyCollectionChanged"/> to notify subscribers of
13+
/// changes to the collection, such as additions or removals.</remarks>
14+
public interface ITableViewColumnsCollection : IList<TableViewColumn>, INotifyCollectionChanged
15+
{
16+
/// <summary>
17+
/// Occurs when a property of a column changes.
18+
/// </summary>
19+
/// <remarks>
20+
/// This event is triggered to notify subscribers about changes to column properties, such as width, visibility, or other attributes.
21+
/// Handlers can use the <see cref="TableViewColumnPropertyChangedEventArgs"/> parameter to access details about the specific property that changed.
22+
/// </remarks>
23+
event EventHandler<TableViewColumnPropertyChangedEventArgs>? ColumnPropertyChanged;
24+
25+
/// <summary>
26+
/// Gets the list of visible <see cref="TableViewColumn"/>s.
27+
/// </summary>
28+
/// <remarks>
29+
/// 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"/>.
30+
/// The result is also ordered by the <see cref="TableViewColumn.Order"/> property, allowing for a consistent display order of the columns.
31+
/// </remarks>
32+
IList<TableViewColumn> VisibleColumns { get; }
33+
34+
/// <summary>
35+
/// Gets or sets the <see cref="WinUI.TableView.TableView"/> associated with the collection.
36+
/// </summary>
37+
/// <remarks>
38+
/// This property allows access to the <see cref="WinUI.TableView.TableView"/> that owns this collection of columns.
39+
/// </remarks>
40+
TableView? TableView { get; }
41+
}

src/TableView.Properties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public TableViewCellSlot? CurrentCellSlot
265265
/// <summary>
266266
/// Gets the collection of columns in the TableView.
267267
/// </summary>
268-
public TableViewColumnsCollection Columns { get; } = [];
268+
public ITableViewColumnsCollection Columns { get; }
269269

270270
/// <summary>
271271
/// Gets or sets the height of the header row.

src/TableView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public TableView()
4848
{
4949
DefaultStyleKey = typeof(TableView);
5050

51-
Columns.TableView = this;
51+
Columns = new TableViewColumnsCollection(this);
5252
FilterHandler = new ColumnFilterHandler(this);
5353
base.ItemsSource = _collectionView;
5454
base.SelectionMode = SelectionMode;

src/TableViewColumnsCollection.cs

Lines changed: 128 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,162 @@
11
using Microsoft.UI.Xaml;
22
using System;
33
using System.Collections.Generic;
4-
using System.Collections.ObjectModel;
54
using System.Collections.Specialized;
6-
using System.ComponentModel;
75
using System.Linq;
6+
using Windows.Foundation.Collections;
87

98
namespace WinUI.TableView;
109

1110
/// <summary>
12-
/// Represents a collection of columns in a TableView.
11+
/// Represents a collection of <see cref="TableViewColumn"/> objects used in a <see cref="WinUI.TableView.TableView"/>.
1312
/// </summary>
14-
public partial class TableViewColumnsCollection : ObservableCollection<TableViewColumn>
13+
/// <remarks>This collection provides functionality for managing columns in a <see cref="WinUI.TableView.TableView"/>, including adding,
14+
/// removing, and tracking changes to column properties. It supports notifications for collection changes and column
15+
/// property changes, enabling dynamic updates to the <see cref="WinUI.TableView.TableView"/>.</remarks>
16+
public partial class TableViewColumnsCollection : DependencyObjectCollection, ITableViewColumnsCollection
1517
{
18+
private TableViewColumn[] _itemsCopy = []; // To keep a copy of the items to keep track of removed items
19+
/// <inheritdoc/>
20+
public event EventHandler<TableViewColumnPropertyChangedEventArgs>? ColumnPropertyChanged;
21+
/// <inheritdoc/>
22+
public event NotifyCollectionChangedEventHandler? CollectionChanged;
23+
1624
/// <summary>
17-
/// Occurs when a property of a column in the collection changes.
25+
/// The constructor for the <see cref="TableViewColumnsCollection"/> class.
1826
/// </summary>
19-
internal event EventHandler<TableViewColumnPropertyChangedEventArgs>? ColumnPropertyChanged;
27+
/// <param name="tableView">
28+
/// The <see cref="WinUI.TableView.TableView"/> that owns this collection.
29+
/// </param>
30+
public TableViewColumnsCollection(TableView tableView)
31+
{
32+
TableView = tableView ?? throw new ArgumentNullException(nameof(tableView));
33+
VectorChanged += OnVectorChanged;
34+
}
2035

2136
/// <summary>
22-
/// Gets the list of visible columns in the collection.
37+
/// Handles changes to the underlying vector of <see cref="DependencyObject"/> items.
2338
/// </summary>
24-
internal IList<TableViewColumn> VisibleColumns =>
25-
[.. Items.Where(x => x.Visibility == Visibility.Visible)
26-
.OrderBy(x => x.Order ?? 0)];
27-
28-
/// <inheritdoc/>
29-
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
39+
private void OnVectorChanged(IObservableVector<DependencyObject> sender, IVectorChangedEventArgs args)
3040
{
31-
base.OnCollectionChanged(e);
41+
var index = (int)args.Index;
3242

33-
if (e.NewItems != null)
43+
switch (args.CollectionChange)
3444
{
35-
foreach (var column in e.NewItems.OfType<TableViewColumn>())
36-
{
37-
column.SetOwningCollection(this);
38-
column.SetOwningTableView(TableView!);
39-
}
45+
case CollectionChange.ItemInserted:
46+
if (args.Index < Count)
47+
{
48+
var column = (TableViewColumn)sender[index];
49+
column.SetOwningCollection(this);
50+
column.SetOwningTableView(((ITableViewColumnsCollection)this).TableView!);
51+
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, column, (int)args.Index));
52+
}
53+
break;
54+
case CollectionChange.ItemRemoved:
55+
if (args.Index < _itemsCopy.Length)
56+
{
57+
var column = _itemsCopy[index];
58+
column.SetOwningCollection(null!);
59+
column.SetOwningTableView(null!);
60+
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, column, (int)args.Index));
61+
}
62+
break;
63+
case CollectionChange.Reset:
64+
foreach (var item in _itemsCopy)
65+
{
66+
item.SetOwningCollection(null!);
67+
item.SetOwningTableView(null!);
68+
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
69+
}
70+
break;
4071
}
4172

42-
if (e.OldItems != null)
43-
{
44-
foreach (var column in e.OldItems.OfType<TableViewColumn>())
45-
{
46-
column.SetOwningCollection(null!);
47-
column.SetOwningTableView(null!);
48-
}
49-
}
73+
_itemsCopy = new TableViewColumn[Count];
74+
CopyTo(_itemsCopy, 0);
5075
}
5176

5277
/// <summary>
5378
/// Handles the property changed event for a column.
5479
/// </summary>
55-
/// <param name="column">The column that changed.</param>
56-
/// <param name="propertyName">The name of the property that changed.</param>
5780
internal void HandleColumnPropertyChanged(TableViewColumn column, string propertyName)
5881
{
59-
if (Items.Contains(column))
82+
if (Contains(column) && this is ITableViewColumnsCollection d)
6083
{
6184
var index = IndexOf(column);
6285
ColumnPropertyChanged?.Invoke(this, new TableViewColumnPropertyChangedEventArgs(column, propertyName, index));
6386
}
6487
}
6588

66-
/// <summary>
67-
/// Gets or sets the TableView associated with the collection.
68-
/// </summary>
69-
public TableView? TableView { get; internal set; }
70-
}
89+
/// <inheritdoc/>
90+
public TableView? TableView { get; }
91+
92+
/// <inheritdoc/>
93+
public IList<TableViewColumn> VisibleColumns => [.. this.OfType<TableViewColumn>()
94+
.Where(x => x.Visibility == Visibility.Visible)
95+
.OrderBy(x => x.Order ?? 0)];
96+
97+
TableViewColumn IList<TableViewColumn>.this[int index]
98+
{
99+
get => (TableViewColumn)base[index];
100+
set => base[index] = value;
101+
}
102+
103+
int ICollection<TableViewColumn>.Count => Count;
104+
105+
bool ICollection<TableViewColumn>.IsReadOnly => IsReadOnly;
106+
107+
void ICollection<TableViewColumn>.Add(TableViewColumn item)
108+
{
109+
Add(item);
110+
}
111+
112+
void ICollection<TableViewColumn>.Clear()
113+
{
114+
Clear();
115+
}
116+
117+
bool ICollection<TableViewColumn>.Contains(TableViewColumn item)
118+
{
119+
return Contains(item);
120+
}
121+
122+
void ICollection<TableViewColumn>.CopyTo(TableViewColumn[] array, int arrayIndex)
123+
{
124+
CopyTo(array, arrayIndex);
125+
}
126+
127+
IEnumerator<TableViewColumn> IEnumerable<TableViewColumn>.GetEnumerator()
128+
{
129+
foreach (var item in this)
130+
{
131+
yield return (TableViewColumn)item;
132+
}
133+
}
134+
135+
int IList<TableViewColumn>.IndexOf(TableViewColumn item)
136+
{
137+
return IndexOf(item);
138+
}
139+
140+
void IList<TableViewColumn>.Insert(int index, TableViewColumn item)
141+
{
142+
Insert(index, item);
143+
}
144+
145+
bool ICollection<TableViewColumn>.Remove(TableViewColumn item)
146+
{
147+
var index = IndexOf(item);
148+
149+
if (index >= 0)
150+
{
151+
RemoveAt(index);
152+
return true;
153+
}
154+
155+
return false;
156+
}
157+
158+
void IList<TableViewColumn>.RemoveAt(int index)
159+
{
160+
RemoveAt(index);
161+
}
162+
}

0 commit comments

Comments
 (0)