zoukankan      html  css  js  c++  java
  • UWP 下拉刷新控件(PullToRefreshControl)

    最近项目里面有下拉刷新的需求,自己做了一个,效果还不错。

      <Style TargetType="local:PullToRefreshControl">
            <Setter Property="HeaderTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid>
                            <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Visibility="{Binding IsReachThreshold,Converter={StaticResource InversedBooleanToVisibilityConverter}}">
                                <FontIcon FontSize="30"  FontFamily="Segoe UI Emoji" Glyph="" IsHitTestVisible="False"  VerticalAlignment="Bottom"/>
                                <TextBlock Margin="5,0,5,0" Text="下拉刷新" VerticalAlignment="Bottom"/>
                            </StackPanel>
                            <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Visibility="{Binding IsReachThreshold, Converter={StaticResource BooleanToVisibilityConverter}}">
                                <FontIcon FontSize="30"   FontFamily="Segoe UI Emoji" Glyph="" IsHitTestVisible="False" VerticalAlignment="Bottom"/>
                                <TextBlock Margin="5,0,5,0" Text="释放立即刷新" VerticalAlignment="Bottom"/>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:PullToRefreshControl">
                        <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Margin="{TemplateBinding Margin}">
                            <ScrollViewer x:Name="ScrollViewer"
                                          VerticalScrollBarVisibility="Hidden">
                                <StackPanel>
                                    <ContentControl x:Name="PanelHeader" ContentTemplate="{TemplateBinding HeaderTemplate}" HorizontalContentAlignment="Center" VerticalContentAlignment="Bottom" />
                                    <ContentPresenter x:Name="PanelContent" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                </StackPanel>
                            </ScrollViewer>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
     [TemplatePart(Name = PanelHeader, Type = typeof(ContentControl))]
        [TemplatePart(Name = PanelContent, Type = typeof(ContentPresenter))]
        [TemplatePart(Name = ScrollViewer, Type = typeof(ScrollViewer))]
        public class PullToRefreshControl:ContentControl
        {
            #region Fields
            private const string PanelHeader = "PanelHeader";
            private const string PanelContent = "PanelContent";
            private const string ScrollViewer = "ScrollViewer";
            private ContentControl _panelHeader;
            private ContentPresenter _panelContent;
            private ScrollViewer _scrollViewer;
            #endregion
    
            #region Property
    
            /// <summary>
            /// The threshold for release to refresh,defautl value is 2/5 of PullToRefreshPanel's height.
            /// </summary>
            public double RefreshThreshold
            {
                get { return (double)GetValue(RefreshThresholdProperty); }
                set { SetValue(RefreshThresholdProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for RefreshThreshold.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty RefreshThresholdProperty =
                DependencyProperty.Register("RefreshThreshold", typeof(double), typeof(PullToRefreshControl), new PropertyMetadata(0.0,new PropertyChangedCallback(OnRefreshThresholdChanged)));
    
            private static void OnRefreshThresholdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var pullToRefreshControl = d as PullToRefreshControl;
                pullToRefreshControl.UpdateContentGrid();
            }
    
            /// <summary>
            /// occur when reach threshold.
            /// </summary>
            public event EventHandler PullToRefresh;
    
            public DataTemplate HeaderTemplate
            {
                get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
                set { SetValue(HeaderTemplateProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for HeaderTemplate.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty HeaderTemplateProperty =
                DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(PullToRefreshControl), new PropertyMetadata(null));
    
            public bool IsReachThreshold    
            {
                get { return (bool)GetValue(IsReachThresholdProperty); }
                set { SetValue(IsReachThresholdProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for IsReachThreshold.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty IsReachThresholdProperty =
                DependencyProperty.Register("IsReachThreshold", typeof(bool), typeof(PullToRefreshControl), new PropertyMetadata(false));
    
    
            #endregion
    
            protected override void OnApplyTemplate()
            {
                _panelHeader = GetTemplateChild(PanelHeader) as ContentControl;
                _panelHeader.DataContext = this;
                _panelContent = GetTemplateChild(PanelContent) as ContentPresenter;
                _scrollViewer = GetTemplateChild(ScrollViewer) as ScrollViewer;
                _scrollViewer.ViewChanged += _scrollViewer_ViewChanged;
                base.OnApplyTemplate();
            }
    
            private void _scrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
            {
                //Sometime we can't make it to 0.0.
                IsReachThreshold = _scrollViewer.VerticalOffset <= 5.0;
                if (e.IsIntermediate)
                {
                    return;
                }
    
                if (IsReachThreshold)
                {
                    if (PullToRefresh!=null)
                    {
                        PullToRefresh(this, null);
                    }
                }
                _panelHeader.Height = RefreshThreshold > _panelHeader.ActualHeight ? RefreshThreshold : _panelHeader.ActualHeight;
                this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    _scrollViewer.ChangeView(null, _panelHeader.Height, null);
                });
    
            }
    
            public PullToRefreshControl()
            {
                this.DefaultStyleKey = typeof(PullToRefreshControl);
                this.Loaded +=(s,e)=>
                {
                    if (RefreshThreshold == 0.0)
                    {
                        RefreshThreshold = this.ActualHeight * 2 / 5.0;
                    }
                    UpdateContentGrid();
                };
                this.SizeChanged += (s, e) =>
                {
                    if (RefreshThreshold==0.0)
                    {
                        RefreshThreshold = this.ActualHeight *2 / 5.0;
                    }
                    UpdateContentGrid();
                };
            }
    
            #region Method
            private void UpdateContentGrid()
            {
                if (_scrollViewer != null && _panelContent!=null && _panelHeader !=null)
                {
                    _panelHeader.Height = RefreshThreshold > _panelHeader.ActualHeight? RefreshThreshold: _panelHeader.ActualHeight;
                    this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        _scrollViewer.ChangeView(null, _panelHeader.Height, null, true);
                    });
                    _panelContent.Width = this.ActualWidth;
                    _panelContent.Height = this.ActualHeight;
                }
            }
            #endregion
        }
  • 相关阅读:
    《大话数据结构》第1章 数据结构绪论 1.2 你数据结构怎么学的?
    伍迷七八月新浪微博集锦
    《大话数据结构》第9章 排序 9.7 堆排序(下)
    《大话数据结构》第3章 线性表 3.8.2 单链表的删除
    《大话数据结构》第9章 排序 9.5 直接插入排序
    《大话数据结构》第9章 排序 9.8 归并排序(上)
    《大话数据结构》第2章 算法基础 2.9 算法的时间复杂度
    《大话数据结构》第1章 数据结构绪论 1.1 开场白
    《大话数据结构》第9章 排序 9.1 开场白
    [AWS] Assign a public IP address to an EC2 instance after launched
  • 原文地址:https://www.cnblogs.com/FaDeKongJian/p/5120910.html
Copyright © 2011-2022 走看看