Share the idea of implementing a paging control and the idea of a paging Control

Source: Internet
Author: User

Share the idea of implementing a paging control and the idea of a paging Control

Although the paging control is full, it is impossible to find the WinForm program, so it creates a wheel. At first, I thought this was a simple task. I started the project without thinking too much. In fact, I didn't spend much time writing the first version, and I wanted to implement all the functions. I thought everything would be fine ...... The widget looks like this:

One of the rules of Software Development: if one thing is particularly smooth, there will be some pitfalls waiting for you! The pit size is directly proportional to the smoothness.

Naturally, when the business module was restructured a few days ago, it fell into a paging bin. After switching the number of lines per page, data is always loaded twice. The cause of the problem is also very simple. The data loading event is triggered twice. It seems that there is a big problem with the business logic here! Looking at the logic elsewhere, there is also a problem !!! It was just a weekend, so we started a comprehensive discussion. How can we sort it out? Or starting from the demand.

Requirement 1: You can set the number of lines displayed on each page.

After modifying the number of lines displayed on each page, you need to feed back the ViewModel to reload the data based on the new number of lines displayed. Wait! Sometimes it seems that you do not need to refresh the data, right? For example, 20 rows are displayed on each page, but there are only 10 rows in total. In this case, switch to 100 rows on each page, and only 10 rows can be displayed. In this case, you do not need to reload the data. This saves your time. At this time, data is not refreshed, which not only improves efficiency, but also improves user experience.

Requirement 2: You can switch the page number, Home Page | Previous Page | next page | last page | to [x]

After switching the page number, you need to feed back the ViewModel to reload the data based on the new page number. This is the easiest way to go straight! Well, when the current page is the home page, the home page | previous page buttons should be blocked. Similarly, when the current page is the last page, the next page | last page buttons should also be blocked. If there is only one page, these five buttons should not be available.

There are two basic requirements for paging, but I still need some special requirements. These requirements seem simple, for example:

1. After adding an object, put the object at the end of the list and select it automatically.

2. delete a selected object and remove it from the list. If the object is not the last object in the list, the next object is automatically selected. Otherwise, the previous object is automatically selected. (if the object is a unique object on the current page, it means that the previous object is located on the previous page, to automatically jump to the previous page ).

3. Switch the number of lines displayed on each page and select the current object. You need to recalculate the current page ...... Well, this is where the big hole is. Do you need to reload the data? It seems that the logic is quite complicated ...... After combing for a long time, I summarized the following sentence:After switching the page number or changing the actual number of lines displayed on the current page, you need to reload the data!

The business logic has been sorted out here, and the next step is to write code for implementation. How should we design the above business logic?

1. Three custom events and one delegate need to be defined (because parameters need to be passed through the event) to notify the user of changes to corresponding parameters and reload list data.

1 /// <summary> 2 // The number of lines on each page is changed. The number of lines on each page is changed. 3 /// </summary> 4 public event EventHandler RowsPerPageChanged; 5 6 /// <summary> 7 // the current page is changed. The notification is sent to reload the list data. 8 /// </summary> 9 public event PageControlHandle CurrentPageChanged; 10 11 /// <summary> 12 // The total number of rows has changed, and the FocusedRowHandle13 is notified. /// </summary> 14 public event PageControlHandle TotalRowsChanged; 15 16 /// <summary> 17 // indicates the Method 18 for processing paging control events /// </summary> 19 /// <param name = "sender"> </param> 20 // <param name = "e"> </param> 21 public delegate void PageControlHandle (object sender, pageControlEventArgs e );
View Code

2. Five attributes need to be defined to pass parameters.

1 /// <summary> 2 /// option 3 for the drop-down list of lines per page /// </summary> 4 public Collection <string> RowsSelectItems 5 {6 get {return _ SelectItems ;} 7 set 8 {9 _ SelectItems = value; 10 cbeRows. properties. items. addRange (value); 11 cbeRows. selectedIndex = 0; 12 RowsPerPage = int. parse (_ SelectItems [0]); 13} 14} 15 16 /// <summary> 17 // total number of Rows 18 /// </summary> 19 public int TotalRows20 {21 set22 {23 _ Rows = value; 24 _ TotalPages = (int) Math. ceiling (decimal) _ Rows/RowsPerPage); 25 Refresh (); 26} 27} 28 29 // <summary> 30 // Handle31 of the currently selected row // </summary> 32 public int FocusedRowHandle33 {34 private get {return _ Handle- rowsPerPage * _ Current ;} 35 set {_ Handle = RowsPerPage * _ Current + value ;} 36} 37 38 // <summary> 39 // The number of rows per page is 40 /// </summary> 41 public int RowsPerPage {get; private set ;} 42 43 // <summary> 44 // Current page 45 // </summary> 46 public int CurrentPage => _ Current + 1;
View Code

3. Two Public methods are required for adding or deleting a list object and then processing the corresponding business logic

