C#时钟不工作,因为wpf中没有负坐标

时间:2017-03-04 18:58:04

标签: c# wpf

我试图制作一个简单的时钟而且它不起作用,因为sin和cos给出的值是wpf没有的值!

namespace Desenho
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        [DllImport("Kernel32")]
        public static extern void AllocConsole();

    [DllImport("Kernel32")]
    public static extern void FreeConsole();

    private Timer timer1;
    int i = 0;

    public MainWindow()
    {
        InitializeComponent();
        AllocConsole();
        Console.Clear();
        InitTimer();

    }

    public void InitTimer()
    {
        timer1 = new Timer();
        timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
        timer1.Interval = 1; // in miliseconds
        timer1.Start();
        /*for(int a = 0; a>-200; a--)
        {
            Console.WriteLine("Angulo: {0}; Cos: {1}; Sen: {2}; Rad: {3};", a, Math.Cos(toRad(a)), Math.Sin(toRad(a)), toRad(a));
        }*/
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        /*if(i == 5)
        {
            i = 0;
        }
        mudaCores(i);
        i++;*/
        float x = 100+(float)Math.Cos(toRad(i));
        float y = 100+(float)Math.Sin(toRad(i));
        desenhaLinha(x, y);
        i--;
        Console.WriteLine("Angulo: {0}; X: {1}; Y: {2};", i, x, y);
    }

    private async void desenhaLinha(float x, float y)
    {

            await Task.Run(() =>
            {
                    panel.Dispatcher.BeginInvoke((Action)(() => panel.linhas.Add(new Cordenadas(new Pen(new SolidColorBrush(Colors.Red), 2), new Point(100, 100), new Point(x, y)))));
                    panel.Dispatcher.BeginInvoke((Action)(() => panel.InvalidateVisual()));

            });

        }



    private async void mudaCores(int i)
    {
        Color[] cores = new Color[] { Colors.Red, Colors.Black, Colors.Blue, Colors.Green, Colors.Yellow, Colors.Violet };
        try
        {
            await Task.Run(() => { panel.Dispatcher.BeginInvoke((Action)(() => panel.color = cores[i]));
                panel.Dispatcher.BeginInvoke((Action)(() => panel.InvalidateVisual()));
            });
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    double toRad(double graus)
    {
        double rad;
        rad = graus * Math.PI / 180;
        return rad;
    }
}

}

我的drawLine函数只需要一个点作为参数,因为它假设中心一个为100,100。我怎样才能使这个工作?

1 个答案:

答案 0 :(得分:2)

IMO你应该丢弃所有代码并编写MVVM应用程序,并在视图和视图模型之间进行分离。

首先为您的时钟创建一个视图模型,例如具有时钟的小时,分​​钟和秒针的三个角度属性,以及从UI线程中的当前时间(DateTime.Now)更新这些属性的DispatcherTimer。

public class ClockViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ClockViewModel()
    {
        var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
        timer.Tick += TimerTick;
        timer.Start();
    }

    private void TimerTick(object sender, EventArgs e)
    {
        var t = DateTime.Now.TimeOfDay;
        HoursAngle = t.TotalHours * 30 % 360; // fractional hours
        MinutesAngle = t.Minutes * 6; // full minutes
        SecondsAngle = t.Seconds * 6; // full seconds
    }

    private double hoursAngle;
    public double HoursAngle
    {
        get { return hoursAngle; }
        set
        {
            hoursAngle = value;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(HoursAngle)));
        }
    }

    private double minutesAngle;
    public double MinutesAngle
    {
        get { return minutesAngle; }
        set
        {
            minutesAngle = value;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(MinutesAngle)));
        }
    }

    private double secondsAngle;
    public double SecondsAngle
    {
        get { return secondsAngle; }
        set
        {
            secondsAngle = value;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(SecondsAngle)));
        }
    }
}

然后为时钟指针创建一个包含三行的视图,每个时钟指针都有RotateTransform,具有数据绑定Angle属性。下面显示的视图将时钟放在2xx网格右下角单元格的左上角,以便将网格中的线条居中。

Window的DataContext设置为视图模型的实例。

<Window.DataContext>
    <local:ClockViewModel/>
</Window.DataContext>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Canvas Grid.Column="1" Grid.Row="1">
        <Line Y2="-50"
              Stroke="Black" StrokeThickness="9"
              StrokeStartLineCap="Round" StrokeEndLineCap="Triangle">
            <Line.RenderTransform>
                <RotateTransform Angle="{Binding HoursAngle}"/>
            </Line.RenderTransform>
        </Line>
        <Line Y2="-100"
              Stroke="Gray" StrokeThickness="7"
              StrokeStartLineCap="Round" StrokeEndLineCap="Triangle">
            <Line.RenderTransform>
                <RotateTransform Angle="{Binding MinutesAngle}"/>
            </Line.RenderTransform>
        </Line>
        <Line Y2="-100"
              Stroke="Red" StrokeThickness="3"
              StrokeStartLineCap="Round" StrokeEndLineCap="Triangle">
            <Line.RenderTransform>
                <RotateTransform Angle="{Binding SecondsAngle}"/>
            </Line.RenderTransform>
        </Line>
    </Canvas>
</Grid>