WPF制作时钟,依赖属性使用,有个奇怪的地方自己没理解

来源:互联网 发布:人过五十知天命感慨 编辑:程序博客网 时间:2024/04/27 07:36
前台布局,借鉴别人的,后台自己写的:
<Window x:Class="wpfClock.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:c="clr-namespace:wpfClock"
        Title="Window1" Height="400" Width="400">
    <Canvas Width="400" Height="400" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Ellipse  Canvas.Left="42" Canvas.Top="42" Width="316" Height="316" Fill="#FFD8D8D8"
                 Stroke="#FF838585" StrokeThickness="10"/>
        <!--表盘-->
        <Grid  Height="20" Width="280" Canvas.Left="60" Canvas.Top="190" RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7"/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition Width="7"/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="90"/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center"  />
            <TextBlock Grid.Column="1" FontSize="9"  Text="12"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Grid.Column="3" FontSize="9"  Text="6"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Rectangle Fill="#FF838585" Grid.Column="4"  Height="5" VerticalAlignment="Center"/>
        </Grid>
        <Grid  Height="20" Width="280" Canvas.Left="60" Canvas.Top="190" RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7"/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition Width="7"/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="60"/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="#FF838585" Grid.Column="0" Height="5" VerticalAlignment="Center"/>
            <TextBlock Grid.Column="1" FontSize="9"  Text="11"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Grid.Column="3" FontSize="9"  Text="5"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Rectangle Fill="#FF838585" Grid.Column="4" Height="5" VerticalAlignment="Center"/>
        </Grid>
        <Grid  Height="20" Width="280" Canvas.Left="60" Canvas.Top="190" RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7"/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition Width="7"/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="0"/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="0"/>
            <TextBlock Grid.Column="1" FontSize="9"  Text="9"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Grid.Column="3" FontSize="9"  Text="3"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="4"/>
        </Grid>
        <Grid  Height="20" Width="280" Canvas.Left="60" Canvas.Top="190" RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7"/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition Width="7"/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="30"/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="0"/>
            <TextBlock Grid.Column="1" FontSize="9"  Text="10"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Grid.Column="3" FontSize="9"  Text="4"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="-90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="4"/>
        </Grid>
        <Grid  Height="20" Width="280" Canvas.Left="60" Canvas.Top="190" RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7"/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition Width="7"/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="-30"/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="0"/>
            <TextBlock Grid.Column="1" FontSize="9"  Text="8"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Grid.Column="3" FontSize="9"  Text="2"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="4"/>
        </Grid>
        <Grid  Height="20" Width="280" Canvas.Left="60" Canvas.Top="190" RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7"/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="15"/>
                <ColumnDefinition Width="7"/>
            </Grid.ColumnDefinitions>
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="-60"/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="0"/>
            <TextBlock Grid.Column="1" FontSize="9"  Text="7"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <TextBlock Grid.Column="3" FontSize="9"  Text="1"  AllowDrop="False"  VerticalAlignment="Center"                          TextAlignment="Center"  RenderTransformOrigin="0.5,0.5"  >
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="90"/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
            <Rectangle Fill="#FF838585" Height="5" VerticalAlignment="Center" Grid.Column="4"/>
        </Grid>
        <!--基座-->
        <Ellipse Width="20" Height="20" Fill="Black" Canvas.Top="190" Canvas.Left="190" />
        <!--表针-->
        <Grid x:Name="hourGrid" Canvas.Left="200" Canvas.Top="198" Height="6" Width="80" Background="Black"
              RenderTransformOrigin="0,0.5">
            <Grid.RenderTransform>
                <RotateTransform  Angle="{Binding Path=Hour}"/>
                <!--<RotateTransform  Angle="{Binding Hour,Source={StaticResource DateTime2Angle},Mode=TwoWay}"/>-->
            </Grid.RenderTransform>
        </Grid>
        <Grid x:Name="MinuteGrid" Canvas.Left="200" Canvas.Top="198" Height="4" Width="100" Background="Black"  
              RenderTransformOrigin="0,0.5">
            <Grid.RenderTransform>
                <RotateTransform Angle="{Binding Path=Minute}"/>
                <!--<RotateTransform  Angle="{Binding Minute,Source={StaticResource DateTime2Angle},Mode=TwoWay}"/>-->
            </Grid.RenderTransform>
        </Grid>
        <Grid x:Name="secondGrid" Canvas.Left="241" Canvas.Top="271" Height="2" Width="145"                     
              Background="Black" RenderTransformOrigin="0.2,0.5"  >
            <Grid.RenderTransform>
                <TransformGroup>
                    <RotateTransform  Angle="{Binding Path=Second}"/>
                    <!--<RotateTransform  Angle="{Binding Second,Source={StaticResource DateTime2Angle},Mode=TwoWay}"/>上面那段绑定换成这段时间就不走,很奇怪,求解释-->
                    <TranslateTransform X="-68.36" Y="-71.62"/>
                </TransformGroup>
            </Grid.RenderTransform>
        </Grid>
    </Canvas>