1 /// <summary> 2 /// add List member 3 /// </summary> 4 /// <param name = "count"> increase the number, default Value: 1 </param> 5 public void AddItems (int count = 1) 6 {7 _ Rows + = count; 8 _ Handle = _ Rows-1; 9 10 var page = _ Current; 11 Refresh (); 12 13 if (_ Current> page) 14 {15 // if the page number is changed, reload the data 16 CurrentPageChanged ?. Invoke (this, new PageControlEventArgs (FocusedRowHandle); 17} 18 else19 {20 TotalRowsChanged ?. Invoke (this, new PageControlEventArgs (FocusedRowHandle )); 21} 22} 23 24 // <summary> 25 // reduce List member 26 /// </summary> 27 /// <param name = "count"> decrease quantity, default Value: 1 </param> 28 public void RemoveItems (int count = 1) 29 {30 _ Rows-= count; 31 if (_ Handle> = _ Rows) _ Handle = _ Rows-1; 32 33 var page = _ Current; 34 Refresh (); 35 36 if (_ TotalPages = 1 | _ Handle <RowsPerPage * (_ TotalPages-1) | _ Current <page) 37 {38 // It's not the last page or you need to reload the data 39 CurrentPageChanged ?. Invoke (this, new PageControlEventArgs (FocusedRowHandle); 40} 41 else42 {43 TotalRowsChanged ?. Invoke (this, new PageControlEventArgs (FocusedRowHandle); 44} 45}
View Code

The rest is the internal logic processing function.

1 /// <summary> 2 // switch the number of lines per page 3 /// </summary> 4 private void PageRowsChanged () 5 {6 var change = RowsPerPage <_ Rows-RowsPerPage * _ Current; 7 RowsPerPage = int. parse (cbeRows. text); 8 RowsPerPageChanged ?. Invoke (this, null); 9 10 var page = _ Current; 11 Refresh (); 12 13 change = change | RowsPerPage <_ Rows-RowsPerPage * _ Current; 14 if (_ Current = page &&! Change) return; 15 16 // After switching the page number or changing the number of lines displayed on the current page, you need to reload the data 17 CurrentPageChanged ?. Invoke (this, new PageControlEventArgs (FocusedRowHandle )); 18} 19 20 // <summary> 21 // switch to the current page 22 // </summary> 23 // <param name = "page"> page number </ param> 24 private void ChangePage (int page) 25 {26 _ Handle = RowsPerPage * page; 27 28 Refresh (); 29 30 CurrentPageChanged ?. Invoke (this, new PageControlEventArgs (FocusedRowHandle )); 31} 32 33 // <summary> 34 // Refresh control 35 // </summary> 36 private new void Refresh () 37 {38 var total = _ TotalPages = 0? 1: _ TotalPages; 39 labRows. text = $ "Rows/pages | total {_ Rows} Rows | points {total} pages"; 40 labRows. refresh (); 41 42 _ Current = (int) Math. floor (decimal) _ Handle/RowsPerPage); 43 btnFirst. enabled = _ Current> 0; 44 btnPrev. enabled = _ Current> 0; 45 btnNext. enabled = _ Current <_ TotalPages-1; 46 btnLast. enabled = _ Current <_ TotalPages-1; 47 btnJump. enabled = _ TotalPages> 1; 48 49 var width = (int) Math. log10 (_ Current + 1) * 7 + 18; 50 btnJump. width = width; 51 btnJump. text = CurrentPage. toString (); 52 labRows. focus (); 53}
View Code

Complete code see: https://github.com/xuanbg/Utility/tree/master/Controls

After reconstruction, the paging control exposes only five attributes and two methods. You only need to assign a value to the corresponding attribute after the parameter changes. The adjustment of the number of lines per page, the loading of List data and the FocusedRowHandle of the list are completed by subscribing to the event. The sample code is as follows:

1 View. tabRole. rowsPerPageChanged + = (sender, args) => _ PageRows = View. tabRole. rowsPerPage; 2 View. tabRole. currentPageChanged + = (sender, args) => PageChanged (args. rowHandle); 3 View. tabRole. totalRowsChanged + = (sender, args) => View. gdvRole. focusedRowHandle = args. rowHandle; 4 5 /// <summary> 6 // switch the page number and reload the role list 7 /// </summary> 8 /// <param name = "handel"> current focus row </param> 9 private void PageChanged (int handel) 10 {11 _ CurrentPage = View. tabRole. currentPage; 12 13 LoadRoles (handel ); 14} 15 16 /// <summary> 17 // Add a role to the role list 18 /// </summary> 19 /// <param name = "role"> RoleInfo </param> 20 internal void AddRole (RoleInfo role) 21 {22 _ Roles. add (role); 23 24 View. tabRole. addItems (); 25 View. grdRole. refreshDataSource (); 26} 27 28 // <summary> 29 // Delete the currently selected role 30 /// </summary> 31 internal void RoleDelete () 32 {33 _ Roles. remove (Role); 34 35 View. tabRole. removeItems (); 36 View. gdvRole. refreshData (); 37}
View Code

If this text is helpful to the reader, please help me to recommend it. Thank you!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.