WPF学习————制作时钟

话不多说,这个实例非常适合入门者。主要的东西是路径Path。然后是RenderTransfer和数据绑定。不熟悉的请先阅读相关知识,也可以根据实例来一边实践一边学习。

先上效果:

整体结构如下:

窗体设置: 

Height="450" Width="450" ResizeMode="NoResize" WindowStyle="None"

xaml层次:

 <Border Background="LightCyan">
        <Grid>
            <Ellipse Stroke="Black" StrokeThickness="10" Margin="10"></Ellipse>
            <Ellipse Stroke="Gray" StrokeThickness="1" Width="350" Height="350"></Ellipse>
            <Ellipse Stroke="Gray" StrokeThickness="1" Width="380" Height="380"></Ellipse>
            <Ellipse  StrokeThickness="5" Fill="White" Width="20" Height="20" Stroke="Black" ></Ellipse>

            <TextBlock Text="12" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="205" Y="50"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="1" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="290" Y="80"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="2" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="340" Y="130"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="3" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="370" Y="200"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="4" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="350" Y="280"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="5" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="300" Y="340"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="6" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="215" Y="360"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="8" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="80" Y="280"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="7" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="140" Y="340"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="9" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="60" Y="205"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="11" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="140" Y="80"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="10" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="85" Y="130"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="0" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="90" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="180" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="270" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="30" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="60" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="120" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="150" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="210" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="240" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>

            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="300" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="330" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Yellow" StrokeThickness="1" Name="seconds">
                <Path.RenderTransform>
                    <RotateTransform CenterX="225" CenterY="225" Angle="{Binding clockTimeData.second_indicate,  UpdateSourceTrigger=PropertyChanged}">
                        
                    </RotateTransform>
                </Path.RenderTransform>
                <Path.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF2BE60E" Offset="0.3"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Path.Fill>
                <Path.Data>
                    <PathGeometry Figures="M 225,60 220,200 225,225 225,250  225,225  230,200 z">
                    </PathGeometry>
                </Path.Data>
                <!--<Path.Triggers>
                    <EventTrigger RoutedEvent="Loaded">
                        --><!--<BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation 
                                    Storyboard.TargetName="seconds"
                                    Storyboard.TargetProperty="RenderTransform.Angle"
                                    Duration="00:01:00" From="0" To="360" By="6" RepeatBehavior="Forever"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>--><!--
                    </EventTrigger>
                </Path.Triggers>-->

            </Path>
            <Path  Stroke="Black" StrokeThickness="2">
                <Path.RenderTransform>
                    <RotateTransform CenterX="225" CenterY="225" Angle="{Binding clockTimeData.minius_indicate,  UpdateSourceTrigger=PropertyChanged}">

                    </RotateTransform>
                </Path.RenderTransform>
                <Path.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF157AF3" Offset="0.3"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Path.Fill>
                <Path.Data>
                    <PathGeometry Figures="M 225,80 215,200 225,225 225,250  225,225  235,200 z">

                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="2">
                <Path.RenderTransform>
                    <RotateTransform CenterX="225" CenterY="225" Angle="{Binding clockTimeData.hours_indicate,  UpdateSourceTrigger=PropertyChanged}">

                    </RotateTransform>
                </Path.RenderTransform>
                <Path.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFE233AA" Offset="0.3"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Path.Fill>
                <Path.Data>
                    <PathGeometry Figures="M 225,120 200,200 225,225 225,250  225,225  250,200 z">

                    </PathGeometry>
                </Path.Data>
            </Path>

        </Grid>
    </Border>
View Code

 

1:先设计静态的东西。时钟的面板上的,最外面的大黑圆。数值对应的分度圆。

<Ellipse Stroke="Black" StrokeThickness="10" Margin="10"></Ellipse>
<Ellipse Stroke="Gray" StrokeThickness="1" Width="350" Height="350"></Ellipse>
<Ellipse Stroke="Gray" StrokeThickness="1" Width="380" Height="380"></Ellipse>
<Ellipse StrokeThickness="5" Fill="White" Width="20" Height="20" Stroke="Black" ></Ellipse>
View Code

 

2:设计数字,并安排到合适的位置,注意数值对应的黑点也是Path。

 <TextBlock Text="12" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="205" Y="50"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="1" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="290" Y="80"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="2" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="340" Y="130"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="3" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="370" Y="200"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="4" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="350" Y="280"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="5" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="300" Y="340"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="6" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="215" Y="360"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="8" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="80" Y="280"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="7" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="140" Y="340"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="9" FontSize="35" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="60" Y="205"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="11" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="140" Y="80"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Text="10" FontSize="25" >
                <TextBlock.RenderTransform>
                    <TranslateTransform X="85" Y="130"></TranslateTransform>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="0" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="90" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="180" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="3">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="270" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="30" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="60" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="120" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="150" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="210" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="240" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>

            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="300" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="1">
                <Path.Data>
                    <PathGeometry Figures="M 225,35 225,50">
                        <PathGeometry.Transform>
                            <RotateTransform Angle="330" CenterX="225" CenterY="225"></RotateTransform>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </Path.Data>
            </Path>
View Code

 

