├── .gitattributes ├── .gitignore ├── PaggingControlProject.sln.DotSettings ├── PagingControlProject.sln ├── PagingControlProject.sln.DotSettings ├── PagingControlProject ├── App.cs ├── App.xaml ├── Custom Control │ ├── IPageControlContract.cs │ ├── PageChangedEventArgs.cs │ ├── PageChanges.cs │ └── PagingControl.cs ├── CustomSortingDataGrid.cs ├── Database │ ├── MyService.cs │ └── Student.cs ├── MainViewModel.cs ├── MainWindow.cs ├── MainWindow.xaml ├── PagingControlProject.csproj ├── Properties │ ├── Annotations.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── SortData.cs ├── app.config └── packages.config └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /PaggingControlProject.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /PagingControlProject.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PagingControlProject", "PagingControlProject\PagingControlProject.csproj", "{B2B01F0C-538B-4956-AB88-53B7258E2662}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x86 = Debug|x86 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B2B01F0C-538B-4956-AB88-53B7258E2662}.Debug|x86.ActiveCfg = Debug|x86 15 | {B2B01F0C-538B-4956-AB88-53B7258E2662}.Debug|x86.Build.0 = Debug|x86 16 | {B2B01F0C-538B-4956-AB88-53B7258E2662}.Release|x86.ActiveCfg = Release|x86 17 | {B2B01F0C-538B-4956-AB88-53B7258E2662}.Release|x86.Build.0 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /PagingControlProject.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /PagingControlProject/App.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace PagingControlProject 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PagingControlProject/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PagingControlProject/Custom Control/IPageControlContract.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject.Custom_Control 2 | { 3 | using System.Collections.Generic; 4 | 5 | public interface IPageControlContract 6 | { 7 | int GetTotalCount(); 8 | ICollection GetRecordsBy(int startingIndex, int numberOfRecords, object sortData); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /PagingControlProject/Custom Control/PageChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject.Custom_Control 2 | { 3 | using System.Windows; 4 | 5 | public class PageChangedEventArgs : RoutedEventArgs 6 | { 7 | #region PRIVATE VARIABLES 8 | 9 | private int _OldPage, _NewPage, _TotalPages; 10 | 11 | #endregion 12 | 13 | #region PROPERTIES 14 | 15 | public int OldPage 16 | { 17 | get 18 | { 19 | return _OldPage; 20 | } 21 | } 22 | 23 | public int NewPage 24 | { 25 | get 26 | { 27 | return _NewPage; 28 | } 29 | } 30 | 31 | public int TotalPages 32 | { 33 | get 34 | { 35 | return _TotalPages; 36 | } 37 | } 38 | 39 | #endregion 40 | 41 | #region CONSTRUCTOR 42 | 43 | public PageChangedEventArgs(RoutedEvent EventToRaise, int OldPage, int NewPage, int TotalPages) 44 | : base(EventToRaise) 45 | { 46 | _OldPage = OldPage; 47 | _NewPage = NewPage; 48 | _TotalPages = TotalPages; 49 | } 50 | 51 | #endregion 52 | } 53 | } -------------------------------------------------------------------------------- /PagingControlProject/Custom Control/PageChanges.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject.Custom_Control 2 | { 3 | internal enum PageChanges 4 | { 5 | First, 6 | Previous, 7 | Current, 8 | Next, 9 | Last 10 | } 11 | } -------------------------------------------------------------------------------- /PagingControlProject/Custom Control/PagingControl.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject.Custom_Control 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.ObjectModel; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Data; 11 | 12 | [TemplatePart(Name = "PART_FirstPageButton", Type = typeof(Button)), 13 | TemplatePart(Name = "PART_PreviousPageButton", Type = typeof(Button)), 14 | TemplatePart(Name = "PART_PageTextBox", Type = typeof(TextBox)), 15 | TemplatePart(Name = "PART_NextPageButton", Type = typeof(Button)), 16 | TemplatePart(Name = "PART_LastPageButton", Type = typeof(Button)), 17 | TemplatePart(Name = "PART_PageSizesCombobox", Type = typeof(ComboBox))] 18 | public class PagingControl : Control 19 | { 20 | #region CUSTOM CONTROL VARIABLES 21 | 22 | protected Button btnFirstPage, btnPreviousPage, btnNextPage, btnLastPage; 23 | protected TextBox txtPage; 24 | protected ComboBox cmbPageSizes; 25 | 26 | #endregion 27 | 28 | #region PROPERTIES 29 | 30 | public static readonly DependencyProperty ItemsSourceProperty; 31 | public static readonly DependencyProperty PageProperty; 32 | public static readonly DependencyProperty TotalPagesProperty; 33 | public static readonly DependencyProperty PageSizesProperty; 34 | public static readonly DependencyProperty PageContractProperty; 35 | public static readonly DependencyProperty FilterProperty; 36 | 37 | public ObservableCollection ItemsSource 38 | { 39 | get 40 | { 41 | return GetValue(ItemsSourceProperty) as ObservableCollection; 42 | } 43 | protected set 44 | { 45 | SetValue(ItemsSourceProperty, value); 46 | } 47 | } 48 | 49 | public int Page 50 | { 51 | get 52 | { 53 | return (int)GetValue(PageProperty); 54 | } 55 | set 56 | { 57 | SetValue(PageProperty, value); 58 | } 59 | } 60 | 61 | public int TotalPages 62 | { 63 | get 64 | { 65 | return (int)GetValue(TotalPagesProperty); 66 | } 67 | protected set 68 | { 69 | SetValue(TotalPagesProperty, value); 70 | } 71 | } 72 | 73 | public ObservableCollection PageSizes 74 | { 75 | get 76 | { 77 | return GetValue(PageSizesProperty) as ObservableCollection; 78 | } 79 | } 80 | 81 | public IPageControlContract PageContract 82 | { 83 | get 84 | { 85 | return GetValue(PageContractProperty) as IPageControlContract; 86 | } 87 | set 88 | { 89 | SetValue(PageContractProperty, value); 90 | } 91 | } 92 | 93 | public object Filter 94 | { 95 | get 96 | { 97 | return GetValue(FilterProperty); 98 | } 99 | set 100 | { 101 | SetValue(FilterProperty, value); 102 | } 103 | } 104 | 105 | #endregion 106 | 107 | #region EVENTS 108 | 109 | public delegate void PageChangedEventHandler(object sender, PageChangedEventArgs args); 110 | 111 | public static readonly RoutedEvent PreviewPageChangeEvent; 112 | public static readonly RoutedEvent PageChangedEvent; 113 | 114 | public event PageChangedEventHandler PreviewPageChange 115 | { 116 | add 117 | { 118 | AddHandler(PreviewPageChangeEvent, value); 119 | } 120 | remove 121 | { 122 | RemoveHandler(PreviewPageChangeEvent, value); 123 | } 124 | } 125 | 126 | public event PageChangedEventHandler PageChanged 127 | { 128 | add 129 | { 130 | AddHandler(PageChangedEvent, value); 131 | } 132 | remove 133 | { 134 | RemoveHandler(PageChangedEvent, value); 135 | } 136 | } 137 | 138 | #endregion 139 | 140 | #region CONTROL CONSTRUCTORS 141 | 142 | static PagingControl() 143 | { 144 | ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(ObservableCollection), typeof(PagingControl), new PropertyMetadata(new ObservableCollection())); 145 | PageProperty = DependencyProperty.Register("Page", typeof(int), typeof(PagingControl)); 146 | TotalPagesProperty = DependencyProperty.Register("TotalPages", typeof(int), typeof(PagingControl)); 147 | PageSizesProperty = DependencyProperty.Register("PageSizes", typeof(ObservableCollection), typeof(PagingControl), new PropertyMetadata(new ObservableCollection())); 148 | PageContractProperty = DependencyProperty.Register("PageContract", typeof(IPageControlContract), typeof(PagingControl)); 149 | FilterProperty = DependencyProperty.Register("Filter", typeof(object), typeof(PagingControl), new FrameworkPropertyMetadata(Target)); 150 | 151 | PreviewPageChangeEvent = EventManager.RegisterRoutedEvent("PreviewPageChange", RoutingStrategy.Bubble, typeof(PageChangedEventHandler), typeof(PagingControl)); 152 | PageChangedEvent = EventManager.RegisterRoutedEvent("PageChanged", RoutingStrategy.Bubble, typeof(PageChangedEventHandler), typeof(PagingControl)); 153 | } 154 | 155 | private static void Target(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) 156 | { 157 | var target = (PagingControl) dependencyObject; 158 | target.Navigate(PageChanges.Current); 159 | } 160 | 161 | public PagingControl() 162 | { 163 | this.Loaded += new RoutedEventHandler(PaggingControl_Loaded); 164 | } 165 | 166 | ~PagingControl() 167 | { 168 | UnregisterEvents(); 169 | } 170 | 171 | #endregion 172 | 173 | #region EVENTS 174 | 175 | void PaggingControl_Loaded(object sender, RoutedEventArgs e) 176 | { 177 | if (Template == null) 178 | { 179 | throw new Exception("Control template not assigned."); 180 | } 181 | 182 | if (PageContract == null) 183 | { 184 | throw new Exception("IPageControlContract not assigned."); 185 | } 186 | 187 | RegisterEvents(); 188 | SetDefaultValues(); 189 | BindProperties(); 190 | } 191 | 192 | void btnFirstPage_Click(object sender, RoutedEventArgs e) 193 | { 194 | Navigate(PageChanges.First); 195 | } 196 | 197 | void btnPreviousPage_Click(object sender, RoutedEventArgs e) 198 | { 199 | Navigate(PageChanges.Previous); 200 | } 201 | 202 | void btnNextPage_Click(object sender, RoutedEventArgs e) 203 | { 204 | Navigate(PageChanges.Next); 205 | } 206 | 207 | void btnLastPage_Click(object sender, RoutedEventArgs e) 208 | { 209 | Navigate(PageChanges.Last); 210 | } 211 | 212 | void txtPage_LostFocus(object sender, RoutedEventArgs e) 213 | { 214 | Navigate(PageChanges.Current); 215 | } 216 | 217 | void cmbPageSizes_SelectionChanged(object sender, SelectionChangedEventArgs e) 218 | { 219 | Navigate(PageChanges.Current); 220 | } 221 | 222 | #endregion 223 | 224 | #region INTERNAL METHODS 225 | 226 | public override void OnApplyTemplate() 227 | { 228 | btnFirstPage = this.Template.FindName("PART_FirstPageButton", this) as Button; 229 | btnPreviousPage = this.Template.FindName("PART_PreviousPageButton", this) as Button; 230 | txtPage = this.Template.FindName("PART_PageTextBox", this) as TextBox; 231 | btnNextPage = this.Template.FindName("PART_NextPageButton", this) as Button; 232 | btnLastPage = this.Template.FindName("PART_LastPageButton", this) as Button; 233 | cmbPageSizes = this.Template.FindName("PART_PageSizesCombobox", this) as ComboBox; 234 | 235 | if (btnFirstPage == null || 236 | btnPreviousPage == null || 237 | txtPage == null || 238 | btnNextPage == null || 239 | btnLastPage == null || 240 | cmbPageSizes == null) 241 | { 242 | throw new Exception("Invalid Control template."); 243 | } 244 | 245 | base.OnApplyTemplate(); 246 | } 247 | 248 | private void RegisterEvents() 249 | { 250 | btnFirstPage.Click += new RoutedEventHandler(btnFirstPage_Click); 251 | btnPreviousPage.Click += new RoutedEventHandler(btnPreviousPage_Click); 252 | btnNextPage.Click += new RoutedEventHandler(btnNextPage_Click); 253 | btnLastPage.Click += new RoutedEventHandler(btnLastPage_Click); 254 | 255 | txtPage.LostFocus += new RoutedEventHandler(txtPage_LostFocus); 256 | 257 | cmbPageSizes.SelectionChanged += new SelectionChangedEventHandler(cmbPageSizes_SelectionChanged); 258 | } 259 | 260 | private void UnregisterEvents() 261 | { 262 | btnFirstPage.Click -= btnFirstPage_Click; 263 | btnPreviousPage.Click -= btnPreviousPage_Click; 264 | btnNextPage.Click -= btnNextPage_Click; 265 | btnLastPage.Click -= btnLastPage_Click; 266 | 267 | txtPage.LostFocus -= txtPage_LostFocus; 268 | 269 | cmbPageSizes.SelectionChanged -= cmbPageSizes_SelectionChanged; 270 | } 271 | 272 | private void SetDefaultValues() 273 | { 274 | ItemsSource = new ObservableCollection(); 275 | 276 | cmbPageSizes.IsEditable = false; 277 | cmbPageSizes.SelectedIndex = 0; 278 | } 279 | 280 | private void BindProperties() 281 | { 282 | Binding propBinding; 283 | 284 | propBinding = new Binding("Page"); 285 | propBinding.RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent); 286 | propBinding.Mode = BindingMode.TwoWay; 287 | propBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 288 | txtPage.SetBinding(TextBox.TextProperty, propBinding); 289 | 290 | propBinding = new Binding("PageSizes"); 291 | propBinding.RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent); 292 | propBinding.Mode = BindingMode.TwoWay; 293 | propBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 294 | cmbPageSizes.SetBinding(ComboBox.ItemsSourceProperty, propBinding); 295 | } 296 | 297 | private void RaisePageChanged(int OldPage, int NewPage) 298 | { 299 | PageChangedEventArgs args = new PageChangedEventArgs(PageChangedEvent, OldPage, NewPage, TotalPages); 300 | RaiseEvent(args); 301 | } 302 | 303 | private void RaisePreviewPageChange(int OldPage, int NewPage) 304 | { 305 | PageChangedEventArgs args = new PageChangedEventArgs(PreviewPageChangeEvent, OldPage, NewPage, TotalPages); 306 | RaiseEvent(args); 307 | } 308 | 309 | private void Navigate(PageChanges change) 310 | { 311 | int totalRecords; 312 | int newPageSize; 313 | 314 | if (PageContract == null) 315 | { 316 | return; 317 | } 318 | 319 | totalRecords = PageContract.GetTotalCount(); 320 | newPageSize = (int)cmbPageSizes.SelectedItem; 321 | 322 | if (totalRecords == 0) 323 | { 324 | ItemsSource.Clear(); 325 | TotalPages = 1; 326 | Page = 1; 327 | } 328 | else 329 | { 330 | TotalPages = (totalRecords / newPageSize) + (int)((totalRecords % newPageSize == 0) ? 0 : 1); 331 | } 332 | 333 | int newPage = 1; 334 | 335 | switch (change) 336 | { 337 | case PageChanges.First: 338 | if (Page == 1) 339 | { 340 | return; 341 | } 342 | break; 343 | case PageChanges.Previous: 344 | newPage = (Page - 1 > TotalPages) ? TotalPages : (Page - 1 < 1) ? 1 : Page - 1; 345 | break; 346 | case PageChanges.Current: 347 | newPage = (Page > TotalPages) ? TotalPages : (Page < 1) ? 1 : Page; 348 | break; 349 | case PageChanges.Next: 350 | newPage = (Page + 1 > TotalPages) ? TotalPages : Page + 1; 351 | //(Page + 1) < 1 ? 1 : 352 | break; 353 | case PageChanges.Last: 354 | if (Page == TotalPages) 355 | { 356 | return; 357 | } 358 | newPage = TotalPages; 359 | break; 360 | default: 361 | break; 362 | } 363 | 364 | var startingIndex = (newPage - 1) * newPageSize; 365 | 366 | var oldPage = Page; 367 | RaisePreviewPageChange(Page, newPage); 368 | 369 | Page = newPage; 370 | ItemsSource.Clear(); 371 | 372 | ICollection fetchData = PageContract.GetRecordsBy(startingIndex, newPageSize, Filter); 373 | foreach (object row in fetchData) 374 | { 375 | ItemsSource.Add(row); 376 | } 377 | 378 | RaisePageChanged(oldPage, Page); 379 | } 380 | 381 | #endregion 382 | } 383 | } -------------------------------------------------------------------------------- /PagingControlProject/CustomSortingDataGrid.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject 2 | { 3 | using System; 4 | using System.ComponentModel; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Input; 8 | 9 | public class CustomSortingDataGrid : DataGrid 10 | { 11 | public CustomSortingDataGrid() 12 | { 13 | Sorting += OnSorting; 14 | } 15 | 16 | private void OnSorting(object sender, DataGridSortingEventArgs eventArgs) 17 | { 18 | eventArgs.Handled = true; 19 | if (SortCommand != null) 20 | { 21 | var column = eventArgs.Column; 22 | var sortDirection = GetNextSortDirection(column.SortDirection); 23 | column.SortDirection = sortDirection; 24 | SortCommand.Execute(new SortData(column.Header.ToString(), sortDirection)); 25 | } 26 | } 27 | 28 | public static readonly DependencyProperty SortCommandProperty = DependencyProperty.Register( 29 | "SortCommand", 30 | typeof(ICommand), 31 | typeof(CustomSortingDataGrid), 32 | new PropertyMetadata(default(ICommand))); 33 | 34 | public ICommand SortCommand 35 | { 36 | get { return (ICommand)GetValue(SortCommandProperty); } 37 | set { SetValue(SortCommandProperty, value); } 38 | } 39 | 40 | private ListSortDirection? GetNextSortDirection(ListSortDirection? sortDirection) 41 | { 42 | if (!sortDirection.HasValue) 43 | { 44 | return ListSortDirection.Ascending; 45 | } 46 | else 47 | { 48 | if (sortDirection == ListSortDirection.Ascending) 49 | { 50 | return ListSortDirection.Descending; 51 | } 52 | else 53 | { 54 | return null; 55 | } 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /PagingControlProject/Database/MyService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Dynamic; 5 | 6 | namespace PagingControlProject.Database 7 | { 8 | using System.ComponentModel; 9 | using Custom_Control; 10 | 11 | public class MyService : IPageControlContract 12 | { 13 | List studentList = new List(); 14 | 15 | public MyService() 16 | { 17 | Student studentObj; 18 | Random randomObj = new Random(); 19 | 20 | for (int i = 0; i < 1000; i++) 21 | { 22 | studentObj = new Student(); 23 | studentObj.FirstName = "First " + i; 24 | studentObj.MiddleName = "Middle " + i; 25 | studentObj.LastName = "Last " + i; 26 | studentObj.Age = (int)randomObj.Next(1, 100); 27 | 28 | studentList.Add(studentObj); 29 | } 30 | } 31 | 32 | #region IPageControlContract Members 33 | 34 | public int GetTotalCount() 35 | { 36 | return studentList.Count; 37 | } 38 | 39 | public ICollection GetRecordsBy(int startingIndex, int numberOfRecords, object sortData) 40 | { 41 | var filter = (SortData)sortData; 42 | 43 | if (filter?.ListSortDirection == null) 44 | { 45 | return studentList 46 | .Skip(startingIndex) 47 | .Take(numberOfRecords) 48 | .ToList(); 49 | } 50 | else 51 | { 52 | var sortDirectionStr = filter.ListSortDirection == ListSortDirection.Ascending ? "ASC" : "DESC"; 53 | // Ordenación aquí 54 | return studentList.OrderBy(filter.ColumnName + " " + sortDirectionStr) 55 | .Skip(startingIndex) 56 | .Take(numberOfRecords) 57 | .ToList(); 58 | } 59 | } 60 | 61 | #endregion 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /PagingControlProject/Database/Student.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject.Database 2 | { 3 | public class Student 4 | { 5 | public string FirstName { get; set; } 6 | public string MiddleName { get; set; } 7 | public string LastName { get; set; } 8 | public int Age { get; set; } 9 | 10 | public override string ToString() 11 | { 12 | return FirstName + "." + MiddleName + "." + LastName + " (" + Age + ")"; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /PagingControlProject/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject 2 | { 3 | using System.ComponentModel; 4 | using System.Runtime.CompilerServices; 5 | using Database; 6 | using GalaSoft.MvvmLight.Command; 7 | using Properties; 8 | 9 | public class MainViewModel : INotifyPropertyChanged 10 | { 11 | private object filter; 12 | 13 | public RelayCommand SortCommand => new RelayCommand(sort => Filter = sort); 14 | 15 | public MyService Service { get; set; } = new MyService(); 16 | 17 | public object Filter 18 | { 19 | get { return filter; } 20 | set 21 | { 22 | filter = value; 23 | OnPropertyChanged(); 24 | } 25 | } 26 | 27 | 28 | public event PropertyChangedEventHandler PropertyChanged; 29 | 30 | [NotifyPropertyChangedInvocator] 31 | protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 32 | { 33 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /PagingControlProject/MainWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Navigation; 13 | using System.Windows.Shapes; 14 | 15 | namespace PagingControlProject 16 | { 17 | /// 18 | /// Interaction logic for MainWindow.xaml 19 | /// 20 | public partial class MainWindow : Window 21 | { 22 | public MainWindow() 23 | { 24 | InitializeComponent(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /PagingControlProject/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 47 | 48 | 49 | 62 | 63 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 10 80 | 20 81 | 50 82 | 100 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /PagingControlProject/PagingControlProject.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {B2B01F0C-538B-4956-AB88-53B7258E2662} 9 | WinExe 10 | Properties 11 | PagingControlProject 12 | PagingControlProject 13 | v4.6 14 | 15 | 16 | 512 17 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 18 | 4 19 | 20 | 21 | x86 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | false 30 | default 31 | 32 | 33 | x86 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | false 41 | 42 | 43 | 44 | ..\packages\MvvmLightLibs.5.2.0.0\lib\net40\GalaSoft.MvvmLight.dll 45 | True 46 | 47 | 48 | ..\packages\MvvmLightLibs.5.2.0.0\lib\net40\GalaSoft.MvvmLight.Extras.dll 49 | True 50 | 51 | 52 | ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll 53 | True 54 | 55 | 56 | 57 | 58 | ..\packages\System.Linq.Dynamic.1.0.5\lib\net40\System.Linq.Dynamic.dll 59 | True 60 | 61 | 62 | ..\packages\MvvmLightLibs.5.2.0.0\lib\net40\System.Windows.Interactivity.dll 63 | True 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 4.0 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | MSBuild:Compile 80 | Designer 81 | 82 | 83 | 84 | MSBuild:Compile 85 | Designer 86 | 87 | 88 | App.xaml 89 | Code 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | MainWindow.xaml 100 | Code 101 | 102 | 103 | 104 | 105 | 106 | 107 | Code 108 | 109 | 110 | True 111 | True 112 | Resources.resx 113 | 114 | 115 | True 116 | Settings.settings 117 | True 118 | 119 | 120 | ResXFileCodeGenerator 121 | Resources.Designer.cs 122 | 123 | 124 | 125 | 126 | SettingsSingleFileGenerator 127 | Settings.Designer.cs 128 | 129 | 130 | 131 | 132 | 133 | 140 | -------------------------------------------------------------------------------- /PagingControlProject/Properties/Annotations.cs: -------------------------------------------------------------------------------- 1 |  2 | #pragma warning disable 1591 3 | // ReSharper disable UnusedMember.Global 4 | // ReSharper disable MemberCanBePrivate.Global 5 | // ReSharper disable UnusedAutoPropertyAccessor.Global 6 | // ReSharper disable IntroduceOptionalParameters.Global 7 | // ReSharper disable MemberCanBeProtected.Global 8 | // ReSharper disable InconsistentNaming 9 | 10 | namespace PagingControlProject.Properties 11 | { 12 | using System; 13 | 14 | /// 15 | /// Indicates that the value of the marked element could be null sometimes, 16 | /// so the check for null is necessary before its usage. 17 | /// 18 | /// 19 | /// [CanBeNull] object Test() => null; 20 | /// 21 | /// void UseTest() { 22 | /// var p = Test(); 23 | /// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' 24 | /// } 25 | /// 26 | [AttributeUsage( 27 | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | 28 | AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] 29 | public sealed class CanBeNullAttribute : Attribute { } 30 | 31 | /// 32 | /// Indicates that the value of the marked element could never be null. 33 | /// 34 | /// 35 | /// [NotNull] object Foo() { 36 | /// return null; // Warning: Possible 'null' assignment 37 | /// } 38 | /// 39 | [AttributeUsage( 40 | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | 41 | AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] 42 | public sealed class NotNullAttribute : Attribute { } 43 | 44 | /// 45 | /// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task 46 | /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property 47 | /// or of the Lazy.Value property can never be null. 48 | /// 49 | [AttributeUsage( 50 | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | 51 | AttributeTargets.Delegate | AttributeTargets.Field)] 52 | public sealed class ItemNotNullAttribute : Attribute { } 53 | 54 | /// 55 | /// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task 56 | /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property 57 | /// or of the Lazy.Value property can be null. 58 | /// 59 | [AttributeUsage( 60 | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | 61 | AttributeTargets.Delegate | AttributeTargets.Field)] 62 | public sealed class ItemCanBeNullAttribute : Attribute { } 63 | 64 | /// 65 | /// Indicates that the marked method builds string by format pattern and (optional) arguments. 66 | /// Parameter, which contains format string, should be given in constructor. The format string 67 | /// should be in -like form. 68 | /// 69 | /// 70 | /// [StringFormatMethod("message")] 71 | /// void ShowError(string message, params object[] args) { /* do something */ } 72 | /// 73 | /// void Foo() { 74 | /// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string 75 | /// } 76 | /// 77 | [AttributeUsage( 78 | AttributeTargets.Constructor | AttributeTargets.Method | 79 | AttributeTargets.Property | AttributeTargets.Delegate)] 80 | public sealed class StringFormatMethodAttribute : Attribute 81 | { 82 | /// 83 | /// Specifies which parameter of an annotated method should be treated as format-string 84 | /// 85 | public StringFormatMethodAttribute(string formatParameterName) 86 | { 87 | FormatParameterName = formatParameterName; 88 | } 89 | 90 | public string FormatParameterName { get; private set; } 91 | } 92 | 93 | /// 94 | /// For a parameter that is expected to be one of the limited set of values. 95 | /// Specify fields of which type should be used as values for this parameter. 96 | /// 97 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] 98 | public sealed class ValueProviderAttribute : Attribute 99 | { 100 | public ValueProviderAttribute(string name) 101 | { 102 | Name = name; 103 | } 104 | 105 | [NotNull] public string Name { get; private set; } 106 | } 107 | 108 | /// 109 | /// Indicates that the function argument should be string literal and match one 110 | /// of the parameters of the caller function. For example, ReSharper annotates 111 | /// the parameter of . 112 | /// 113 | /// 114 | /// void Foo(string param) { 115 | /// if (param == null) 116 | /// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol 117 | /// } 118 | /// 119 | [AttributeUsage(AttributeTargets.Parameter)] 120 | public sealed class InvokerParameterNameAttribute : Attribute { } 121 | 122 | /// 123 | /// Indicates that the method is contained in a type that implements 124 | /// System.ComponentModel.INotifyPropertyChanged interface and this method 125 | /// is used to notify that some property value changed. 126 | /// 127 | /// 128 | /// The method should be non-static and conform to one of the supported signatures: 129 | /// 130 | /// NotifyChanged(string) 131 | /// NotifyChanged(params string[]) 132 | /// NotifyChanged{T}(Expression{Func{T}}) 133 | /// NotifyChanged{T,U}(Expression{Func{T,U}}) 134 | /// SetProperty{T}(ref T, T, string) 135 | /// 136 | /// 137 | /// 138 | /// public class Foo : INotifyPropertyChanged { 139 | /// public event PropertyChangedEventHandler PropertyChanged; 140 | /// 141 | /// [NotifyPropertyChangedInvocator] 142 | /// protected virtual void NotifyChanged(string propertyName) { ... } 143 | /// 144 | /// string _name; 145 | /// 146 | /// public string Name { 147 | /// get { return _name; } 148 | /// set { _name = value; NotifyChanged("LastName"); /* Warning */ } 149 | /// } 150 | /// } 151 | /// 152 | /// Examples of generated notifications: 153 | /// 154 | /// NotifyChanged("Property") 155 | /// NotifyChanged(() => Property) 156 | /// NotifyChanged((VM x) => x.Property) 157 | /// SetProperty(ref myField, value, "Property") 158 | /// 159 | /// 160 | [AttributeUsage(AttributeTargets.Method)] 161 | public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute 162 | { 163 | public NotifyPropertyChangedInvocatorAttribute() { } 164 | public NotifyPropertyChangedInvocatorAttribute(string parameterName) 165 | { 166 | ParameterName = parameterName; 167 | } 168 | 169 | public string ParameterName { get; private set; } 170 | } 171 | 172 | /// 173 | /// Describes dependency between method input and output. 174 | /// 175 | /// 176 | ///

Function Definition Table syntax:

177 | /// 178 | /// FDT ::= FDTRow [;FDTRow]* 179 | /// FDTRow ::= Input => Output | Output <= Input 180 | /// Input ::= ParameterName: Value [, Input]* 181 | /// Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value} 182 | /// Value ::= true | false | null | notnull | canbenull 183 | /// 184 | /// If method has single input parameter, it's name could be omitted.
185 | /// Using halt (or void/nothing, which is the same) 186 | /// for method output means that the methos doesn't return normally.
187 | /// canbenull annotation is only applicable for output parameters.
188 | /// You can use multiple [ContractAnnotation] for each FDT row, 189 | /// or use single attribute with rows separated by semicolon.
190 | ///
191 | /// 192 | /// 193 | /// [ContractAnnotation("=> halt")] 194 | /// public void TerminationMethod() 195 | /// 196 | /// 197 | /// [ContractAnnotation("halt <= condition: false")] 198 | /// public void Assert(bool condition, string text) // regular assertion method 199 | /// 200 | /// 201 | /// [ContractAnnotation("s:null => true")] 202 | /// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty() 203 | /// 204 | /// 205 | /// // A method that returns null if the parameter is null, 206 | /// // and not null if the parameter is not null 207 | /// [ContractAnnotation("null => null; notnull => notnull")] 208 | /// public object Transform(object data) 209 | /// 210 | /// 211 | /// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] 212 | /// public bool TryParse(string s, out Person result) 213 | /// 214 | /// 215 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 216 | public sealed class ContractAnnotationAttribute : Attribute 217 | { 218 | public ContractAnnotationAttribute([NotNull] string contract) 219 | : this(contract, false) { } 220 | 221 | public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates) 222 | { 223 | Contract = contract; 224 | ForceFullStates = forceFullStates; 225 | } 226 | 227 | public string Contract { get; private set; } 228 | public bool ForceFullStates { get; private set; } 229 | } 230 | 231 | /// 232 | /// Indicates that marked element should be localized or not. 233 | /// 234 | /// 235 | /// [LocalizationRequiredAttribute(true)] 236 | /// class Foo { 237 | /// string str = "my string"; // Warning: Localizable string 238 | /// } 239 | /// 240 | [AttributeUsage(AttributeTargets.All)] 241 | public sealed class LocalizationRequiredAttribute : Attribute 242 | { 243 | public LocalizationRequiredAttribute() : this(true) { } 244 | public LocalizationRequiredAttribute(bool required) 245 | { 246 | Required = required; 247 | } 248 | 249 | public bool Required { get; private set; } 250 | } 251 | 252 | /// 253 | /// Indicates that the value of the marked type (or its derivatives) 254 | /// cannot be compared using '==' or '!=' operators and Equals() 255 | /// should be used instead. However, using '==' or '!=' for comparison 256 | /// with null is always permitted. 257 | /// 258 | /// 259 | /// [CannotApplyEqualityOperator] 260 | /// class NoEquality { } 261 | /// 262 | /// class UsesNoEquality { 263 | /// void Test() { 264 | /// var ca1 = new NoEquality(); 265 | /// var ca2 = new NoEquality(); 266 | /// if (ca1 != null) { // OK 267 | /// bool condition = ca1 == ca2; // Warning 268 | /// } 269 | /// } 270 | /// } 271 | /// 272 | [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)] 273 | public sealed class CannotApplyEqualityOperatorAttribute : Attribute { } 274 | 275 | /// 276 | /// When applied to a target attribute, specifies a requirement for any type marked 277 | /// with the target attribute to implement or inherit specific type or types. 278 | /// 279 | /// 280 | /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement 281 | /// class ComponentAttribute : Attribute { } 282 | /// 283 | /// [Component] // ComponentAttribute requires implementing IComponent interface 284 | /// class MyComponent : IComponent { } 285 | /// 286 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 287 | [BaseTypeRequired(typeof(Attribute))] 288 | public sealed class BaseTypeRequiredAttribute : Attribute 289 | { 290 | public BaseTypeRequiredAttribute([NotNull] Type baseType) 291 | { 292 | BaseType = baseType; 293 | } 294 | 295 | [NotNull] public Type BaseType { get; private set; } 296 | } 297 | 298 | /// 299 | /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), 300 | /// so this symbol will not be marked as unused (as well as by other usage inspections). 301 | /// 302 | [AttributeUsage(AttributeTargets.All)] 303 | public sealed class UsedImplicitlyAttribute : Attribute 304 | { 305 | public UsedImplicitlyAttribute() 306 | : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } 307 | 308 | public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) 309 | : this(useKindFlags, ImplicitUseTargetFlags.Default) { } 310 | 311 | public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) 312 | : this(ImplicitUseKindFlags.Default, targetFlags) { } 313 | 314 | public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) 315 | { 316 | UseKindFlags = useKindFlags; 317 | TargetFlags = targetFlags; 318 | } 319 | 320 | public ImplicitUseKindFlags UseKindFlags { get; private set; } 321 | public ImplicitUseTargetFlags TargetFlags { get; private set; } 322 | } 323 | 324 | /// 325 | /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes 326 | /// as unused (as well as by other usage inspections) 327 | /// 328 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter)] 329 | public sealed class MeansImplicitUseAttribute : Attribute 330 | { 331 | public MeansImplicitUseAttribute() 332 | : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } 333 | 334 | public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) 335 | : this(useKindFlags, ImplicitUseTargetFlags.Default) { } 336 | 337 | public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) 338 | : this(ImplicitUseKindFlags.Default, targetFlags) { } 339 | 340 | public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) 341 | { 342 | UseKindFlags = useKindFlags; 343 | TargetFlags = targetFlags; 344 | } 345 | 346 | [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; } 347 | [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; } 348 | } 349 | 350 | [Flags] 351 | public enum ImplicitUseKindFlags 352 | { 353 | Default = Access | Assign | InstantiatedWithFixedConstructorSignature, 354 | /// Only entity marked with attribute considered used. 355 | Access = 1, 356 | /// Indicates implicit assignment to a member. 357 | Assign = 2, 358 | /// 359 | /// Indicates implicit instantiation of a type with fixed constructor signature. 360 | /// That means any unused constructor parameters won't be reported as such. 361 | /// 362 | InstantiatedWithFixedConstructorSignature = 4, 363 | /// Indicates implicit instantiation of a type. 364 | InstantiatedNoFixedConstructorSignature = 8, 365 | } 366 | 367 | /// 368 | /// Specify what is considered used implicitly when marked 369 | /// with or . 370 | /// 371 | [Flags] 372 | public enum ImplicitUseTargetFlags 373 | { 374 | Default = Itself, 375 | Itself = 1, 376 | /// Members of entity marked with attribute are considered used. 377 | Members = 2, 378 | /// Entity marked with attribute and all its members considered used. 379 | WithMembers = Itself | Members 380 | } 381 | 382 | /// 383 | /// This attribute is intended to mark publicly available API 384 | /// which should not be removed and so is treated as used. 385 | /// 386 | [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)] 387 | public sealed class PublicAPIAttribute : Attribute 388 | { 389 | public PublicAPIAttribute() { } 390 | public PublicAPIAttribute([NotNull] string comment) 391 | { 392 | Comment = comment; 393 | } 394 | 395 | public string Comment { get; private set; } 396 | } 397 | 398 | /// 399 | /// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. 400 | /// If the parameter is a delegate, indicates that delegate is executed while the method is executed. 401 | /// If the parameter is an enumerable, indicates that it is enumerated while the method is executed. 402 | /// 403 | [AttributeUsage(AttributeTargets.Parameter)] 404 | public sealed class InstantHandleAttribute : Attribute { } 405 | 406 | /// 407 | /// Indicates that a method does not make any observable state changes. 408 | /// The same as System.Diagnostics.Contracts.PureAttribute. 409 | /// 410 | /// 411 | /// [Pure] int Multiply(int x, int y) => x * y; 412 | /// 413 | /// void M() { 414 | /// Multiply(123, 42); // Waring: Return value of pure method is not used 415 | /// } 416 | /// 417 | [AttributeUsage(AttributeTargets.Method)] 418 | public sealed class PureAttribute : Attribute { } 419 | 420 | /// 421 | /// Indicates that the return value of method invocation must be used. 422 | /// 423 | [AttributeUsage(AttributeTargets.Method)] 424 | public sealed class MustUseReturnValueAttribute : Attribute 425 | { 426 | public MustUseReturnValueAttribute() { } 427 | public MustUseReturnValueAttribute([NotNull] string justification) 428 | { 429 | Justification = justification; 430 | } 431 | 432 | public string Justification { get; private set; } 433 | } 434 | 435 | /// 436 | /// Indicates the type member or parameter of some type, that should be used instead of all other ways 437 | /// to get the value that type. This annotation is useful when you have some "context" value evaluated 438 | /// and stored somewhere, meaning that all other ways to get this value must be consolidated with existing one. 439 | /// 440 | /// 441 | /// class Foo { 442 | /// [ProvidesContext] IBarService _barService = ...; 443 | /// 444 | /// void ProcessNode(INode node) { 445 | /// DoSomething(node, node.GetGlobalServices().Bar); 446 | /// // ^ Warning: use value of '_barService' field 447 | /// } 448 | /// } 449 | /// 450 | [AttributeUsage( 451 | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter | 452 | AttributeTargets.Method)] 453 | public sealed class ProvidesContextAttribute : Attribute { } 454 | 455 | /// 456 | /// Indicates that a parameter is a path to a file or a folder within a web project. 457 | /// Path can be relative or absolute, starting from web root (~). 458 | /// 459 | [AttributeUsage(AttributeTargets.Parameter)] 460 | public sealed class PathReferenceAttribute : Attribute 461 | { 462 | public PathReferenceAttribute() { } 463 | public PathReferenceAttribute([PathReference] string basePath) 464 | { 465 | BasePath = basePath; 466 | } 467 | 468 | public string BasePath { get; private set; } 469 | } 470 | 471 | /// 472 | /// An extension method marked with this attribute is processed by ReSharper code completion 473 | /// as a 'Source Template'. When extension method is completed over some expression, it's source code 474 | /// is automatically expanded like a template at call site. 475 | /// 476 | /// 477 | /// Template method body can contain valid source code and/or special comments starting with '$'. 478 | /// Text inside these comments is added as source code when the template is applied. Template parameters 479 | /// can be used either as additional method parameters or as identifiers wrapped in two '$' signs. 480 | /// Use the attribute to specify macros for parameters. 481 | /// 482 | /// 483 | /// In this example, the 'forEach' method is a source template available over all values 484 | /// of enumerable types, producing ordinary C# 'foreach' statement and placing caret inside block: 485 | /// 486 | /// [SourceTemplate] 487 | /// public static void forEach<T>(this IEnumerable<T> xs) { 488 | /// foreach (var x in xs) { 489 | /// //$ $END$ 490 | /// } 491 | /// } 492 | /// 493 | /// 494 | [AttributeUsage(AttributeTargets.Method)] 495 | public sealed class SourceTemplateAttribute : Attribute { } 496 | 497 | /// 498 | /// Allows specifying a macro for a parameter of a source template. 499 | /// 500 | /// 501 | /// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression 502 | /// is defined in the property. When applied on a method, the target 503 | /// template parameter is defined in the property. To apply the macro silently 504 | /// for the parameter, set the property value = -1. 505 | /// 506 | /// 507 | /// Applying the attribute on a source template method: 508 | /// 509 | /// [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")] 510 | /// public static void forEach<T>(this IEnumerable<T> collection) { 511 | /// foreach (var item in collection) { 512 | /// //$ $END$ 513 | /// } 514 | /// } 515 | /// 516 | /// Applying the attribute on a template method parameter: 517 | /// 518 | /// [SourceTemplate] 519 | /// public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) { 520 | /// /*$ var $x$Id = "$newguid$" + x.ToString(); 521 | /// x.DoSomething($x$Id); */ 522 | /// } 523 | /// 524 | /// 525 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = true)] 526 | public sealed class MacroAttribute : Attribute 527 | { 528 | /// 529 | /// Allows specifying a macro that will be executed for a source template 530 | /// parameter when the template is expanded. 531 | /// 532 | public string Expression { get; set; } 533 | 534 | /// 535 | /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. 536 | /// 537 | /// 538 | /// If the target parameter is used several times in the template, only one occurrence becomes editable; 539 | /// other occurrences are changed synchronously. To specify the zero-based index of the editable occurrence, 540 | /// use values >= 0. To make the parameter non-editable when the template is expanded, use -1. 541 | /// > 542 | public int Editable { get; set; } 543 | 544 | /// 545 | /// Identifies the target parameter of a source template if the 546 | /// is applied on a template method. 547 | /// 548 | public string Target { get; set; } 549 | } 550 | 551 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 552 | public sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute 553 | { 554 | public AspMvcAreaMasterLocationFormatAttribute(string format) 555 | { 556 | Format = format; 557 | } 558 | 559 | public string Format { get; private set; } 560 | } 561 | 562 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 563 | public sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute 564 | { 565 | public AspMvcAreaPartialViewLocationFormatAttribute(string format) 566 | { 567 | Format = format; 568 | } 569 | 570 | public string Format { get; private set; } 571 | } 572 | 573 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 574 | public sealed class AspMvcAreaViewLocationFormatAttribute : Attribute 575 | { 576 | public AspMvcAreaViewLocationFormatAttribute(string format) 577 | { 578 | Format = format; 579 | } 580 | 581 | public string Format { get; private set; } 582 | } 583 | 584 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 585 | public sealed class AspMvcMasterLocationFormatAttribute : Attribute 586 | { 587 | public AspMvcMasterLocationFormatAttribute(string format) 588 | { 589 | Format = format; 590 | } 591 | 592 | public string Format { get; private set; } 593 | } 594 | 595 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 596 | public sealed class AspMvcPartialViewLocationFormatAttribute : Attribute 597 | { 598 | public AspMvcPartialViewLocationFormatAttribute(string format) 599 | { 600 | Format = format; 601 | } 602 | 603 | public string Format { get; private set; } 604 | } 605 | 606 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 607 | public sealed class AspMvcViewLocationFormatAttribute : Attribute 608 | { 609 | public AspMvcViewLocationFormatAttribute(string format) 610 | { 611 | Format = format; 612 | } 613 | 614 | public string Format { get; private set; } 615 | } 616 | 617 | /// 618 | /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter 619 | /// is an MVC action. If applied to a method, the MVC action name is calculated 620 | /// implicitly from the context. Use this attribute for custom wrappers similar to 621 | /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). 622 | /// 623 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] 624 | public sealed class AspMvcActionAttribute : Attribute 625 | { 626 | public AspMvcActionAttribute() { } 627 | public AspMvcActionAttribute(string anonymousProperty) 628 | { 629 | AnonymousProperty = anonymousProperty; 630 | } 631 | 632 | public string AnonymousProperty { get; private set; } 633 | } 634 | 635 | /// 636 | /// ASP.NET MVC attribute. Indicates that a parameter is an MVC area. 637 | /// Use this attribute for custom wrappers similar to 638 | /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). 639 | /// 640 | [AttributeUsage(AttributeTargets.Parameter)] 641 | public sealed class AspMvcAreaAttribute : Attribute 642 | { 643 | public AspMvcAreaAttribute() { } 644 | public AspMvcAreaAttribute(string anonymousProperty) 645 | { 646 | AnonymousProperty = anonymousProperty; 647 | } 648 | 649 | public string AnonymousProperty { get; private set; } 650 | } 651 | 652 | /// 653 | /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is 654 | /// an MVC controller. If applied to a method, the MVC controller name is calculated 655 | /// implicitly from the context. Use this attribute for custom wrappers similar to 656 | /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String). 657 | /// 658 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] 659 | public sealed class AspMvcControllerAttribute : Attribute 660 | { 661 | public AspMvcControllerAttribute() { } 662 | public AspMvcControllerAttribute(string anonymousProperty) 663 | { 664 | AnonymousProperty = anonymousProperty; 665 | } 666 | 667 | public string AnonymousProperty { get; private set; } 668 | } 669 | 670 | /// 671 | /// ASP.NET MVC attribute. Indicates that a parameter is an MVC Master. Use this attribute 672 | /// for custom wrappers similar to System.Web.Mvc.Controller.View(String, String). 673 | /// 674 | [AttributeUsage(AttributeTargets.Parameter)] 675 | public sealed class AspMvcMasterAttribute : Attribute { } 676 | 677 | /// 678 | /// ASP.NET MVC attribute. Indicates that a parameter is an MVC model type. Use this attribute 679 | /// for custom wrappers similar to System.Web.Mvc.Controller.View(String, Object). 680 | /// 681 | [AttributeUsage(AttributeTargets.Parameter)] 682 | public sealed class AspMvcModelTypeAttribute : Attribute { } 683 | 684 | /// 685 | /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC 686 | /// partial view. If applied to a method, the MVC partial view name is calculated implicitly 687 | /// from the context. Use this attribute for custom wrappers similar to 688 | /// System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String). 689 | /// 690 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] 691 | public sealed class AspMvcPartialViewAttribute : Attribute { } 692 | 693 | /// 694 | /// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method. 695 | /// 696 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 697 | public sealed class AspMvcSuppressViewErrorAttribute : Attribute { } 698 | 699 | /// 700 | /// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template. 701 | /// Use this attribute for custom wrappers similar to 702 | /// System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String). 703 | /// 704 | [AttributeUsage(AttributeTargets.Parameter)] 705 | public sealed class AspMvcDisplayTemplateAttribute : Attribute { } 706 | 707 | /// 708 | /// ASP.NET MVC attribute. Indicates that a parameter is an MVC editor template. 709 | /// Use this attribute for custom wrappers similar to 710 | /// System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String). 711 | /// 712 | [AttributeUsage(AttributeTargets.Parameter)] 713 | public sealed class AspMvcEditorTemplateAttribute : Attribute { } 714 | 715 | /// 716 | /// ASP.NET MVC attribute. Indicates that a parameter is an MVC template. 717 | /// Use this attribute for custom wrappers similar to 718 | /// System.ComponentModel.DataAnnotations.UIHintAttribute(System.String). 719 | /// 720 | [AttributeUsage(AttributeTargets.Parameter)] 721 | public sealed class AspMvcTemplateAttribute : Attribute { } 722 | 723 | /// 724 | /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter 725 | /// is an MVC view component. If applied to a method, the MVC view name is calculated implicitly 726 | /// from the context. Use this attribute for custom wrappers similar to 727 | /// System.Web.Mvc.Controller.View(Object). 728 | /// 729 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] 730 | public sealed class AspMvcViewAttribute : Attribute { } 731 | 732 | /// 733 | /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter 734 | /// is an MVC view component name. 735 | /// 736 | [AttributeUsage(AttributeTargets.Parameter)] 737 | public sealed class AspMvcViewComponentAttribute : Attribute { } 738 | 739 | /// 740 | /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter 741 | /// is an MVC view component view. If applied to a method, the MVC view component view name is default. 742 | /// 743 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] 744 | public sealed class AspMvcViewComponentViewAttribute : Attribute { } 745 | 746 | /// 747 | /// ASP.NET MVC attribute. When applied to a parameter of an attribute, 748 | /// indicates that this parameter is an MVC action name. 749 | /// 750 | /// 751 | /// [ActionName("Foo")] 752 | /// public ActionResult Login(string returnUrl) { 753 | /// ViewBag.ReturnUrl = Url.Action("Foo"); // OK 754 | /// return RedirectToAction("Bar"); // Error: Cannot resolve action 755 | /// } 756 | /// 757 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)] 758 | public sealed class AspMvcActionSelectorAttribute : Attribute { } 759 | 760 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] 761 | public sealed class HtmlElementAttributesAttribute : Attribute 762 | { 763 | public HtmlElementAttributesAttribute() { } 764 | public HtmlElementAttributesAttribute(string name) 765 | { 766 | Name = name; 767 | } 768 | 769 | public string Name { get; private set; } 770 | } 771 | 772 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] 773 | public sealed class HtmlAttributeValueAttribute : Attribute 774 | { 775 | public HtmlAttributeValueAttribute([NotNull] string name) 776 | { 777 | Name = name; 778 | } 779 | 780 | [NotNull] public string Name { get; private set; } 781 | } 782 | 783 | /// 784 | /// Razor attribute. Indicates that a parameter or a method is a Razor section. 785 | /// Use this attribute for custom wrappers similar to 786 | /// System.Web.WebPages.WebPageBase.RenderSection(String). 787 | /// 788 | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] 789 | public sealed class RazorSectionAttribute : Attribute { } 790 | 791 | /// 792 | /// Indicates how method, constructor invocation or property access 793 | /// over collection type affects content of the collection. 794 | /// 795 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)] 796 | public sealed class CollectionAccessAttribute : Attribute 797 | { 798 | public CollectionAccessAttribute(CollectionAccessType collectionAccessType) 799 | { 800 | CollectionAccessType = collectionAccessType; 801 | } 802 | 803 | public CollectionAccessType CollectionAccessType { get; private set; } 804 | } 805 | 806 | [Flags] 807 | public enum CollectionAccessType 808 | { 809 | /// Method does not use or modify content of the collection. 810 | None = 0, 811 | /// Method only reads content of the collection but does not modify it. 812 | Read = 1, 813 | /// Method can change content of the collection but does not add new elements. 814 | ModifyExistingContent = 2, 815 | /// Method can add new elements to the collection. 816 | UpdatedContent = ModifyExistingContent | 4 817 | } 818 | 819 | /// 820 | /// Indicates that the marked method is assertion method, i.e. it halts control flow if 821 | /// one of the conditions is satisfied. To set the condition, mark one of the parameters with 822 | /// attribute. 823 | /// 824 | [AttributeUsage(AttributeTargets.Method)] 825 | public sealed class AssertionMethodAttribute : Attribute { } 826 | 827 | /// 828 | /// Indicates the condition parameter of the assertion method. The method itself should be 829 | /// marked by attribute. The mandatory argument of 830 | /// the attribute is the assertion type. 831 | /// 832 | [AttributeUsage(AttributeTargets.Parameter)] 833 | public sealed class AssertionConditionAttribute : Attribute 834 | { 835 | public AssertionConditionAttribute(AssertionConditionType conditionType) 836 | { 837 | ConditionType = conditionType; 838 | } 839 | 840 | public AssertionConditionType ConditionType { get; private set; } 841 | } 842 | 843 | /// 844 | /// Specifies assertion type. If the assertion method argument satisfies the condition, 845 | /// then the execution continues. Otherwise, execution is assumed to be halted. 846 | /// 847 | public enum AssertionConditionType 848 | { 849 | /// Marked parameter should be evaluated to true. 850 | IS_TRUE = 0, 851 | /// Marked parameter should be evaluated to false. 852 | IS_FALSE = 1, 853 | /// Marked parameter should be evaluated to null value. 854 | IS_NULL = 2, 855 | /// Marked parameter should be evaluated to not null value. 856 | IS_NOT_NULL = 3, 857 | } 858 | 859 | /// 860 | /// Indicates that the marked method unconditionally terminates control flow execution. 861 | /// For example, it could unconditionally throw exception. 862 | /// 863 | [Obsolete("Use [ContractAnnotation('=> halt')] instead")] 864 | [AttributeUsage(AttributeTargets.Method)] 865 | public sealed class TerminatesProgramAttribute : Attribute { } 866 | 867 | /// 868 | /// Indicates that method is pure LINQ method, with postponed enumeration (like Enumerable.Select, 869 | /// .Where). This annotation allows inference of [InstantHandle] annotation for parameters 870 | /// of delegate type by analyzing LINQ method chains. 871 | /// 872 | [AttributeUsage(AttributeTargets.Method)] 873 | public sealed class LinqTunnelAttribute : Attribute { } 874 | 875 | /// 876 | /// Indicates that IEnumerable, passed as parameter, is not enumerated. 877 | /// 878 | [AttributeUsage(AttributeTargets.Parameter)] 879 | public sealed class NoEnumerationAttribute : Attribute { } 880 | 881 | /// 882 | /// Indicates that parameter is regular expression pattern. 883 | /// 884 | [AttributeUsage(AttributeTargets.Parameter)] 885 | public sealed class RegexPatternAttribute : Attribute { } 886 | 887 | /// 888 | /// XAML attribute. Indicates the type that has ItemsSource property and should be treated 889 | /// as ItemsControl-derived type, to enable inner items DataContext type resolve. 890 | /// 891 | [AttributeUsage(AttributeTargets.Class)] 892 | public sealed class XamlItemsControlAttribute : Attribute { } 893 | 894 | /// 895 | /// XAML attribute. Indicates the property of some BindingBase-derived type, that 896 | /// is used to bind some item of ItemsControl-derived type. This annotation will 897 | /// enable the DataContext type resolve for XAML bindings for such properties. 898 | /// 899 | /// 900 | /// Property should have the tree ancestor of the ItemsControl type or 901 | /// marked with the attribute. 902 | /// 903 | [AttributeUsage(AttributeTargets.Property)] 904 | public sealed class XamlItemBindingOfItemsControlAttribute : Attribute { } 905 | 906 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 907 | public sealed class AspChildControlTypeAttribute : Attribute 908 | { 909 | public AspChildControlTypeAttribute(string tagName, Type controlType) 910 | { 911 | TagName = tagName; 912 | ControlType = controlType; 913 | } 914 | 915 | public string TagName { get; private set; } 916 | public Type ControlType { get; private set; } 917 | } 918 | 919 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] 920 | public sealed class AspDataFieldAttribute : Attribute { } 921 | 922 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] 923 | public sealed class AspDataFieldsAttribute : Attribute { } 924 | 925 | [AttributeUsage(AttributeTargets.Property)] 926 | public sealed class AspMethodPropertyAttribute : Attribute { } 927 | 928 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 929 | public sealed class AspRequiredAttributeAttribute : Attribute 930 | { 931 | public AspRequiredAttributeAttribute([NotNull] string attribute) 932 | { 933 | Attribute = attribute; 934 | } 935 | 936 | public string Attribute { get; private set; } 937 | } 938 | 939 | [AttributeUsage(AttributeTargets.Property)] 940 | public sealed class AspTypePropertyAttribute : Attribute 941 | { 942 | public bool CreateConstructorReferences { get; private set; } 943 | 944 | public AspTypePropertyAttribute(bool createConstructorReferences) 945 | { 946 | CreateConstructorReferences = createConstructorReferences; 947 | } 948 | } 949 | 950 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 951 | public sealed class RazorImportNamespaceAttribute : Attribute 952 | { 953 | public RazorImportNamespaceAttribute(string name) 954 | { 955 | Name = name; 956 | } 957 | 958 | public string Name { get; private set; } 959 | } 960 | 961 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 962 | public sealed class RazorInjectionAttribute : Attribute 963 | { 964 | public RazorInjectionAttribute(string type, string fieldName) 965 | { 966 | Type = type; 967 | FieldName = fieldName; 968 | } 969 | 970 | public string Type { get; private set; } 971 | public string FieldName { get; private set; } 972 | } 973 | 974 | [AttributeUsage(AttributeTargets.Method)] 975 | public sealed class RazorHelperCommonAttribute : Attribute { } 976 | 977 | [AttributeUsage(AttributeTargets.Property)] 978 | public sealed class RazorLayoutAttribute : Attribute { } 979 | 980 | [AttributeUsage(AttributeTargets.Method)] 981 | public sealed class RazorWriteLiteralMethodAttribute : Attribute { } 982 | 983 | [AttributeUsage(AttributeTargets.Method)] 984 | public sealed class RazorWriteMethodAttribute : Attribute { } 985 | 986 | [AttributeUsage(AttributeTargets.Parameter)] 987 | public sealed class RazorWriteMethodParameterAttribute : Attribute { } 988 | 989 | /// 990 | /// Prevents the Member Reordering feature from tossing members of the marked class. 991 | /// 992 | /// 993 | /// The attribute must be mentioned in your member reordering patterns 994 | /// 995 | [AttributeUsage(AttributeTargets.All)] 996 | public sealed class NoReorder : Attribute { } 997 | } -------------------------------------------------------------------------------- /PagingControlProject/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("PaggingControlProject")] 11 | [assembly: AssemblyDescription("Pagging Control")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Nilay Joshi")] 14 | [assembly: AssemblyProduct("PaggingControlProject")] 15 | [assembly: AssemblyCopyright("Nilay Joshi")] 16 | [assembly: AssemblyTrademark("Nilay Joshi")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /PagingControlProject/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace PagingControlProject.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PagingControlProject.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /PagingControlProject/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /PagingControlProject/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace PagingControlProject.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PagingControlProject/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /PagingControlProject/SortData.cs: -------------------------------------------------------------------------------- 1 | namespace PagingControlProject 2 | { 3 | using System.ComponentModel; 4 | 5 | public class SortData 6 | { 7 | public SortData(string columnName, ListSortDirection? listSortDirection) 8 | { 9 | ColumnName = columnName; 10 | ListSortDirection = listSortDirection; 11 | } 12 | 13 | public string ColumnName { get; set; } 14 | public ListSortDirection? ListSortDirection { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /PagingControlProject/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /PagingControlProject/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XAML Paging & Sorting Control 2 | A paging control based on http://www.codeproject.com/Articles/350447/WPF-Paging-in-DataGrid-ListBox by Nilay [M Joshi](http://www.codeproject.com/script/Membership/View.aspx?mid=5277189) 3 | 4 | With support for Sorting! 5 | 6 | Ready to use with MVVM ;) 7 | --------------------------------------------------------------------------------