PageRenderTime 46ms CodeModel.GetById 8ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 1ms

/ILSpy/Controls/SortableGridViewColumn.cs

http://github.com/icsharpcode/ILSpy
C# | 237 lines | 177 code | 29 blank | 31 comment | 45 complexity | fd5d8868528314042152208950230201 MD5 | raw file
  1// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
  2// 
  3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4// software and associated documentation files (the "Software"), to deal in the Software
  5// without restriction, including without limitation the rights to use, copy, modify, merge,
  6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7// to whom the Software is furnished to do so, subject to the following conditions:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 17// DEALINGS IN THE SOFTWARE.
 18
 19using System;
 20using System.ComponentModel;
 21using System.Windows;
 22using System.Windows.Controls;
 23using System.Windows.Data;
 24
 25namespace ICSharpCode.ILSpy.Controls
 26{
 27	/// <summary>
 28	/// Allows to automatically sort a grid view.
 29	/// </summary>
 30	public class SortableGridViewColumn : GridViewColumn
 31	{
 32		// This class was copied from ICSharpCode.Core.Presentation.
 33		
 34		static readonly ComponentResourceKey headerTemplateKey = new ComponentResourceKey(typeof(SortableGridViewColumn), "ColumnHeaderTemplate");
 35		
 36		public SortableGridViewColumn()
 37		{
 38			this.SetValueToExtension(HeaderTemplateProperty, new DynamicResourceExtension(headerTemplateKey));
 39		}
 40		
 41		string sortBy;
 42		
 43		public string SortBy {
 44			get { return sortBy; }
 45			set {
 46				if (sortBy != value) {
 47					sortBy = value;
 48					OnPropertyChanged(new PropertyChangedEventArgs("SortBy"));
 49				}
 50			}
 51		}
 52		
 53		#region SortDirection property
 54		public static readonly DependencyProperty SortDirectionProperty =
 55			DependencyProperty.RegisterAttached("SortDirection", typeof(ColumnSortDirection), typeof(SortableGridViewColumn),
 56			                                    new FrameworkPropertyMetadata(ColumnSortDirection.None, OnSortDirectionChanged));
 57		
 58		public ColumnSortDirection SortDirection {
 59			get { return (ColumnSortDirection)GetValue(SortDirectionProperty); }
 60			set { SetValue(SortDirectionProperty, value); }
 61		}
 62		
 63		public static ColumnSortDirection GetSortDirection(ListView listView)
 64		{
 65			return (ColumnSortDirection)listView.GetValue(SortDirectionProperty);
 66		}
 67		
 68		public static void SetSortDirection(ListView listView, ColumnSortDirection value)
 69		{
 70			listView.SetValue(SortDirectionProperty, value);
 71		}
 72		
 73		static void OnSortDirectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
 74		{
 75			ListView grid = sender as ListView;
 76			if (grid != null) {
 77				SortableGridViewColumn col = GetCurrentSortColumn(grid);
 78				if (col != null)
 79					col.SortDirection = (ColumnSortDirection)args.NewValue;
 80				Sort(grid);
 81			}
 82		}
 83		#endregion
 84		
 85		#region CurrentSortColumn property
 86		public static readonly DependencyProperty CurrentSortColumnProperty =
 87			DependencyProperty.RegisterAttached("CurrentSortColumn", typeof(SortableGridViewColumn), typeof(SortableGridViewColumn),
 88			                                    new FrameworkPropertyMetadata(OnCurrentSortColumnChanged));
 89		
 90		public static SortableGridViewColumn GetCurrentSortColumn(ListView listView)
 91		{
 92			return (SortableGridViewColumn)listView.GetValue(CurrentSortColumnProperty);
 93		}
 94		
 95		public static void SetCurrentSortColumn(ListView listView, SortableGridViewColumn value)
 96		{
 97			listView.SetValue(CurrentSortColumnProperty, value);
 98		}
 99		
100		static void OnCurrentSortColumnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
101		{
102			ListView grid = sender as ListView;
103			if (grid != null) {
104				SortableGridViewColumn oldColumn = (SortableGridViewColumn)args.OldValue;
105				if (oldColumn != null)
106					oldColumn.SortDirection = ColumnSortDirection.None;
107				SortableGridViewColumn newColumn = (SortableGridViewColumn)args.NewValue;
108				if (newColumn != null) {
109					newColumn.SortDirection = GetSortDirection(grid);
110				}
111				Sort(grid);
112			}
113		}
114		#endregion
115		
116		#region SortMode property
117		public static readonly DependencyProperty SortModeProperty =
118			DependencyProperty.RegisterAttached("SortMode", typeof(ListViewSortMode), typeof(SortableGridViewColumn),
119			                                    new FrameworkPropertyMetadata(ListViewSortMode.None, OnSortModeChanged));
120		
121		public static ListViewSortMode GetSortMode(ListView listView)
122		{
123			return (ListViewSortMode)listView.GetValue(SortModeProperty);
124		}
125		
126		public static void SetSortMode(ListView listView, ListViewSortMode value)
127		{
128			listView.SetValue(SortModeProperty, value);
129		}
130		
131		static void OnSortModeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
132		{
133			ListView grid = sender as ListView;
134			if (grid != null) {
135				if ((ListViewSortMode)args.NewValue != ListViewSortMode.None)
136					grid.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(GridViewColumnHeaderClickHandler));
137				else
138					grid.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(GridViewColumnHeaderClickHandler));
139			}
140		}
141		
142		static void GridViewColumnHeaderClickHandler(object sender, RoutedEventArgs e)
143		{
144			ListView grid = sender as ListView;
145			GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
146			if (grid != null && headerClicked != null && headerClicked.Role != GridViewColumnHeaderRole.Padding) {
147				if (headerClicked.Column == GetCurrentSortColumn(grid)) {
148					switch (GetSortDirection(grid)) {
149						case ColumnSortDirection.None:
150							SetSortDirection(grid, ColumnSortDirection.Ascending);
151							break;
152						case ColumnSortDirection.Ascending:
153							SetSortDirection(grid, ColumnSortDirection.Descending);
154							break;
155						case ColumnSortDirection.Descending:
156							SetSortDirection(grid, ColumnSortDirection.None);
157							break;
158					}
159				} else {
160					SetSortDirection(grid, ColumnSortDirection.Ascending);
161					SetCurrentSortColumn(grid, headerClicked.Column as SortableGridViewColumn);
162				}
163			}
164		}
165		#endregion
166		
167		static void Sort(ListView grid)
168		{
169			ColumnSortDirection currentDirection = GetSortDirection(grid);
170			SortableGridViewColumn column = GetCurrentSortColumn(grid);
171			ICollectionView dataView = CollectionViewSource.GetDefaultView(grid.ItemsSource);
172
173			if (dataView == null) return;
174
175			if (column != null && GetSortMode(grid) == ListViewSortMode.Automatic && currentDirection != ColumnSortDirection.None) {
176				string sortBy = column.SortBy;
177				if (sortBy == null) {
178					Binding binding = column.DisplayMemberBinding as Binding;
179					if (binding != null && binding.Path != null) {
180						sortBy = binding.Path.Path;
181					}
182				}
183
184				dataView.SortDescriptions.Clear();
185				if (sortBy != null) {
186					ListSortDirection direction;
187					if (currentDirection == ColumnSortDirection.Descending)
188						direction = ListSortDirection.Descending;
189					else
190						direction = ListSortDirection.Ascending;
191					dataView.SortDescriptions.Add(new SortDescription(sortBy, direction));
192				}
193			} else {
194				dataView.SortDescriptions.Clear();
195			}
196
197			dataView.Refresh();
198		}
199	}
200	
201	public enum ColumnSortDirection
202	{
203		None,
204		Ascending,
205		Descending
206	}
207	
208	public enum ListViewSortMode
209	{
210		/// <summary>
211		/// Disable automatic sorting when sortable columns are clicked.
212		/// </summary>
213		None,
214		/// <summary>
215		/// Fully automatic sorting.
216		/// </summary>
217		Automatic,
218		/// <summary>
219		/// Automatically update SortDirection and CurrentSortColumn properties,
220		/// but do not actually sort the data.
221		/// </summary>
222		HalfAutomatic
223	}
224	
225	sealed class ColumnSortDirectionToVisibilityConverter : IValueConverter
226	{
227		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
228		{
229			return Equals(value, parameter) ? Visibility.Visible : Visibility.Collapsed;
230		}
231		
232		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
233		{
234			throw new NotSupportedException();
235		}
236	}
237}