mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-29 07:16:33 +08:00
Add ProcessFilter
This commit is contained in:
@@ -248,9 +248,17 @@ public abstract partial class DataGridColumn : AvaloniaObject
|
||||
|
||||
public bool CanUserFilter
|
||||
{
|
||||
get => CanUserResizeInternal ??
|
||||
OwningGrid?.CanUserFilterColumns ??
|
||||
DataGrid.DefaultCanUserResizeColumns;
|
||||
get
|
||||
{
|
||||
var canUserFilter = CanUserResizeInternal ??
|
||||
OwningGrid?.CanUserFilterColumns ??
|
||||
DataGrid.DefaultCanUserFilterColumns;
|
||||
if (HasHeaderCell)
|
||||
{
|
||||
HeaderCell.CanUserFilter = canUserFilter;
|
||||
}
|
||||
return canUserFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
CanUserFilterInternal = value;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// All other rights reserved.
|
||||
|
||||
using System.Diagnostics;
|
||||
using AtomUI.Controls.Data;
|
||||
using Avalonia;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
@@ -15,29 +16,111 @@ internal partial class DataGridColumnHeader
|
||||
nameof(CanUserFilter),
|
||||
o => o.CanUserFilter,
|
||||
(o, v) => o.CanUserFilter = v);
|
||||
|
||||
|
||||
private bool _canUserFilter = false;
|
||||
|
||||
internal bool CanUserFilter
|
||||
{
|
||||
get => _canUserFilter;
|
||||
set => SetAndRaise(CanUserFilterProperty, ref _canUserFilter, value);
|
||||
}
|
||||
|
||||
internal void InvokeProcessSort()
|
||||
|
||||
private DataGridFilterIndicator? _filterIndicator;
|
||||
|
||||
internal void InvokeProcessFilter(List<string> filterValues)
|
||||
{
|
||||
Debug.Assert(OwningGrid != null);
|
||||
if (OwningGrid.WaitForLostFocus(InvokeProcessSort))
|
||||
if (OwningGrid.WaitForLostFocus(() => InvokeProcessFilter(filterValues)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OwningGrid.CommitEdit(DataGridEditingUnit.Row, exitEditingMode: true))
|
||||
{
|
||||
Avalonia.Threading.Dispatcher.UIThread.Post(ProcessSort);
|
||||
Avalonia.Threading.Dispatcher.UIThread.Post(() => ProcessFilter(filterValues));
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProcessSort()
|
||||
internal void ProcessFilter(List<string> filterValues)
|
||||
{
|
||||
|
||||
if (OwningColumn != null &&
|
||||
OwningGrid != null &&
|
||||
OwningGrid.EditingRow == null &&
|
||||
OwningColumn != OwningGrid.ColumnsInternal.FillerColumn &&
|
||||
(OwningColumn.CanUserFilter || OwningGrid.CanUserFilterColumns))
|
||||
{
|
||||
var ea = new DataGridColumnEventArgs(OwningColumn);
|
||||
OwningGrid.HandleColumnFiltering(ea);
|
||||
if (!ea.Handled && OwningGrid.DataConnection.AllowFilter &&
|
||||
OwningGrid.DataConnection.FilterDescriptions != null)
|
||||
{
|
||||
DataGrid owningGrid = OwningGrid;
|
||||
DataGridFilterDescription? newFilter;
|
||||
DataGridFilterDescription? filter = OwningColumn.GetFilterDescription();
|
||||
IDataGridCollectionView? collectionView = owningGrid.DataConnection.CollectionView;
|
||||
Debug.Assert(collectionView != null);
|
||||
using (collectionView.DeferRefresh())
|
||||
{
|
||||
if (owningGrid.DataConnection.FilterDescriptions.Count == 0)
|
||||
{
|
||||
owningGrid.DataConnection.FilterDescriptions.Clear();
|
||||
}
|
||||
|
||||
if (filter != null)
|
||||
{
|
||||
// 比较一下值,如果过滤的值不相等就重新添加
|
||||
var oldFilterValues = filter.FilterConditions.ToHashSet();
|
||||
var newFilterValues = filterValues.ToHashSet();
|
||||
if (!oldFilterValues.SetEquals(newFilterValues))
|
||||
{
|
||||
newFilter = new DataGridFilterDescription()
|
||||
{
|
||||
PropertyPath = filter.PropertyPath,
|
||||
Filter = filter.Filter,
|
||||
FilterConditions = filterValues.Cast<object>().ToList(),
|
||||
};
|
||||
int oldIndex = owningGrid.DataConnection.FilterDescriptions.IndexOf(filter);
|
||||
if (oldIndex >= 0)
|
||||
{
|
||||
owningGrid.DataConnection.FilterDescriptions.Remove(filter);
|
||||
owningGrid.DataConnection.FilterDescriptions.Insert(oldIndex, newFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
owningGrid.DataConnection.FilterDescriptions.Add(newFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string? propertyName = OwningColumn.GetFilterPropertyName();
|
||||
if (string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
newFilter = new DataGridFilterDescription()
|
||||
{
|
||||
PropertyPath = propertyName,
|
||||
Filter = OwningColumn.OnFilter,
|
||||
FilterConditions = filterValues.Cast<object>().ToList(),
|
||||
};
|
||||
owningGrid.DataConnection.FilterDescriptions.Add(newFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureFilterIndicator()
|
||||
{
|
||||
if (_filterIndicator != null)
|
||||
{
|
||||
_filterIndicator.FilterRequest += HandleFilterRequest;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleFilterRequest(object? sender, DataGridColumnFilterEventArgs args)
|
||||
{
|
||||
InvokeProcessFilter(args.FilterValues);
|
||||
}
|
||||
}
|
||||
@@ -201,7 +201,6 @@ internal partial class DataGridColumnHeader : ContentControl
|
||||
private bool _desiredSeparatorVisibility = true;
|
||||
private StackPanel? _indicatorsLayout;
|
||||
private static Lazy<Cursor> _resizeCursor = new Lazy<Cursor>(() => new Cursor(StandardCursorType.SizeWestEast));
|
||||
private DataGridFilterIndicator? _filterIndicator;
|
||||
private Border? _frame;
|
||||
|
||||
static DataGridColumnHeader()
|
||||
@@ -863,6 +862,8 @@ internal partial class DataGridColumnHeader : ContentControl
|
||||
{
|
||||
_filterIndicator.OwningColumn = OwningColumn;
|
||||
}
|
||||
|
||||
ConfigureFilterIndicator();
|
||||
if (_indicatorsLayout != null)
|
||||
{
|
||||
_indicatorsLayout.Children.CollectionChanged += HandleIndicatorLayoutChildrenChanged;
|
||||
|
||||
@@ -26,6 +26,8 @@ internal class DataGridFilterIndicator : IconButton
|
||||
|
||||
public static readonly StyledProperty<bool> FilterMultipleProperty =
|
||||
AvaloniaProperty.Register<DataGridFilterIndicator, bool>(nameof(FilterMultiple));
|
||||
|
||||
public event EventHandler<DataGridColumnFilterEventArgs>? FilterRequest;
|
||||
|
||||
public bool IsFilterActivated
|
||||
{
|
||||
@@ -242,6 +244,11 @@ internal class DataGridFilterIndicator : IconButton
|
||||
|
||||
private void HandleFilterValuesSelected(object? sender, DataGridFilterValuesSelectedEventArgs args)
|
||||
{
|
||||
Debug.Assert(OwningColumn != null);
|
||||
if (OwningColumn.FilterOnClose || args.IsConfirmed)
|
||||
{
|
||||
FilterRequest?.Invoke(this, new DataGridColumnFilterEventArgs(OwningColumn, args.Values));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
|
||||
@@ -101,6 +101,22 @@ internal class DataGridDataConnection
|
||||
return CollectionView.CanSort;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if the collection view says it can filter.
|
||||
/// </summary>
|
||||
public bool AllowFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CollectionView == null ||
|
||||
(EditableCollectionView != null && (EditableCollectionView.IsAddingNew || EditableCollectionView.IsEditingItem)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return CollectionView.CanFilter;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CommittingEdit { get; private set; }
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ public class DataGridFilterDescription
|
||||
public string? PropertyPath { get; set; }
|
||||
public bool HasPropertyPath => !string.IsNullOrEmpty(PropertyPath);
|
||||
public StringComparison ComparisonType { get; } = StringComparison.InvariantCultureIgnoreCase;
|
||||
public bool IsEnabled { get; set; }
|
||||
public int ColumnIndex { get; set; }
|
||||
|
||||
public List<object> FilterConditions { get; set; } = new List<object>();
|
||||
public Func<object, object, bool>? Filter { get; set; }
|
||||
|
||||
|
||||
@@ -119,6 +119,11 @@ public partial class DataGrid
|
||||
{
|
||||
Sorting?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected internal virtual void HandleColumnFiltering(DataGridColumnEventArgs e)
|
||||
{
|
||||
Filtering?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the widths of all columns with DisplayIndex >= displayIndex such that the total
|
||||
|
||||
@@ -718,6 +718,11 @@ public partial class DataGrid : TemplatedControl,
|
||||
/// Occurs when the <see cref="DataGridColumn"/> sorting request is triggered.
|
||||
/// </summary>
|
||||
public event EventHandler<DataGridColumnEventArgs>? Sorting;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the <see cref="DataGridColumn"/> filtering request is triggered.
|
||||
/// </summary>
|
||||
public event EventHandler<DataGridColumnEventArgs>? Filtering;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a <see cref="T:AtomUI.Controls.DataGridRow" />
|
||||
|
||||
@@ -2,16 +2,13 @@ namespace AtomUI.Controls;
|
||||
|
||||
public class DataGridColumnFilterEventArgs : EventArgs
|
||||
{
|
||||
public DataGridFilterMode FilterMode { get; }
|
||||
public List<string> FilterValues { get; }
|
||||
|
||||
public DataGridColumn Column { get; }
|
||||
|
||||
public DataGridColumnFilterEventArgs(DataGridColumn column, DataGridFilterMode filterMode,
|
||||
List<string> filterValues)
|
||||
public DataGridColumnFilterEventArgs(DataGridColumn column, List<string> filterValues)
|
||||
{
|
||||
Column = column;
|
||||
FilterMode = filterMode;
|
||||
FilterValues = filterValues;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user