3:用Path设计好时针,分针,秒针的形状,并加入渐变效果。

  <Path  Stroke="Yellow" StrokeThickness="1" Name="seconds">
                <Path.RenderTransform>
                    <RotateTransform CenterX="225" CenterY="225" Angle="{Binding clockTimeData.second_indicate,  UpdateSourceTrigger=PropertyChanged}">
                        
                    </RotateTransform>
                </Path.RenderTransform>
                <Path.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF2BE60E" Offset="0.3"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Path.Fill>
                <Path.Data>
                    <PathGeometry Figures="M 225,60 220,200 225,225 225,250  225,225  230,200 z">
                    </PathGeometry>
                </Path.Data>
                <!--<Path.Triggers>
                    <EventTrigger RoutedEvent="Loaded">
                        --><!--<BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation 
                                    Storyboard.TargetName="seconds"
                                    Storyboard.TargetProperty="RenderTransform.Angle"
                                    Duration="00:01:00" From="0" To="360" By="6" RepeatBehavior="Forever"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>--><!--
                    </EventTrigger>
                </Path.Triggers>-->

            </Path>
            <Path  Stroke="Black" StrokeThickness="2">
                <Path.RenderTransform>
                    <RotateTransform CenterX="225" CenterY="225" Angle="{Binding clockTimeData.minius_indicate,  UpdateSourceTrigger=PropertyChanged}">

                    </RotateTransform>
                </Path.RenderTransform>
                <Path.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF157AF3" Offset="0.3"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Path.Fill>
                <Path.Data>
                    <PathGeometry Figures="M 225,80 215,200 225,225 225,250  225,225  235,200 z">

                    </PathGeometry>
                </Path.Data>
            </Path>
            <Path  Stroke="Black" StrokeThickness="2">
                <Path.RenderTransform>
                    <RotateTransform CenterX="225" CenterY="225" Angle="{Binding clockTimeData.hours_indicate,  UpdateSourceTrigger=PropertyChanged}">

                    </RotateTransform>
                </Path.RenderTransform>
                <Path.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFE233AA" Offset="0.3"/>
                        <GradientStop Color="White" Offset="1"/>
                    </LinearGradientBrush>
                </Path.Fill>
                <Path.Data>
                    <PathGeometry Figures="M 225,120 200,200 225,225 225,250  225,225  250,200 z">

                    </PathGeometry>
                </Path.Data>
            </Path>
View Code

 

4:建立时分秒对应的数据,并开notifypropertychange。

 public class ClockTimeData:NotifyPropertyChange
    {


        public ClockTimeData()
        {
           

        }



        double _second_indicate;
        public double second_indicate
        {
            set
            {
                _second_indicate = value;
                RaisePropertyChanged(nameof(second_indicate));
            }
            get
            {
                return _second_indicate;
            }

        }




        double _minius_indicate;
        public double minius_indicate
        {
            set
            {
                _minius_indicate = value;
                RaisePropertyChanged(nameof(minius_indicate));
            }
            get
            {
                return _minius_indicate;
            }

        }
        public double hours_indicate
        {
            set;
            get;
        }
    }
View Code

 

5:建立ViewModel.搭建数据和UI的关联逻辑。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WPFClock.Modles;
using MVVMLibrary.MVVMCommon;
using MVVMLibrary.MVVMBase;

namespace WPFClock.ViewModles
{
   public class ClolcTimeVM:ViewModelBase
    {

        public ClockTimeData clockTimeData
        {
            set;
            get;
        }

        Action Updateindicate;

        public ClolcTimeVM()
        {
            clockTimeData = new ClockTimeData();
            Updateindicate += Updateindicatefun;
            Updateindicate.BeginInvoke(
                ar=>Updateindicate.EndInvoke(ar)
                ,null);
        }

        private void Updateindicatefun()
        {
           while(true)
            {
                clockTimeData.second_indicate = DateTime.Now.Second*6.0;
                clockTimeData.minius_indicate = DateTime.Now.Minute * 6.0+ DateTime.Now.Second/60.0*6;
                double hour = DateTime.Now.Hour > 12 ? (DateTime.Now.Hour - 12) : DateTime.Now.Hour;
                 clockTimeData.hours_indicate = hour * 30.0+ DateTime.Now.Minute / 60.0*30;
                Thread.Sleep(200);
            }
        }
    }
}
View Code

 

6:将UI的datacontex设置到ViewModel.

 <Window.DataContext>
        <vm:ClolcTimeVM></vm:ClolcTimeVM>
    </Window.DataContext>
View Code

 

7:运行后,时针,分针,秒针将根据当前的计算机时间来布置和运动。

 clockTimeData.second_indicate = DateTime.Now.Second*6.0;
                clockTimeData.minius_indicate = DateTime.Now.Minute * 6.0+ DateTime.Now.Second/60.0*6;
                double hour = DateTime.Now.Hour > 12 ? (DateTime.Now.Hour - 12) : DateTime.Now.Hour;
                 clockTimeData.hours_indicate = hour * 30.0+ DateTime.Now.Minute / 60.0*30;
View Code

 

posted on 2021-09-10 08:07  半路敲代码  阅读(354)  评论(0编辑  收藏  举报

导航