</Window>

后台:
创建依赖属性类:
 class DateTime2Angle : DependencyObject
    {
       public double Hour
        {
            get { return (double)GetValue(HourProperty); }
            set
            {
                SetValue(HourProperty, value);
               
            }
        }

        // Using a DependencyProperty as the backing store for Hour.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HourProperty =
            DependencyProperty.Register("Hour", typeof(double), typeof(DateTime2Angle));


        public double Minute
        {
            get { return (double)GetValue(MinuteProperty); }
            set { SetValue(MinuteProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Minute.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinuteProperty =
            DependencyProperty.Register("Minute", typeof(double), typeof(DateTime2Angle));



        public double Second
        {
            get { return (double)GetValue(SecondProperty); }
            set { SetValue(SecondProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Second.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SecondProperty =
            DependencyProperty.Register("Second", typeof(double), typeof(DateTime2Angle));

    }
在App.xmal中引用
<Application x:Class="wpfClock.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:date2Angle="clr-namespace:wpfClock"//添加命名空间
             StartupUri="Window1.xaml">
    <Application.Resources>
        <date2Angle:DateTime2Angle x:Key="DateTime2Angle"></date2Angle:DateTime2Angle>
    </Application.Resources>
</Application>

/// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Window1 : Window
    {
        private Timer _timer;
        private DateTime2Angle date = new DateTime2Angle();
        public Window1()
        {
            InitializeComponent();
            initTime();
            this.DataContext = date;//不加这段时钟也没法走,求解释
        }

        public void initTime()
        {
            _timer = new Timer(1000);
            _timer.Elapsed += _timer_Elapsed;
            _timer.Start();

        }

        void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            double angle = 0d;
            var vhour = DateTime.Now.Hour;

            var vsecond = DateTime.Now.Second;
            angle = 270 + vsecond * 6;// 秒针 一秒钟转6度
            angle = angle > 360 ? angle - 360 : angle;
            this.Dispatcher.Invoke(new Action(delegate
            {
                date.Second = angle;
                         }));
            var vminute = DateTime.Now.Minute;

            angle = 270 + vminute * 6;// 分针 一分钟转6度
            angle = angle > 360 ? angle - 360 : angle;
//date.Minute = angle;不能直接赋值,会报错:调用线程无法访问此对象,因为另一个线程拥有该对象,需使用委托然后赋值,如下:

            this.Dispatcher.Invoke(new Action(delegate
            {
                date.Minute = angle;
                          }));


            vhour = vhour > 12 ? vhour - 12 : vhour; //12小时制
            angle = 270 + vhour * 30;// 时针 1小时转30度
            angle = angle > 360 ? angle - 360 : angle;
            //时针角度与分针也有关系,整点角度+分针偏移


            this.Dispatcher.Invoke(new Action(delegate
            {
                date.Hour = angle + vminute / 10 * 5;
                         }));

        }

        ~Window1()
        {
            _timer.Stop();
            _timer.Dispose();
        }
    }
运行结果:

0 0
原创粉丝点击