Skip to content

Commit 2f254f2

Browse files
committed
improved auto generate column process
1 parent 417ae32 commit 2f254f2

9 files changed

+244
-141
lines changed

src/Columns/TableViewColumn.cs

Lines changed: 40 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,15 @@ public bool CanFilter
204204
set => SetValue(CanFilterProperty, value);
205205
}
206206

207+
/// <summary>
208+
/// Gets or sets the order in which this column should be displayed.
209+
/// </summary>
210+
public int? Order
211+
{
212+
get => (int?)GetValue(OrderProperty);
213+
set => SetValue(OrderProperty, value);
214+
}
215+
207216
internal TableViewColumnsCollection? OwningCollection { get; set; }
208217

209218
/// <summary>
@@ -293,69 +302,32 @@ internal void EnsureHeaderStyle()
293302
/// <summary>
294303
/// Handles changes to the Width property.
295304
/// </summary>
296-
private static void OnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
297-
{
298-
if (d is TableViewColumn column && column.OwningCollection is { })
299-
{
300-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(Width));
301-
}
302-
}
303-
304-
/// <summary>
305-
/// Handles changes to the MinWidth property.
306-
/// </summary>
307-
private static void OnMinWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
308-
{
309-
if (d is TableViewColumn column && column.OwningCollection is { })
310-
{
311-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(MinWidth));
312-
}
313-
}
314-
315-
/// <summary>
316-
/// Handles changes to the MaxWidth property.
317-
/// </summary>
318-
private static void OnMaxWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
319-
{
320-
if (d is TableViewColumn column && column.OwningCollection is { })
321-
{
322-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(MaxWidth));
323-
}
324-
}
325-
326-
/// <summary>
327-
/// Handles changes to the ActualWidth property.
328-
/// </summary>
329-
private static void OnActualWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
330-
{
331-
if (d is TableViewColumn column && column.OwningCollection is { })
332-
{
333-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(ActualWidth));
334-
}
335-
}
336-
337-
/// <summary>
338-
/// Handles changes to the IsReadOnly property.
339-
/// </summary>
340-
private static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
305+
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
341306
{
342-
if (d is TableViewColumn column && column.OwningCollection is { })
307+
if (d is TableViewColumn { OwningCollection: { } } column)
343308
{
344-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(IsReadOnly));
309+
if (e.Property == CellStyleProperty)
310+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(CellStyle));
311+
else if (e.Property == WidthProperty)
312+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(Width));
313+
else if (e.Property == MinWidthProperty)
314+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(MinWidth));
315+
else if (e.Property == MaxWidthProperty)
316+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(MaxWidth));
317+
else if (e.Property == ActualWidthProperty)
318+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(ActualWidth));
319+
else if (e.Property == IsReadOnlyProperty)
320+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(IsReadOnly));
321+
else if (e.Property == VisibilityProperty)
322+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(Visibility));
323+
else if (e.Property == OrderProperty)
324+
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(Order));
345325
}
346326
}
347327

348328
/// <summary>
349-
/// Handles changes to the Visibility property.
329+
/// Handles changes to the CanFilter property.
350330
/// </summary>
351-
private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
352-
{
353-
if (d is TableViewColumn column && column.OwningCollection is { })
354-
{
355-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(Visibility));
356-
}
357-
}
358-
359331
private static void OnCanFilterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
360332
{
361333
if (d is TableViewColumn column && column.HeaderControl is not null)
@@ -375,17 +347,6 @@ private static void OnHeaderStyleChanged(DependencyObject d, DependencyPropertyC
375347
}
376348
}
377349

