stay windows phone In order to ensure the user experience, we often encounter the problem of loading data when using data list in . This problem is so common that you have to face it sooner or later as long as you use the data list . A lot of people will say that there is a solution to this problem . In fact, the real problem is not how to realize the dynamic loading of list data ? And our real goal is how to make this loading method achieve a good user experience when users operate . The rationality based on user experience is higher than the realization of the function itself .

And this rationality is mainly reflected in when to load data ? When do I need data local caching to speed up local UI Respond to ? That is to say, our starting point is based on the product user experience . We need to apply certain loading strategies to the dynamic loading of the list to restrict the operation behavior . To achieve this purpose . stay WP On the platform, if you pay attention to . You will find that whenever you encounter such a problem involving user experience . We also usually look at what other platforms do . Maybe it's also a way of thinking . from Android and IOS From a platform perspective . Several common ways to load data .

[ The way 1]: Auto drop down loading

This is a common way . Usually in a separate data list . When we first came in, the list loaded the latest data . When users need more or older data . The user slides up . When scroll to UI More data is automatically loaded at the bottom . Characteristic is Automatic loading Avoid more manual operations . In the case of network patency The list operation is smooth . It is determined that the user cannot control the whole data process .

[ The way 2]: Manually pull down to load

The way 1 The adopted users drop down to UI Load automatically at the bottom . The whole loading process is not controlled by the user . namely It is impossible for users to manually enable loading more or older data only when needed . Two ways 2 When the user scrolls UI You can choose whether to load more data . Users can control the whole data loading process .

[ The way 3]:UI Prompt to load

UI Prompt how and how to load 1 、2 Completely different . When the user drops down and loads more data . It will prompt you to pop up a UI Prompt layer . Prompt the loading progress . During the data loading process, the whole LiveView You can't do anything UI Operation of the . The user can only wait for the data loading to complete before operating again UI. This is in many ways Pc Platform projects see a lot of .

[ The way 4]: The drop-down refresh

When the user first comes in . When you get the latest data from the list . If the list changes dynamically with time . Users want to get the latest data on the current page . At this time, the value is reflected . You don't need to re-enter the page to get the latest data . The whole operation flow of pull-down refresh is . The user is in UI Drop down the entire list in the top area . When the user gestures away UI In the top area . The list automatically goes back to the top . And start loading the latest data . Update to ListView In the to . In the loading process, users can still operate the current UI data .

In the above four ways Android and Ios The more common data loading method in . Of course. Ios You can see something similar in Pc End data paging . It also includes using some custom animation methods to get a better loading experience . Forget about it . Let's start with these basic loading methods . Let's talk about how to Windows Phone Get the best loading experience from the data list in .

We need one in a vertical screen at present ListBox. I hope users can get the latest and older data through gesture operation . From the above four independent loading methods . Combine the advantages and disadvantages of the four methods . Design it. windows phone Data list loading strategy Summarized below :

WP ListBox Data loading strategy :

A: The top area of the list supports drop-down data refresh .

B: When the user swipes, scrolls the list to the bottom More old data can be loaded

C: When the user scrolls from the bottom to the top of the list while sliding It still supports loading the latest data .

We have defined our requirement loading strategy . To try Windows Phone A single independent class table tries to realize the above three features .

Slide the list up and down to load

From the above three loading strategies . Let's first achieve . Slide up and down the list to load data . That is, when the user scrolls UI Older data is automatically loaded at the bottom . When the user scrolls to the top, the latest data is automatically loaded . Page loading data set using common ListBox To illustrate this example .

First, we build a Project Name it DynamicLoadData stay MainPage Add a default ListBox Control :

 1: <!--ContentPanel - place additional content here-->
 2: <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 3: <ListBox x:Name="DynamicLoadData_LB"></ListBox>
 4: </Grid>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

as everyone knows . Realization Listbox Slide load data . A lot of people will adopt a more common way on the Internet . That is, monitoring ListBox Of MouseMove event . This event is triggered when the list of gestures moves up and down . After event triggering . By testing ListBox.VerticalOffSet Current scroll bar position . Again ListBox.ScrollableHeight The scroll bar can reach the maximum displacement, the distance difference between the two . To see if it's at the bottom . Load new data .

