new ScrollViewer control

1. add IsEnableInertia Property;
2. add IsPenetrating Property;
This commit is contained in:
NaBian 2018-08-30 16:32:53 +08:00
parent 3e73f31379
commit b29479914a
7 changed files with 136 additions and 26 deletions

View File

@ -0,0 +1,102 @@
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Tools;
namespace HandyControl.Controls
{
public class ScrollViewer : System.Windows.Controls.ScrollViewer
{
private double _totalVerticalOffset;
private bool _isRunning;
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (!IsEnableInertia)
{
base.OnMouseWheel(e);
return;
}
e.Handled = true;
if (!_isRunning)
{
_totalVerticalOffset = VerticalOffset;
CurrentVerticalOffset = VerticalOffset;
}
_totalVerticalOffset = Math.Min(Math.Max(0, _totalVerticalOffset - e.Delta), ScrollableHeight);
var animation = AnimationHelper.CreateAnimation(_totalVerticalOffset, 500);
animation.EasingFunction = new CubicEase
{
EasingMode = EasingMode.EaseOut
};
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += (s,e1)=>
{
CurrentVerticalOffset = _totalVerticalOffset;
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentVerticalOffsetProperty, animation);
}
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) =>
IsPenetrating ? null : base.HitTestCore(hitTestParameters);
/// <summary>
/// 是否支持惯性
/// </summary>
public static readonly DependencyProperty IsEnableInertiaProperty = DependencyProperty.Register(
"IsEnableInertia", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(default(bool)));
/// <summary>
/// 是否支持惯性
/// </summary>
public bool IsEnableInertia
{
get => (bool) GetValue(IsEnableInertiaProperty);
set => SetValue(IsEnableInertiaProperty, value);
}
/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public static readonly DependencyProperty IsPenetratingProperty = DependencyProperty.Register(
"IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(default(bool)));
/// <summary>
/// 控件是否可以穿透点击
/// </summary>
public bool IsPenetrating
{
get => (bool) GetValue(IsPenetratingProperty);
set => SetValue(IsPenetratingProperty, value);
}
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
private static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register(
"CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(default(double), CurrentVerticalOffsetChangedCallback));
private static void CurrentVerticalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ScrollViewer ctl && e.NewValue is double v)
{
ctl.ScrollToVerticalOffset(v);
}
}
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
private double CurrentVerticalOffset
{
get => (double) GetValue(CurrentVerticalOffsetProperty);
set => SetValue(CurrentVerticalOffsetProperty, value);
}
}
}

View File

@ -29,6 +29,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\HandyControl.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="Controls\Attach\IconSwitchElement.cs" />
@ -40,6 +41,7 @@
<DependentUpon>ColorPicker.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\Attach\IconElement.cs" />
<Compile Include="Controls\ScrollViewer.cs" />
<Compile Include="Controls\Info\InfoControl.cs" />
<Compile Include="Controls\Info\InfoNumericUpDown.xaml.cs">
<DependentUpon>InfoNumericUpDown.xaml</DependentUpon>

View File

@ -1,12 +1,13 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<!--普通菜单项-->
<Style x:Key="MenuItemBaseStyle" TargetType="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="controls:ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
<Setter Property="Template">
@ -61,9 +62,9 @@
<ContentPresenter x:Name="menuHeaderContainer" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Popup Grid.Column="0" x:Name="PART_Popup" PlacementTarget="{Binding ElementName=templateRoot}" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="0,0,2,2" x:Name="SubMenuBorder" BorderThickness="1,0,1,1" BorderBrush="{DynamicResource BorderBrush}" Background="White">
<ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="SubMenuScrollViewer" Margin="0,6">
<controls:ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="SubMenuScrollViewer" Margin="0,6">
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</ScrollViewer>
</controls:ScrollViewer>
</Border>
</Popup>
</Grid>
@ -174,9 +175,9 @@
<Path x:Name="Path" Grid.Column="4" Width="10" Height="10" HorizontalAlignment="Left" Data="{StaticResource RightGeometry}" Stretch="Uniform" Fill="{TemplateBinding Foreground}" Uid="Path_16" VerticalAlignment="Center"/>
<Popup Grid.Column="1" x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Right" VerticalOffset="-7">
<Border CornerRadius="2" x:Name="SubMenuBorder" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" Background="White">
<ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="SubMenuScrollViewer" Margin="0,6">
<controls:ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="SubMenuScrollViewer" Margin="0,6">
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</ScrollViewer>
</controls:ScrollViewer>
</Border>
</Popup>
</Grid>
@ -206,9 +207,9 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Background="White" CornerRadius="2" MaxHeight="{TemplateBinding MaxHeight}" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}">
<ScrollViewer Margin="0,6" VerticalScrollBarVisibility="Auto">
<controls:ScrollViewer Margin="0,6" VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</controls:ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>

