我试图制作一个简单的时钟而且它不起作用,因为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。我怎样才能使这个工作?
答案 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>