/// <summary> /// Synchronizes the sort descriptions collection to the sort descriptors collection. /// </summary> /// <param name="descriptor">The descriptor that changed</param> /// <param name="e">The property change event</param> private void HandleSortDescriptorChanged(SortDescriptor descriptor, PropertyChangedEventArgs e) { this._ignoreChanges = true; try { // We have to reset when the collections were not equal before the change if (this._sourceCollection.Count != this._descriptionCollection.Count) { SortCollectionManager.ResetToSortDescriptors(this._descriptionCollection, this._sourceCollection); } else { int index = this._sourceCollection.IndexOf(descriptor); SortDescription?description = SortCollectionManager.GetDescriptionFromDescriptor(descriptor); if (!description.HasValue) { this._descriptionCollection.RemoveAt(index); } else { this._descriptionCollection[index] = description.Value; } } } finally { this._ignoreChanges = false; } }
internal void UpdateSort(string propertyName, ListSortDirection sortDirection) { var sortDesc = new SortDescription(propertyName, sortDirection); if (_wordsView == null) _deferredSortDesc = sortDesc; else UpdateSort(sortDesc); }
/// <summary> /// Resets the <paramref name="sortDescriptions"/> collection to match the <paramref name="sortDescriptors"/> collection. /// </summary> /// <param name="sortDescriptions">The collection to reset</param> /// <param name="sortDescriptors">The collection to match</param> private static void ResetToSortDescriptors(SortDescriptionCollection sortDescriptions, SortDescriptorCollection sortDescriptors) { sortDescriptions.Clear(); foreach (SortDescriptor descriptor in sortDescriptors) { SortDescription?description = SortCollectionManager.GetDescriptionFromDescriptor(descriptor); if (description.HasValue) { sortDescriptions.Add(description.Value); } } }
private static SortDescription?GetDescriptionFromExpression(ListSortDirection direction, Expression <Func <T, object> > memberExpression) { SortDescription?maybe = null; if (TryGetMemberNameFromExpression(memberExpression, out string memberName)) { var sortDesc = new SortDescription(memberName, direction); maybe = sortDesc; } return(maybe); }
/// <summary> /// Synchronizes the sort descriptions collection to the sort descriptors collection. /// </summary> /// <param name="e">The collection change event</param> private void HandleSortDescriptorCollectionChanged(NotifyCollectionChangedEventArgs e) { this._ignoreChanges = true; try { // We have to reset in a number of situations // 1) Resetting the SortDescriptors // 2) Collections were not equal before replacing SortDescriptors // 3) Collections were not equal before removing SortDescriptors // 4) Collections were not equal before adding SortDescriptors if ((e.Action == NotifyCollectionChangedAction.Reset) || ((e.Action == NotifyCollectionChangedAction.Replace) && ((this._sourceCollection.Count + e.OldItems.Count) != (this._descriptionCollection.Count + e.NewItems.Count))) || ((e.Action == NotifyCollectionChangedAction.Remove) && ((this._sourceCollection.Count + e.OldItems.Count) != this._descriptionCollection.Count)) || ((e.Action == NotifyCollectionChangedAction.Add) && (this._sourceCollection.Count != (this._descriptionCollection.Count + e.NewItems.Count)))) { SortCollectionManager.ResetToSortDescriptors(this._descriptionCollection, this._sourceCollection); } else { if ((e.Action == NotifyCollectionChangedAction.Remove) || (e.Action == NotifyCollectionChangedAction.Replace)) { int index = e.OldStartingIndex; if (e.Action == NotifyCollectionChangedAction.Replace) // TODO: This is a DependencyObjectCollection bug! { index = e.NewStartingIndex; } for (int i = 0; i < e.OldItems.Count; i++) { this._descriptionCollection.RemoveAt(index); } } if ((e.Action == NotifyCollectionChangedAction.Add) || (e.Action == NotifyCollectionChangedAction.Replace)) { int index = e.NewStartingIndex; foreach (object item in e.NewItems) { SortDescription?description = SortCollectionManager.GetDescriptionFromDescriptor((SortDescriptor)item); if (description.HasValue) { this._descriptionCollection.Insert(index++, description.Value); } } } } } finally { this._ignoreChanges = false; } }
private void InnerUpdateSorting(SortKeySelection nextSortKeySelection, SortDirectionSelection nextSortDirectionSelection) { if (nextSortDirectionSelection == SortDirectionSelection.None) { nextSortKeySelection = SortKeySelection.None; } var sortDirection = (nextSortDirectionSelection == SortDirectionSelection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending; SortDescription?sortDescription = null; switch (nextSortKeySelection) { case SortKeySelection.None: break; case SortKeySelection.SubstLocName: sortDescription = new SortDescription("CombinedInfo.SubstLocInfo.ObjID.Name", sortDirection); break; case SortKeySelection.SubstInfoFrom: sortDescription = new SortDescription("CombinedInfo.SubstInfoFrom", sortDirection); break; case SortKeySelection.SubstName: sortDescription = new SortDescription("CombinedInfo.SubstInfo.ObjID.Name", sortDirection); break; default: break; } if (sortDescription == null) { if (listView.Items.SortDescriptions.Count > 0) { listView.Items.SortDescriptions.Clear(); currentSortKeySelection = SortKeySelection.None; currentSortDirectionSelection = SortDirectionSelection.None; } } else { if (listView.Items.SortDescriptions.Count == 0) { listView.Items.SortDescriptions.Add(sortDescription ?? default(SortDescription)); } else { listView.Items.SortDescriptions[0] = sortDescription ?? default(SortDescription); } currentSortKeySelection = nextSortKeySelection; currentSortDirectionSelection = nextSortDirectionSelection; } }
internal void ApplyState(bool useTransitions) { // Common States if (this.IsPressed && DataGridColumnHeader._dragMode != DragMode.Resize) { VisualStates.GoToState(this, useTransitions, VisualStates.StatePressed, VisualStates.StateMouseOver, VisualStates.StateNormal); } else if (this.IsMouseOver && DataGridColumnHeader._dragMode != DragMode.Resize) { VisualStates.GoToState(this, useTransitions, VisualStates.StateMouseOver, VisualStates.StateNormal); } else { VisualStates.GoToState(this, useTransitions, VisualStates.StateNormal); } // Sort States this.CurrentSortingState = null; if (this.OwningGrid != null && this.OwningGrid.DataConnection != null && this.OwningGrid.DataConnection.AllowSort) { SortDescription?sort = this.OwningColumn.GetSortDescription(); if (sort.HasValue) { this.CurrentSortingState = sort.Value.Direction; if (this.CurrentSortingState == ListSortDirection.Ascending) { VisualStates.GoToState(this, useTransitions, VisualStates.StateSortAscending, VisualStates.StateUnsorted); } if (this.CurrentSortingState == ListSortDirection.Descending) { VisualStates.GoToState(this, useTransitions, VisualStates.StateSortDescending, VisualStates.StateUnsorted); } } else { VisualStates.GoToState(this, useTransitions, VisualStates.StateUnsorted); } } }
internal void ApplyState() { // Common States if (this.IsMouseOver) { VisualStates.GoToState(this, true, VisualStates.StateMouseOver, VisualStates.StateNormal); } else { VisualStates.GoToState(this, true, VisualStates.StateNormal); } // Sort States this.CurrentSortingState = null; if (this.OwningGrid != null && this.OwningGrid.DataConnection != null && this.OwningGrid.DataConnection.AllowSort) { SortDescription?sort = this.OwningColumn.GetSortDescription(); if (sort.HasValue) { this.CurrentSortingState = sort.Value.Direction; if (this.CurrentSortingState == ListSortDirection.Ascending) { VisualStates.GoToState(this, true, VisualStates.StateSortAscending, VisualStates.StateUnsorted); } if (this.CurrentSortingState == ListSortDirection.Descending) { VisualStates.GoToState(this, true, VisualStates.StateSortDescending, VisualStates.StateUnsorted); } } else { VisualStates.GoToState(this, true, VisualStates.StateUnsorted); } } }
private void ProcessSort() { if (this.OwningColumn != null && this.OwningGrid != null && this.OwningGrid.EditingRow == null && this.OwningColumn != this.OwningGrid.ColumnsInternal.FillerColumn && this.OwningGrid.CanUserSortColumns && this.OwningColumn.CanUserSort) { DataGridColumnEventArgs ea = new DataGridColumnEventArgs(this.OwningColumn); this.OwningGrid.OnColumnSorting(ea); #if FEATURE_ICOLLECTIONVIEW_SORT if (!ea.Handled && this.OwningGrid.DataConnection.AllowSort && this.OwningGrid.DataConnection.SortDescriptions != null) { // - DataConnection.AllowSort is true, and // - SortDescriptionsCollection exists, and // - the column's data type is comparable DataGrid owningGrid = this.OwningGrid; ListSortDirection newSortDirection; SortDescription newSort; bool ctrl; bool shift; KeyboardHelper.GetMetaKeyState(out ctrl, out shift); SortDescription?sort = this.OwningColumn.GetSortDescription(); ICollectionView collectionView = owningGrid.DataConnection.CollectionView; Debug.Assert(collectionView != null); try { owningGrid.OnUserSorting(); using (collectionView.DeferRefresh()) { // If shift is held down, we multi-sort, therefore if it isn't, we'll clear the sorts beforehand if (!shift || owningGrid.DataConnection.SortDescriptions.Count == 0) { if (collectionView.CanGroup && collectionView.GroupDescriptions != null) { // Make sure we sort by the GroupDescriptions first for (int i = 0; i < collectionView.GroupDescriptions.Count; i++) { PropertyGroupDescription groupDescription = collectionView.GroupDescriptions[i] as PropertyGroupDescription; if (groupDescription != null && collectionView.SortDescriptions.Count <= i || collectionView.SortDescriptions[i].PropertyName != groupDescription.PropertyName) { collectionView.SortDescriptions.Insert(Math.Min(i, collectionView.SortDescriptions.Count), new SortDescription(groupDescription.PropertyName, ListSortDirection.Ascending)); } } while (collectionView.SortDescriptions.Count > collectionView.GroupDescriptions.Count) { collectionView.SortDescriptions.RemoveAt(collectionView.GroupDescriptions.Count); } } else if (!shift) { owningGrid.DataConnection.SortDescriptions.Clear(); } } if (sort.HasValue) { // swap direction switch (sort.Value.Direction) { case ListSortDirection.Ascending: newSortDirection = ListSortDirection.Descending; break; default: newSortDirection = ListSortDirection.Ascending; break; } newSort = new SortDescription(sort.Value.PropertyName, newSortDirection); // changing direction should not affect sort order, so we replace this column's // sort description instead of just adding it to the end of the collection int oldIndex = owningGrid.DataConnection.SortDescriptions.IndexOf(sort.Value); if (oldIndex >= 0) { owningGrid.DataConnection.SortDescriptions.Remove(sort.Value); owningGrid.DataConnection.SortDescriptions.Insert(oldIndex, newSort); } else { owningGrid.DataConnection.SortDescriptions.Add(newSort); } } else { // start new sort newSortDirection = ListSortDirection.Ascending; string propertyName = this.OwningColumn.GetSortPropertyName(); // no-opt if we couldn't find a property to sort on if (string.IsNullOrEmpty(propertyName)) { return; } newSort = new SortDescription(propertyName, newSortDirection); owningGrid.DataConnection.SortDescriptions.Add(newSort); } } } finally { owningGrid.OnUserSorted(); } sortProcessed = true; } #endif // Send the Invoked event for the column header's automation peer. DataGridAutomationPeer.RaiseAutomationInvokeEvent(this); } }
internal void ProcessSort() { // if we can sort: // - DataConnection.AllowSort is true, and // - AllowUserToSortColumns and CanSort are true, and // - OwningColumn is bound, and // - SortDescriptionsCollection exists, and // - the column's data type is comparable // then try to sort if (this.OwningColumn != null && this.OwningGrid != null && this.OwningGrid.EditingRow == null && this.OwningColumn != this.OwningGrid.ColumnsInternal.FillerColumn && this.OwningGrid.DataConnection.AllowSort && this.OwningGrid.CanUserSortColumns && this.OwningColumn.CanUserSort && this.OwningGrid.DataConnection.SortDescriptions != null) { DataGrid owningGrid = this.OwningGrid; ListSortDirection newSortDirection; SortDescription newSort; bool ctrl; bool shift; KeyboardHelper.GetMetaKeyState(out ctrl, out shift); SortDescription?sort = this.OwningColumn.GetSortDescription(); ICollectionView collectionView = owningGrid.DataConnection.CollectionView; Debug.Assert(collectionView != null); using (collectionView.DeferRefresh()) { // if shift is held down, we multi-sort, therefore if it isn't, we'll clear the sorts beforehand if (!shift || owningGrid.DataConnection.SortDescriptions.Count == 0) { if (collectionView.CanGroup && collectionView.GroupDescriptions != null) { // Make sure we sort by the GroupDescriptions first for (int i = 0; i < collectionView.GroupDescriptions.Count; i++) { PropertyGroupDescription groupDescription = collectionView.GroupDescriptions[i] as PropertyGroupDescription; if (groupDescription != null && collectionView.SortDescriptions.Count <= i || collectionView.SortDescriptions[i].PropertyName != groupDescription.PropertyName) { collectionView.SortDescriptions.Insert(Math.Min(i, collectionView.SortDescriptions.Count), new SortDescription(groupDescription.PropertyName, ListSortDirection.Ascending)); } } while (collectionView.SortDescriptions.Count > collectionView.GroupDescriptions.Count) { collectionView.SortDescriptions.RemoveAt(collectionView.GroupDescriptions.Count); } } else if (!shift) { owningGrid.DataConnection.SortDescriptions.Clear(); } } if (sort.HasValue) { // swap direction switch (sort.Value.Direction) { case ListSortDirection.Ascending: newSortDirection = ListSortDirection.Descending; break; default: newSortDirection = ListSortDirection.Ascending; break; } newSort = new SortDescription(sort.Value.PropertyName, newSortDirection); // changing direction should not affect sort order, so we replace this column's // sort description instead of just adding it to the end of the collection int oldIndex = owningGrid.DataConnection.SortDescriptions.IndexOf(sort.Value); if (oldIndex >= 0) { owningGrid.DataConnection.SortDescriptions.Remove(sort.Value); owningGrid.DataConnection.SortDescriptions.Insert(oldIndex, newSort); } else { owningGrid.DataConnection.SortDescriptions.Add(newSort); } } else { // start new sort newSortDirection = ListSortDirection.Ascending; string propertyName = this.OwningColumn.GetSortPropertyName(); // no-opt if we couldn't find a property to sort on if (string.IsNullOrEmpty(propertyName)) { return; } newSort = new SortDescription(propertyName, newSortDirection); owningGrid.DataConnection.SortDescriptions.Add(newSort); } } // We've completed the sort, so send the Invoked event for the column header's automation peer if (AutomationPeer.ListenerExists(AutomationEvents.InvokePatternOnInvoked)) { AutomationPeer peer = FrameworkElementAutomationPeer.FromElement(this); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.InvokePatternOnInvoked); } } } }
public BaseViewCollection(IEnumerable <T> items, SortDescription?sortDescription) : base(items.Where(x => x != null)) { _defaultSortDescription = sortDescription; this.UpdateView(); }
public BaseViewCollection(ListSortDirection direction, Expression <Func <T, object> > sortExpression) : base() { _defaultSortDescription = GetDescriptionFromExpression(direction, sortExpression); this.UpdateView(); }
internal void ProcessSort() { // if we can sort: // - DataConnection.AllowSort is true, and // - AllowUserToSortColumns and CanSort are true, and // - OwningColumn is bound, and // - SortDescriptionsCollection exists, and // - the column's data type is comparable // then try to sort if (this.OwningColumn != this.OwningGrid.ColumnsInternal.FillerColumn && this.OwningGrid.DataConnection.AllowSort && this.OwningGrid.CanUserSortColumns && this.OwningColumn.CanUserSort && this.OwningGrid.DataConnection.SortDescriptions != null) { ListSortDirection newSortDirection; SortDescription newSort; bool ctrl; bool shift; KeyboardHelper.GetMetaKeyState(out ctrl, out shift); SortDescription?sort = this.OwningColumn.GetSortDescription(); // if shift is held down, we multi-sort, therefore if it isn't, we'll clear the sorts beforehand if (!shift) { this.OwningGrid.DataConnection.SortDescriptions.Clear(); } if (sort.HasValue) { // swap direction switch (sort.Value.Direction) { case ListSortDirection.Ascending: newSortDirection = ListSortDirection.Descending; break; default: newSortDirection = ListSortDirection.Ascending; break; } newSort = new SortDescription(sort.Value.PropertyName, newSortDirection); // changing direction should not affect sort order, so we replace this column's // sort description instead of just adding it to the end of the collection int oldIndex = this.OwningGrid.DataConnection.SortDescriptions.IndexOf(sort.Value); if (oldIndex >= 0) { this.OwningGrid.DataConnection.SortDescriptions.Remove(sort.Value); this.OwningGrid.DataConnection.SortDescriptions.Insert(oldIndex, newSort); } else { this.OwningGrid.DataConnection.SortDescriptions.Add(newSort); } } else { // start new sort newSortDirection = ListSortDirection.Ascending; string propertyName = this.OwningColumn.GetSortPropertyName(); // no-opt if we couldn't find a property to sort on if (string.IsNullOrEmpty(propertyName)) { return; } newSort = new SortDescription(propertyName, newSortDirection); this.OwningGrid.DataConnection.SortDescriptions.Add(newSort); } // We've completed the sort, so send the Invoked event for the column header's automation peer if (AutomationPeer.ListenerExists(AutomationEvents.InvokePatternOnInvoked)) { AutomationPeer peer = FrameworkElementAutomationPeer.FromElement(this); if (peer != null) { peer.RaiseAutomationEvent(AutomationEvents.InvokePatternOnInvoked); } } } }