按钮动画、定时响应刷新
按钮动画
效果图如下:
新建用户控件UC_AutoRefreshButton
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Width="auto" Height="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="Button_Click" x:Name="btnReFresh">
<Button.Background>
<ImageBrush ImageSource="{Binding ImgBackgroudPath, RelativeSource={RelativeSource AncestorType=local:UC_AutoRefreshButton}}"/>
</Button.Background>
</Button>
<Rectangle Grid.Row="2" Height="5" Width="{Binding Path=ActualWidth,RelativeSource={RelativeSource AncestorType=local:UC_AutoRefreshButton}}">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource PrimaryColor}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="2" Height="5" Width="{Binding Path=ActualWidth,RelativeSource={RelativeSource AncestorType=local:UC_AutoRefreshButton}}">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BackgroundColor}"/>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" x:Name="transparentStop"/>
<GradientStop Offset="0" Color="Black" x:Name="visibleStop"/>
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
<UserControl.Resources>
<Storyboard x:Key="LinearTimeline" FillBehavior="Stop">
<DoubleAnimation Storyboard.TargetName="transparentStop"
Storyboard.TargetProperty="Offset"
From="0" To="1"
Duration="{Binding AminationDuration, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource Int2DurationConverter}}" />
<DoubleAnimation Storyboard.TargetName="visibleStop"
Storyboard.TargetProperty="Offset"
From="0" To="1"
Duration="{Binding AminationDuration, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource Int2DurationConverter}}" />
</Storyboard>
</UserControl.Resources>
后台实现
public partial class UC_AutoRefreshButton : UserControl
{
/// <summary>
/// 背景图相对路径
/// </summary>
public string ImgBackgroudPath
{
get { return (string)GetValue(ImgBackgroudPathProperty); }
set { SetValue(ImgBackgroudPathProperty, value); }
}
public static readonly DependencyProperty ImgBackgroudPathProperty =
DependencyProperty.Register("ImgBackgroudPath", typeof(string), typeof(UC_AutoRefreshButton), new PropertyMetadata(ValueBoxes.StringEmptyBox));
/// <summary>
/// 动画持续时间(s)
/// </summary>
public int AminationDuration
{
get { return (int)GetValue(AminationDurationProperty); }
set { SetValue(AminationDurationProperty, value); }
}
public static readonly DependencyProperty AminationDurationProperty =
DependencyProperty.Register("AminationDuration", typeof(int), typeof(UC_AutoRefreshButton), new PropertyMetadata(1));
/// <summary>
/// 声明路由事件
/// 参数:要注册的路由事件名称,路由事件的路由策略,事件处理程序的委托类型(可自定义),路由事件的所有者类型
/// </summary>
public static readonly RoutedEvent ClickedEvent = EventManager.RegisterRoutedEvent("Clicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UC_AutoRefreshButton));
/// <summary>
/// 处理各种路由事件的方法
/// </summary>
public event RoutedEventHandler Clicked
{
// 将路由事件添加路由事件处理程序
add { AddHandler(ClickedEvent, value); }
// 从路由事件处理程序中移除路由事件
remove { RemoveHandler(ClickedEvent, value); }
}
Storyboard _storyboard;
public UC_AutoRefreshButton()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
StoryboardStart();
}
void StoryboardStart()
{
_storyboard = this.FindResource("LinearTimeline") as Storyboard;
if (_storyboard != null)
{
_storyboard.Completed -= _storyboard_Completed;
_storyboard.Completed += _storyboard_Completed;
_storyboard.Begin(this, true);
}
}
private void _storyboard_Completed(object sender, EventArgs e)
{
StoryboardStart();
// 定义传递参数
RoutedPropertyChangedEventArgs<object> args = new RoutedPropertyChangedEventArgs<object>(0, "Storyboard_Completed", ClickedEvent);
// 引用自定义路由事件
btnReFresh.RaiseEvent(args);
}
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_storyboard.Stop(this);
_storyboard_Completed(null, null);
}
}
应用:
<local:UC_AutoRefreshButton x:Name="ucReFresh" Width="200" Height="50" ImgBackgroudPath="/WpfDemo;component/Image/autorefresh.png" AminationDuration="{Binding ElementName=slider,Path=Value}" Clicked="UcReFresh_Clicked" />
<Slider x:Name="slider" Minimum="0" Maximum="10" Value="1" TickPlacement="Both" TickFrequency="1" AutoToolTipPlacement="BottomRight"/>
private void UcReFresh_Clicked(object sender, RoutedEventArgs e)
{
var args = (RoutedPropertyChangedEventArgs<object>)e;
MessageBox.Show("Manual Refresh");
}
扩展
Button添加图片
<Button HorizontalAlignment="Stretch" Command="{Binding PrevCommand}">
<Button.Template>
<ControlTemplate>
<Grid Cursor="Hand">
<Image Source="{Binding ImagePrev, Mode=TwoWay}" Stretch="Fill"
Width="{Binding ElementName=Grid_p, Path=ActualWidth}" Height="{Binding ElementName=Grid_p, Path=ActualHeight}"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
Button添加Path
<Geometry x:Key="UpGeometry" PresentationOptions:Freeze="True">M......</Geometry>
<Style x:Key="PathBaseStyle" TargetType="{x:Type Path}">
<Setter Property="Stretch" Value="Uniform" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
<Style x:Key="UpPathStyle" BasedOn="{StaticResource PathBaseStyle}" TargetType="{x:Type Path}">
<Setter Property="Data" Value="{StaticResource UpGeometry}" />
</Style>
<Button HorizontalAlignment="Stretch" Command="{Binding PrevCommand}">
<Button.Template>
<ControlTemplate>
<Grid Cursor="Hand">
<Border CornerRadius="4">
<Path Margin="2" Fill="White" Style="{StaticResource UpPathStyle}"/>
</Border>
</Grid>
</Button.Template>
</Button>
Button与鼠标移动
<Button HorizontalAlignment="Stretch" Command="{Binding PrevCommand}">
<Button.Template>
<ControlTemplate>
<Grid x:Name="Grid_p" Opacity="0.5" Cursor="Hand">
<Border Width="100" Height="50" Background="{DynamicResource DarkOpacityBrush}" CornerRadius="4">
<Path Margin="2" Fill="White" Style="{StaticResource UpPathStyle}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Grid_p" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:.1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Grid_p" Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:.1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>