But you'll find that there's a problem . In some gesture operations Will suddenly find out Listbox The bottom has been scrolled without loading data . Although the logic is correct, the operation is flexible and sometimes ineffective In fact, the root cause of this problem is that . ListBox.MouseMove Events are triggered only when your finger touches the screen and swipes the screen . But as long as your finger is off the screen . It's like sliding hard before you leave . You'll find that listbox It has reached the bottom, but this load event has not been triggered . Mainly because the current gesture has left the screen MouseMove Events will not be triggered . Even if the ListBox It's rolling to the bottom .

We also know that ListBox The control itself is built in ScrollViewer. In the same way, we judge the current ListBox Of VerticalOffSet And built in ScrollViewer Compare the actual roll position . To determine whether the current scroll is at the top or bottom .

First of all get ListBox in ScrollViewer Control :

 1: public static List<T> GetVisualChildCollection<T>(object parent) where T : UIElement
 2: {
 3: List<T> visualCollection = new List<T>();
 4: GetVisualChildCollection(parent as DependencyObject, visualCollection);
 5: return visualCollection;
 6: }
 7:  
 8: public static void GetVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : UIElement
 9: {
 10: int count = VisualTreeHelper.GetChildrenCount(parent);
 11: for (int i = 0; i < count; i++)
 12: {
 13: DependencyObject child = VisualTreeHelper.GetChild(parent, i);
 14: if (child is T)
 15: visualCollection.Add(child as T);
 16: else if (child != null)
 17: GetVisualChildCollection(child, visualCollection);
 18: }
 19: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

obtain ScrollViewer Control and subscribe to its vertical and horizontal ValueChanged event The implementation is as follows :

 1: private void RegisterScrollListBoxEvent()
 2: {
 3: List<ScrollBar> controlScrollBarList =GetVisualChildCollection<ScrollBar>(this.WholeCityPictureFllow_LB);
 4: if (controlScrollBarList == null)
 5: return;
 6:  
 7: foreach (ScrollBar queryBar in controlScrollBarList)
 8: {
 9: if (queryBar.Orientation == System.Windows.Controls.Orientation.Vertical)
 10: queryBar.ValueChanged += queryBar_ValueChanged;
 11: }
 12: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

stay ValueChange In the event, judge whether it reaches the top or the bottom :

 1: void queryBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
 2: {
 3: ScrollBar scrollBar = (ScrollBar)sender;
 4: object valueObj = scrollBar.GetValue(ScrollBar.ValueProperty);
 5: object maxObj = scrollBar.GetValue(ScrollBar.MaximumProperty);
 6: object minObj = scrollBar.GetValue(ScrollBar.MinimumProperty);
 7:  
 8: if (valueObj != null && maxObj != null)
 9: {
 10: double value = (double)valueObj;
 11: double max = (double)maxObj;
 12: double min = (double)minObj;
 13:  
 14: if (value >= max)
 15: {
 16: #region Load Old 
 17: #endregion
 18: }
 19:  
 20: if (value <= min)
 21: { 
 22: #region Load New 
 23: #endregion 
 24: }
 25: }
 26: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

As above, through judgment listbox Current position and maximum scrolling area Max and Min Compare to determine whether the current scroll is at the top or bottom . The method is extremely simple . It's worth mentioning that . We get to the top and we don't need any extra processing . Sometimes we UI When the elements are rich . We want to make sure that the sliding operation does not result from the data loading operation UI There's a Caton . There are two that need extra control . If every time you load data is similar to 30 It's better to have more content than the whole screen . In addition, we need to trigger loading when we slide down . To put Max-100 Or an appropriate value . The purpose of this is for the user to scroll down and start loading without scrolling to the bottom . The data is preloaded as soon as it reaches the bottom . In the case of network stability back to the operation UI The list is more fluid .

As mentioned above, the actual loading effect needs to be fine tuned to achieve the best . It has been loaded up and down .

so Let's focus on The drop-down refresh .

The drop-down refresh

Say drop-down refresh . I'm afraid in Windows Phone The most frequently used app every day is Sina Weibo has been launched . and IOS The effect is basically the same The effect is as follows :

When the user drops down At the top of the data list will be displayed A down arrow and a drop-down refresh text prompt . Then prompt to release auto refresh . Release the gesture The list goes back to the top . Automatically start loading the latest data . And update the data to ListBox In the to , The whole process is as above . First of all, let's analyze how to realize the idea ?

because Listbox Basically, we need to manipulate events and properties . be based on ListBox Let's rewrite a control RefreshListBox. First, let's see how the tip area at the top is implemented .

Actually ListBox Of Template Implementation is based on ScrollViewer Control ItemsPresenter. ItemsPresenter Is used to specify in the project control template that ItemsControl Defined ItemsPanel The visual tree of the control to be added . So we just need to be in a Grid Put the cue area in ItemsPresenter You can see the whole prompt area from the drop-down menu . Like this custom ListBox The template of :

 1: <ControlTemplate TargetType="local:RefreshBox">
 2: <ScrollViewer x:Name="ScrollViewer" ...>
 3: <Grid>
 4: <Grid Margin="0,-90,0,30" Height="60" VerticalAlignment="Top" x:Name="ReleaseElement">
 5: <!-- Tip Area Here -->
 6: </Grid>
 7: </Grid>
 8: <ItemsPresenter/>
 9: </ScrollViewer>
 10: </ControlTemplate>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

When loading controls . We need to get the custom control RefreshListBox Built in slide ScrollViewer And subscribe to MouseMove and ManipulationCompleted event . And get the tip area ReleaseElement References to objects . rewrite OnApplyTemplate Method :

 1: public override void OnApplyTemplate()
 2: {
 3: base.OnApplyTemplate();
 4: if (ElementScrollViewer != null)
 5: {
 6: ElementScrollViewer.MouseMove -= viewer_MouseMove;
 7: ElementScrollViewer.ManipulationCompleted -= viewer_ManipulationCompleted;
 8: }
 9:  
 10: ElementScrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
 11: if (ElementScrollViewer != null)
 12: { 
 13: ElementScrollViewer.MouseMove += viewer_MouseMove;
 14: ElementScrollViewer.ManipulationCompleted += viewer_ManipulationCompleted;
 15: }
 16:  
 17: ElementRelease = GetTemplateChild("ReleaseElement") as UIElement; 
 18: ChangeVisualState(false);
 19: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

When SrollViewer by Null When subscribing to an event action . If it's different SDK edition [WP7 Or WP8] The execution process discovers that the subscription ManipulationCompleted Not triggered . You can force the addition of processing events in the following ways [ stay WP7 And WP8 All tests are valid ] :

 1: ElementScrollViewer.AddHandler(ScrollViewer.ManipulationCompletedEvent, 
 2: new EventHandler<ManipulationCompletedEventArgs>(viewer_ManipulationCompleted), true); 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

stay MouseMove Incident . By judgment ListBox Of VerticalOffset When it's equal to 0; Both at the top . When the pull-down exceeds a certain distance, it will start to prompt the pull-down to refresh the update RealseElement Element :

 1: private void viewer_MouseMove(object sender, MouseEventArgs e)
 2: {
 3:     if (VerticalOffset == 0)
 4:     {
 5:         var p = this.TransformToVisual(ElementRelease).Transform(new Point());
 6:         if (p.Y < -VerticalPullToRefreshDistance) //Passed thresdhold : In pulling state area
 7:         {            
 8:             //TODO: Update layout//visual states
 9:         }
 10:         else //Is not pulling
 11:         {
 12:             //TODO: Update layout/visual states
 13:         }
 14:     }
 15: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Same logic . stay ManipulationCompleted Event is triggered when the user completes the gesture operation . If at present ListBox VerticalOffset be equal to 0 That is, at the top . When you release, when you gesture listBox Go back to the top and start loading the latest list data and updating the list :

 1: private void viewer_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
 2: {
 3:     var p = this.TransformToVisual(ElementRelease).Transform(new Point());
 4:     if (p.Y < -VerticalPullToRefreshDistance)
 5:     {
 6:         //TODO: Raise Polled to refresh event
 7:     }
 8: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In this way, the basic logic of the whole pull-down refresh is clear . You can rewrite the whole ListBox Realization .

When you first come in and load data :

Drop down is the effect :

Just released the effect :

This is a combination of ListBox The above three requirements are basically realized by sliding up and down refresh .

Source download [https://github.com/chenkai/LoadData]

Contact: @chenkaihome

Windows phone application development [18]- Drop down to refresh more related articles

  1. Wechat applet development The drop-down refresh , Pull up to load more

    This article records how to achieve pull-down refresh in wechat applet , Pull up to load more Let's take a look at the interface first It's like this . This Demo Using several of wechat Api And events , I'll list them first . 1.wx.request ( Get data from the remote server , ...

  2. iOS Development -UIRefreshControl The drop-down refresh

    Pull down refresh has always been the world of the third library , Some third libraries even support up, down, left, right refresh ,UIRefreshControl yes iOS6 A refresh control supported after , However, due to the single function , Styles cannot be customized , So it can't meet the needs of the public , The usage is simple ...

  3. Windows phone application development [22]- Let's talk about the drop-down refresh

    Update a blog a few weeks ago Windows phone application development [18]- The drop-down refresh post , A lot of people mentioned a lot of problems in microblog and blog comments . In fact, in the actual project, I put forward the idea of solving the problem based on this blog, and optimized the solution . In order to be able to ...

  4. Android Several powerful drop-down refresh Libraries

    BeautifulRefreshLayout Many excellent drop-down refresh ( Besides what I wrote T_T) Speaking of pull-down refresh , It's like going through a period of history ... (1) I just learned android When , It's using XListView, stay g ...

  5. UWP Introduction to development ( 7、 ... and )—— The drop-down refresh

    This article is intended to give these days Win10 Mobile Negative news constantly washes the floor , It's not difficult to prove that a simple pull-down refresh is implemented .UWP The bigger difficulty in development is laziness , Lack of willingness to learn . instead of “ Some software doesn't even have a pull-down refresh control ” The idea is . And ...

  6. windows phone The drop-down refresh

    stay windows phone In order to ensure the user experience, we often encounter the problem of loading data when using data list in . This problem is so common that you have to face it sooner or later as long as you use the data list . A lot of people will say that there is a solution to this problem . In fact, the real problem is not how to ...

  7. Android SwipeRefreshLayout The drop-down refresh ——Hi_ Blog Android App Development Notes

    Previously write drop-down refresh It feels so hard , To judge ListView Whether to roll to the top , Also load the header layout , And control The state of the head layout , Wait a lot . I feel like trouble is killing me . I learned it today SwipeRefreshLayout Usage of , Let's share , Yes ...

  8. Android Developing the way of learning - How to do it ?

    Because the latest development involves reading data from the network , So naturally, the drop-down refresh function is indispensable , The general way to search is to customize ListView perhaps RecyclerView To rewrite OnTouch perhaps OnScroll Method to achieve gesture ...

  9. IOS Develop pull-down refresh and pull-up load more

    IOS Develop pull-down refresh and pull-up load more brief introduction 1. Common implementation of pull down refresh (1)UIRefreshControl (2)EGOTTableViewrefresh (3)AH3DPullRefresh ( ...

Random recommendation

  1. V4L2 Frame analysis learning 2

    Reproduced in :http://www.techbulo.com/1198.html v4l2_device v4l2_device stay v4l2 Act as all in the framework v4l2_subdev The parent device of , Manage the sub devices registered under it ...

  2. alert()、confirm() and prompt() The difference and usage of

    1. Warning message box alertalert Method has a parameter , That is, the text string that you want to display to the user . The string is not HTML Format . The message box provides a " determine " The button lets the user close the message box , And the message box is a pattern ...

  3. DIV+CSS Sliding door effect

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. C# Anonymous expressions (Lambda expression )

    Anonymous expressions Let's talk about it this time Lambda Expression bar , It's easy anyway , I don't emphasize it like other experts , Just talk about the method : The preparation conditions are as follows : First of all , An anonymous expression must have a corresponding delegate . As long as there is a corresponding delegation . Next ...

  5. LA 6476 Outpost Navigation (DFS+ prune )

    Topic link Solution DFS+ prune For a passing point k, If it's necessary to go again , Then it must have been through k In the after k The maximum number of ammo points has been increased . Otherwise, there must be no need to go again . Record the maximum number of ammunition passing through each point , Yes dfs Pruning . #i ...

  6. linux Boot automatically start the script

      Preface linux It has its own complete set of startup   system , Caught. linux start-up   The context of ,linux Start of   The process will no longer be mysterious . Before reading, I suggest you take a look at the attached picture . In this paper, we assume that inittab Set in the init tree by :/etc/ ...

  7. MySQL Of char and varchar Handling of spaces

    MySQL Of char and varchar Experiments with spaces in storage and query MySQL edition One . test char Storage and query with spaces Tests found , Stored data ,char The space on the right side of the data type was deleted when it was stored , But the space on the left is still ...

  8. [USACO 07NOV]Cow Relays

    Description For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a rel ...

  9. koa Source code delegate Use

    koa in context Can be called directly request and response An important reason for attributes is the use of delegate take req and res The properties of proxy to context, Delegator.prototype.gette ...

  10. 【 front end 】 Three bug

    Catalog One .Array Object's indexOf() Two . Use jquery,clone() Drop down box problem 3、 ... and .jquery Capture the html5 Of data-* attribute One .Array Object's indexOf() 1.inde ...