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
        }
  • 相关阅读:
    loj6145. 「2017 山东三轮集训 Day7」Easy
    CF1019E Raining season
    CF1261F Xor-Set
    Python笔试——递归算法学习
    Python笔试——贪心算法
    Python笔试——万万没想到抓捕孔连顺
    Python笔试——雀魂启动
    Python学习——正则表达式
    Python笔试——毕业旅行问题
    Python笔试——Stern-Brocot tree
  • 原文地址:https://www.cnblogs.com/FaDeKongJian/p/5120910.html
Copyright © 2011-2022 走看看