我想知道是否可以使用动画(没有背景代码标签)在xaml中创建数字时钟
可以通过矩阵转换将当前时间转换为角度来实现模拟时钟,但是数字时钟不能像这样操作。我尝试了很多方法,但是没有用。有人知道是否有实现它的好方法吗?
模拟时钟实现
<Window>
<Window.Resources>
<FrameworkElement x:Key="time" Tag={x:Static s:DateTime.Now}/>
<TransformGroup x:Key="transformHour">
<TranslateTransform X="{Binding Source={StaticResource time},Path=Tag.Hour}"
Y="{Binding Source={StaticResource time},Path=Tag.Minute}"/>
<MatrixTransform Matrix="30 0 0.5 0 0 0"/>
</TransformGroup>
<TransformGroup x:Key="transformMinute">
<TranslateTransform X="{Binding Source={StaticResource time},Path=Tag.Minute}"
Y="{Binding Source={StaticResource time},Path=Tag.Second}"/>
<MatrixTransform Matrix="6 0 0.1 0 0 0"/>
</TransformGroup>
<TransformGroup x:Key="transformSecond">
<TranslateTransform X="{Binding Source={StaticResource time},Path=Tag.Second}"/>
<MatrixTransform Matrix="6 0 0 0 0 0"/>
</TransformGroup>
<Style TargetType="{x:Type Path}">
<Setter Property="Stroke"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="StrokeThickness" Value="3"/>
<Setter Property="StrokeDashCap" Value="Triangle"/>
</Style>
</Window.Resources>
<Viewbox>
<Canvas Width="200" Height="200">
<Canvas.RenderTransform>
<TranslateTransform X="100" Y="100"/>
</Canvas.RenderTransform>
<Path Data="M 0 -90 A 90 90 0 1 1 -0.01 -90"
StrokeDashArray="0 3.14157" />
<Path Data="M 0 -90 A 90 90 0 1 1 -0.01 -90"
StrokeDashArray="0 7.854"
StrokeThickness="6"/>
<Border Background="LightBlue" Width="10" Height="80" RenderTransformOrigin="0.5 0">
<Border.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="bor_Second" Angle="{Binding Source={StaticResource transformSecond},Path=Value.OffsetX}"/>
<RotateTransform Angle="180"/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border Background="LightGreen" Width="10" Height="60" RenderTransformOrigin="0.5 0">
<Border.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="bor_Minute" Angle="{Binding Source={StaticResource transformMinute},Path=Value.OffsetX}"/>
<RotateTransform Angle="180"/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border Background="LightGray" Width="10" Height="40" RenderTransformOrigin="0.5 0">
<Border.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="bor_Hour" Angle="{Binding Source={StaticResource transformHour},Path=Value.OffsetX}"/>
<RotateTransform Angle="180"/>
</TransformGroup>
</Border.RenderTransform>
</Border>
</Canvas>
</Viewbox>
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="bor_Hour"
Storyboard.TargetProperty="Angle"
IsAdditive="True"
Duration="12:0:0"
From="0" To="360"
RepeatBehavior="Forever"/>
<DoubleAnimation Storyboard.TargetName="bor_Minute"
Storyboard.TargetProperty="Angle"
IsAdditive="True"
Duration="1:0:0"
From="0" To="360"
RepeatBehavior="Forever"/>
<DoubleAnimation Storyboard.TargetName="bor_Second"
Storyboard.TargetProperty="Angle"
IsAdditive="True"
Duration="0:1:0"
From="0" To="360"
RepeatBehavior="Forever"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
</Window>
数字时钟(有错误),我觉得使用这个想法比较麻烦。有人知道是否有实现它的好方法吗?
<Window>
<Window.Resources>
<!--current time-->
<FrameworkElement x:Key="time" Tag="{x:Static s:DateTime.Now}"/>
<!--Current minutes remaining seconds-->
<TransformGroup x:Key="transformSecond">
<TranslateTransform X="{Binding Source={StaticResource time},Path=Tag.Second}" Y="60"/>
<MatrixTransform Matrix="-1 0 1 0 0 0"/>
</TransformGroup>
<!--Remaining seconds interval-->
<FrameworkElement x:Key="timeSpanSecond"
Tag="{Binding Source={StaticResource transformSecond},Path=Value.OffsetX,StringFormat={}{0:F0}}"/>
<!--Current hours remaining minutes-->
<TransformGroup x:Key="transformMinute">
<TranslateTransform X="{Binding Source={StaticResource time},Path=Tag.Minute}" Y="60"/>
<MatrixTransform Matrix="-1 1 1 0 0 1"/>
</TransformGroup>
<!--Remaining minute interval-->
<FrameworkElement x:Key="timeSpanMinute"
Tag="{Binding Source={StaticResource transformMinute},Path=Value.OffsetX,StringFormat={}{0:F0}}"/>
<!--Next minute-->
<FrameworkElement x:Key="minuteNext"
Tag="{Binding Source={StaticResource transformMinute},Path=Value.OffsetY}"/>
<!--Hours remaining on the day-->
<TransformGroup x:Key="transformHour">
<TranslateTransform X="{Binding Source={StaticResource time},Path=Tag.Hour}" Y="24"/>
<MatrixTransform Matrix="-1 1 1 0 0 1"/>
</TransformGroup>
<!--Remaining hours interval-->
<FrameworkElement x:Key="timeSpanHour"
Tag="{Binding Source={StaticResource transformHour},Path=Value.OffsetX,StringFormat={}{0:F0}}"/>
<!--Next hour-->
<FrameworkElement x:Key="hourNext"
Tag="{Binding Source={StaticResource transformHour},Path=Value.OffsetY}"/>
</Window.Resources>
<Grid>
<!--Width:Current seconds-->
<!--Text:Current remaining seconds(TimeSpan)-->
<TextBlock x:Name="tbk_Second" Visibility="Hidden"
Width="{Binding Source={StaticResource time},Path=Tag.Second}"
Text="{Binding Source={StaticResource timeSpanSecond},StringFormat=0:0:{0},Path=Tag}"/>
<TextBlock x:Name="tbk_Minute" Visibility="Hidden"
Width="{Binding Source={StaticResource time},Path=Tag.Minute}"
Text="{Binding Source={StaticResource timeSpanMinute},StringFormat=0:{0}:0,Path=Tag}">
</TextBlock>
<TextBlock x:Name="tbk_Hour" Visibility="Hidden"
Width="{Binding Source={StaticResource time},Path=Tag.Hour}"
Text="{Binding Source={StaticResource timeSpanHour},StringFormat={}{0}:0:0,Path=Tag}"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">
<Run Text="{Binding ElementName=tbk_Hour,Path=Width,StringFormat={}{0:F0}}"/>
<Run Text=":"/>
<Run Text="{Binding ElementName=tbk_Minute,Path=Width,StringFormat={}{0:F0}}"/>
<Run Text=":"/>
<Run Text="{Binding ElementName=tbk_Second,Path=Width,StringFormat={}{0:F0}}"/>
</TextBlock>
</Grid>
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="tbk_Hour"
Storyboard.TargetProperty="Width"
BeginTime="{Binding ElementName=tbk_Minute,Path=Text}"
Duration="{Binding ElementName=tbk_Hour,Path=Text}"
From="{Binding Source={StaticResource hourNext},Path=Tag}"
To="23"/>
<DoubleAnimation Storyboard.TargetName="tbk_Hour"
Storyboard.TargetProperty="Width"
BeginTime="{Binding ElementName=tbk_Hour,Path=Text}"
Duration="24:0:0"
From="0"
To="23"
RepeatBehavior="Forever"/>
<DoubleAnimation Storyboard.TargetName="tbk_Minute"
Storyboard.TargetProperty="Width"
BeginTime="{Binding ElementName=tbk_Second,Path=Text}"
Duration="{Binding ElementName=tbk_Minute,Path=Text}"
From="{Binding Source={StaticResource minuteNext},Path=Tag}"
To="59"/>
<DoubleAnimation Storyboard.TargetName="tbk_Minute"
Storyboard.TargetProperty="Width"
BeginTime="{Binding ElementName=tbk_Minute,Path=Text}"
Duration="1:0:0"
From="0"
To="59"
RepeatBehavior="Forever"/>
<DoubleAnimation
Storyboard.TargetName="tbk_Second"
Storyboard.TargetProperty="Width"
Duration="{Binding ElementName=tbk_Second,Path=Text}"
From="{Binding Source={StaticResource time},Path=Tag.Second}"
To="59"
/>
<DoubleAnimation Storyboard.TargetName="tbk_Second"
Storyboard.TargetProperty="Width"
BeginTime="{Binding ElementName=tbk_Second,Path=Text}"
Duration="0:1:0"
From="0"
To="59"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
</Window>
答案 0 :(得分:0)
也许这是您想要的答案:)
<Window x:Class="WpfApp6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<Grid>
<Grid.Resources>
<!--Set x: share to get the latest every time-->
<system:DateTime x:Key="DateTime"
x:Shared="False" />
<Storyboard x:Key="Storyboard">
<!--Use keyframe animation to update datetime -->
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="DataContext"
Duration="0:0:1"
RepeatBehavior="Forever"
AutoReverse="False">
<DiscreteObjectKeyFrame KeyTime="50%"
Value="{StaticResource DateTime}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<!--Get datetime from DataContext-->
<TextBlock Text="{Binding RelativeSource={RelativeSource Self},Path=DataContext.Now}"
DataContext="{StaticResource DateTime}">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard}" />
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Grid>
</Window>
答案 1 :(得分:-1)
我建议您基于文本块和类似这样的合适字体来做到这一点:
https://www.keshikan.net/fonts-e.html
您的文本块绑定到可以由调用'DateTime.Now();'的异步函数设置的属性。 这是一个XAML示例:
<Border HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,40" Background="DarkGray" BorderThickness="1,1,0,0" BorderBrush="Gray">
<Grid>
<!-- Displays the actual time in red-->
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Opacity="0.6" Foreground="Red" FontSize="20" Text="{Binding Hour, FallbackValue=00, StringFormat=00}" FontFamily="DSEG7 Classic Mini" ></TextBlock>
<TextBlock Opacity="0.6" Foreground="Red" FontSize="20" FontFamily="DSEG7 Classic Mini" >:</TextBlock>
<TextBlock Opacity="0.6" Foreground="Red" FontSize="20" Text="{Binding Min, FallbackValue=00, StringFormat=00}" FontFamily="DSEG7 Classic Mini" ></TextBlock>
<TextBlock Opacity="0.6" Foreground="Red" FontSize="20" FontFamily="DSEG7 Classic Mini">:</TextBlock>
<TextBlock Opacity="0.6" Foreground="Red" FontSize="20" Text="{Binding Sec, FallbackValue=00, StringFormat=00}" FontFamily="DSEG7 Classic Mini" ></TextBlock>
</StackPanel>
<!-- Creates a Glow Effect -->
<StackPanel Orientation="Horizontal" Margin="2">
<StackPanel.Effect>
<BlurEffect KernelType="Gaussian" Radius="3"/>
</StackPanel.Effect>
<TextBlock Foreground="Red" FontSize="20" Text="{Binding Hour, FallbackValue=00, StringFormat=00}" FontFamily="DSEG7 Classic Mini" ></TextBlock>
<TextBlock Foreground="Red" FontSize="20" FontFamily="DSEG7 Classic Mini" >:</TextBlock>
<TextBlock Foreground="Red" FontSize="20" Text="{Binding Min, FallbackValue=00, StringFormat=00}" FontFamily="DSEG7 Classic Mini" ></TextBlock>
<TextBlock Foreground="Red" FontSize="20" FontFamily="DSEG7 Classic Mini">:</TextBlock>
<TextBlock Foreground="Red" FontSize="20" Text="{Binding Sec, FallbackValue=00, StringFormat=00}" FontFamily="DSEG7 Classic Mini" ></TextBlock>
</StackPanel>
<!-- Creates the effect of turned of segments -->
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Opacity="0.1" FontSize="20" Text="88" FontFamily="DSEG7 Classic Mini" ></TextBlock>
<TextBlock Opacity="0.1" FontSize="20" FontFamily="DSEG7 Classic Mini" >:</TextBlock>
<TextBlock Opacity="0.1" FontSize="20" Text="88" FontFamily="DSEG7 Classic Mini" ></TextBlock>
<TextBlock Opacity="0.1" FontSize="20" FontFamily="DSEG7 Classic Mini">:</TextBlock>
<TextBlock Opacity="0.1" FontSize="20" Text="88" FontFamily="DSEG7 Classic Mini" ></TextBlock>
</StackPanel>
</Grid>
</Border>
仅使用一个文本块和一个字符串格式会更加容易,但是这个示例我已经在::