378-
/// <summary>
379-
/// Handles changes to the CellStyle property.
380-
/// </summary>
381-
private static void OnCellStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
382-
{
383-
if (d is TableViewColumn column && column.OwningCollection is { })
384-
{
385-
column.OwningCollection.HandleColumnPropertyChanged(column, nameof(CellStyle));
386-
}
387-
}
388-
389350
/// <summary>
390351
/// Identifies the HeaderStyle dependency property.
391352
/// </summary>
@@ -394,7 +355,7 @@ private static void OnCellStyleChanged(DependencyObject d, DependencyPropertyCha
394355
/// <summary>
395356
/// Identifies the CellStyle dependency property.
396357
/// </summary>
397-
public static readonly DependencyProperty CellStyleProperty = DependencyProperty.Register(nameof(CellStyle), typeof(Style), typeof(TableViewColumn), new PropertyMetadata(null, OnCellStyleChanged));
358+
public static readonly DependencyProperty CellStyleProperty = DependencyProperty.Register(nameof(CellStyle), typeof(Style), typeof(TableViewColumn), new PropertyMetadata(null, OnPropertyChanged));
398359

399360
/// <summary>
400361
/// Identifies the Header dependency property.
@@ -404,22 +365,22 @@ private static void OnCellStyleChanged(DependencyObject d, DependencyPropertyCha
404365
/// <summary>
405366
/// Identifies the Width dependency property.
406367
/// </summary>
407-
public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(nameof(Width), typeof(GridLength), typeof(TableViewColumn), new PropertyMetadata(GridLength.Auto, OnWidthChanged));
368+
public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(nameof(Width), typeof(GridLength), typeof(TableViewColumn), new PropertyMetadata(GridLength.Auto, OnPropertyChanged));
408369

409370
/// <summary>
410371
/// Identifies the MinWidth dependency property.
411372
/// </summary>
412-
public static readonly DependencyProperty MinWidthProperty = DependencyProperty.Register(nameof(MinWidth), typeof(double?), typeof(TableViewColumn), new PropertyMetadata(default, OnMinWidthChanged));
373+
public static readonly DependencyProperty MinWidthProperty = DependencyProperty.Register(nameof(MinWidth), typeof(double?), typeof(TableViewColumn), new PropertyMetadata(default, OnPropertyChanged));
413374

414375
/// <summary>
415376
/// Identifies the MaxWidth dependency property.
416377
/// </summary>
417-
public static readonly DependencyProperty MaxWidthProperty = DependencyProperty.Register(nameof(MaxWidth), typeof(double?), typeof(TableViewColumn), new PropertyMetadata(default, OnMaxWidthChanged));
378+
public static readonly DependencyProperty MaxWidthProperty = DependencyProperty.Register(nameof(MaxWidth), typeof(double?), typeof(TableViewColumn), new PropertyMetadata(default, OnPropertyChanged));
418379

419380
/// <summary>
420381
/// Identifies the ActualWidth dependency property.
421382
/// </summary>
422-
public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(nameof(ActualWidth), typeof(double), typeof(TableViewColumn), new PropertyMetadata(0d, OnActualWidthChanged));
383+
public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(nameof(ActualWidth), typeof(double), typeof(TableViewColumn), new PropertyMetadata(0d, OnPropertyChanged));
423384

424385
/// <summary>
425386
/// Identifies the CanResize dependency property.
@@ -429,12 +390,12 @@ private static void OnCellStyleChanged(DependencyObject d, DependencyPropertyCha
429390
/// <summary>
430391
/// Identifies the IsReadOnly dependency property.
431392
/// </summary>
432-
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(nameof(IsReadOnly), typeof(bool), typeof(TableViewColumn), new PropertyMetadata(false, OnIsReadOnlyChanged));
393+
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(nameof(IsReadOnly), typeof(bool), typeof(TableViewColumn), new PropertyMetadata(false, OnPropertyChanged));
433394

434395
/// <summary>
435396
/// Identifies the Visibility dependency property.
436397
/// </summary>
437-
public static readonly DependencyProperty VisibilityProperty = DependencyProperty.Register(nameof(Visibility), typeof(Visibility), typeof(TableViewColumn), new PropertyMetadata(Visibility.Visible, OnVisibilityChanged));
398+
public static readonly DependencyProperty VisibilityProperty = DependencyProperty.Register(nameof(Visibility), typeof(Visibility), typeof(TableViewColumn), new PropertyMetadata(Visibility.Visible, OnPropertyChanged));
438399

439400
/// <summary>
440401
/// Identifies the Tag dependency property.
@@ -450,4 +411,9 @@ private static void OnCellStyleChanged(DependencyObject d, DependencyPropertyCha
450411
/// Identifies the CanFilter dependency property.
451412
/// </summary>
452413
public static readonly DependencyProperty CanFilterProperty = DependencyProperty.Register(nameof(CanFilter), typeof(bool), typeof(TableViewColumn), new PropertyMetadata(true, OnCanFilterChanged));
414+
415+
/// <summary>
416+
/// Identifies the Order dependency property.
417+
/// </summary>
418+
public static readonly DependencyProperty OrderProperty = DependencyProperty.Register(nameof(Order), typeof(int?), typeof(TableViewColumn), new PropertyMetadata(null, OnPropertyChanged));
453419
}

src/EventArgs/TableViewAutoGeneratingColumnEventArgs.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class TableViewAutoGeneratingColumnEventArgs : CancelEventArgs
1414
/// <param name="propertyName">The name of the property for which the column is being generated.</param>
1515
/// <param name="propertyType">The type of the property for which the column is being generated.</param>
1616
/// <param name="column">The column that is being generated.</param>
17-
public TableViewAutoGeneratingColumnEventArgs(string propertyName, Type propertyType, TableViewColumn column)
17+
public TableViewAutoGeneratingColumnEventArgs(string propertyName, Type? propertyType, TableViewColumn column)
1818
{
1919
PropertyName = propertyName;
2020
PropertyType = propertyType;
@@ -29,7 +29,7 @@ public TableViewAutoGeneratingColumnEventArgs(string propertyName, Type property
2929
/// <summary>
3030
/// Gets the type of the property for which the column is being generated.
3131
/// </summary>
32-
public Type PropertyType { get; }
32+
public Type? PropertyType { get; }
3333

3434
/// <summary>
3535
/// Gets or sets the column that is being generated.

src/Extensions/ObjectExtensions.cs

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections;
3+
using System.Linq;
24
using System.Reflection;
35

46
namespace WinUI.TableView.Extensions;
@@ -92,16 +94,77 @@ internal static class ObjectExtensions
9294
/// <returns></returns>
9395
public static bool IsNumeric(this object obj)
9496
{
95-
return obj is byte
96-
or sbyte
97-
or short
98-
or ushort
97+
return obj is byte
98+
or sbyte
99+
or short
100+
or ushort
99101
or int
100102
or uint
101103
or long
102-
or ulong
103-
or float
104-
or double
104+
or ulong
105+
or float
106+
or double
105107
or decimal;
106108
}
109+
110+
internal static Type? GetItemType(this IEnumerable list)
111+
{
112+
var listType = list.GetType();
113+
Type? itemType = null;
114+
var isICustomTypeProvider = false;
115+
116+
// If it's a generic enumerable, get the generic type.
117+
118+
// Unfortunately, if data source is fed from a bare IEnumerable, TypeHelper will report an element type of object,
119+
// which is not particularly interesting. It is dealt with it further on.
120+
itemType = listType.GetEnumerableItemType();
121+
122+
if (itemType != null)
123+
{
124+
isICustomTypeProvider = typeof(ICustomTypeProvider).IsAssignableFrom(itemType);
125+
}
126+
127+
// Bare IEnumerables mean that result type will be object. In that case, try to get something more interesting.
128+
// Or, if the itemType implements ICustomTypeProvider, try to retrieve the custom type from one of the object instances.
129+
if (itemType == null || itemType == typeof(object) || isICustomTypeProvider)
130+
{
131+
// No type was located yet. Does the list have anything in it?
132+
Type? firstItemType = null;
133+
var en = list.GetEnumerator();
134+
if (en.MoveNext() && en.Current != null)
135+
{
136+
firstItemType = en.Current.GetCustomOrCLRType();
137+
}
138+
else
139+
{
140+
firstItemType = list
141+
.Cast<object>() // cast to convert IEnumerable to IEnumerable<object>
142+
.Select(x => x.GetType()) // get the type
143+
.FirstOrDefault(); // get only the first thing to come out of the sequence, or null if empty
144+
}
145+
146+
if (firstItemType != typeof(object))
147+
{
148+
return firstItemType;
149+
}
150+
}
151+
152+
// Couldn't get the CustomType because there were no items.
153+
if (isICustomTypeProvider)
154+
{
155+
return null;
156+
}
157+
158+
return itemType;
159+
}
160+
161+
internal static Type? GetCustomOrCLRType(this object? instance)
162+
{
163+
if (instance is ICustomTypeProvider customTypeProvider)
164+
{
165+
return customTypeProvider.GetCustomType() ?? instance.GetType();
166+
}
167+
168+
return instance?.GetType();
169+
}
107170
}

src/Extensions/TypeExtensions.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
24
using System.Linq;
35
using System.Reflection;
46

@@ -111,7 +113,7 @@ public static Type GetNonNullableType(this Type type)
111113
public static bool IsPrimitive(this Type? dataType)
112114
{
113115
return dataType is not null &&
114-
(dataType.GetTypeInfo().IsPrimitive ||
116+
(dataType.IsPrimitive ||
115117
dataType == typeof(string) ||
116118
dataType == typeof(decimal) ||
117119
dataType == typeof(DateTime));
@@ -124,4 +126,51 @@ public static bool IsInheritedFromIComparable(this Type type)
124126
{
125127
return type.GetInterfaces().Any(i => i == typeof(IComparable));
126128
}
129+
130+
private static Type? FindGenericType(Type definition, Type type)
131+
{
132+
var definitionTypeInfo = definition.GetTypeInfo();
133+
134+
while (type != null && type != typeof(object))
135+
{
136+
var typeTypeInfo = type.GetTypeInfo();
137+
138+
if (typeTypeInfo.IsGenericType && type.GetGenericTypeDefinition() == definition)
139+
{
140+
return type;
141+
}
142+
143+
if (definitionTypeInfo.IsInterface)
144+
{
145+
foreach (var type2 in typeTypeInfo.ImplementedInterfaces)
146+
{
147+
var type3 = FindGenericType(definition, type2);
148+
if (type3 != null)
149+
{
150+
return type3;
151+
}
152+
}
153+
}
154+
155+
type = typeTypeInfo.BaseType!;
156+
}
157+
158+
return null;
159+
}
160+
161+
internal static Type GetEnumerableItemType(this Type enumerableType)
162+
{
163+
var type = FindGenericType(typeof(IEnumerable<>), enumerableType);
164+
if (type != null)
165+
{
166+
return type.GetGenericArguments()[0];
167+
}
168+
169+
return enumerableType;
170+
}
171+
172+
internal static bool IsEnumerableType(this Type enumerableType)
173+
{
174+
return FindGenericType(typeof(IEnumerable<>), enumerableType) != null;
175+
}
127176
}

src/TableView.Properties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ private static void OnAutoGenerateColumnsChanged(DependencyObject d, DependencyP
551551
{
552552
if (tableView.AutoGenerateColumns)
553553
{
554-
tableView.GenerateColumns();
554+
tableView.EnsureAutoColumns(true);
555555
}
556556
else
557557
{

0 commit comments

Comments
 (0)