View File

@ -1,5 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<!--默认ListBoxItem样式-->
<Style x:Key="ListBoxItemBaseStyle" TargetType="{x:Type ListBoxItem}">
@ -48,10 +49,10 @@
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="controls:ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="controls:ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="controls:ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="controls:ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource ListBoxItemBaseStyle}"/>
@ -59,9 +60,9 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<ScrollViewer Focusable="false">
<controls:ScrollViewer Focusable="false">
<ItemsPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</controls:ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>

View File

@ -1,5 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<Style x:Key="ScrollBarBaseRepeatButton" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
@ -114,7 +115,7 @@
</Style.Triggers>
</Style>
<ControlTemplate x:Key="ScrollViewerBaseControlTemplate" TargetType="{x:Type ScrollViewer}">
<ControlTemplate x:Key="ScrollviewerBaseControlTemplate" TargetType="{x:Type controls:ScrollViewer}">
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
@ -131,10 +132,10 @@
</Grid>
</ControlTemplate>
<Style x:Key="ScrollViewerBaseStyle" TargetType="{x:Type ScrollViewer}">
<Style x:Key="ScrollViewerBaseStyle" TargetType="{x:Type controls:ScrollViewer}">
<Setter Property="VerticalScrollBarVisibility" Value="Auto"></Setter>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template" Value="{StaticResource ScrollViewerBaseControlTemplate}"></Setter>
<Setter Property="Template" Value="{StaticResource ScrollviewerBaseControlTemplate}"></Setter>
</Style>
</ResourceDictionary>

View File

@ -1,11 +1,12 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Base/ScrollViewerBaseStyle.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<!--默认样式-->
<Style BasedOn="{StaticResource ScrollViewerBaseStyle}" TargetType="{x:Type ScrollViewer}"></Style>
<Style BasedOn="{StaticResource ScrollViewerBaseStyle}" TargetType="{x:Type controls:ScrollViewer}"></Style>
</ResourceDictionary>

View File

@ -39,7 +39,7 @@
</StackPanel>
</controls:WindowBorderless.NoUserContent>
<Grid Margin="32,0" Grid.IsSharedSizeScope="True">
<ScrollViewer>
<controls:ScrollViewer>
<StackPanel Margin="0,10" Name="StackPanelMain">
<!--按钮-->
<!--<Border Visibility="Collapsed" Style="{StaticResource BorderRegionStyle}">
@ -366,7 +366,7 @@
</Grid>
</Border>-->
<!--图片浏览-->
<Border Visibility="Visible" Margin="0,10,0,0" Style="{StaticResource BorderRegionStyle}">
<Border Visibility="Collapsed" Margin="0,10,0,0" Style="{StaticResource BorderRegionStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Header"/>
@ -451,11 +451,13 @@
<WrapPanel controls:InfoControl.TitleWidth="280" Grid.Column="1" ItemWidth="500" Margin="0,0,0,10">
<controls:InfoComboBox DisplayMemberPath="Id" SelectedValuePath="Id" ItemsSource="{Binding FruitList,ElementName=MyWindow}" Margin="0,0,0,30" HorizontalAlignment="Stretch" Title="下拉框(必填) InfoComboBox" PlaceHolder="请选择一种水果" ErrorStr="请选择一种水果"></controls:InfoComboBox>
<controls:InfoComboBox DisplayMemberPath="Name" SelectedValuePath="Id" IsEditable="True" ItemsSource="{Binding FruitList,ElementName=MyWindow}" Margin="0,0,0,30" HorizontalAlignment="Stretch" IsNeedly="False" Title="下拉框 InfoComboBox" PlaceHolder="请选择一种水果">
--><!--<sys:String>苹果</sys:String>
-->
<!--<sys:String>苹果</sys:String>
<sys:String>香蕉</sys:String>
<sys:String>橘子</sys:String>
<sys:String>菠萝</sys:String>
<sys:String>葡萄</sys:String>--><!--
<sys:String>葡萄</sys:String>-->
<!--
</controls:InfoComboBox>
<controls:InfoTextBox Margin="0,0,0,30" HorizontalAlignment="Stretch" Title="文本框(必填) InfoTextBox" PlaceHolder="请输入一种水果" ErrorStr="请输入一种水果"></controls:InfoTextBox>
<controls:InfoTextBox TitleAlignment="Top" Margin="0,0,0,30" HorizontalAlignment="Stretch" IsNeedly="False" Title="文本框 InfoTextBox" PlaceHolder="请输入一种水果"></controls:InfoTextBox>
@ -900,6 +902,6 @@
</Grid>
</Border>-->
</StackPanel>
</ScrollViewer>
</controls:ScrollViewer>
</Grid>
</controls:WindowBorderless>