📄 alarmclockcontrol.cs
字号:
#region Using directives
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
#endregion
namespace AlarmClockControlLibrary {
[ToolboxBitmap(typeof(AlarmClockControl), "AlarmClockControl.ico")]
//[ToolboxBitmap(typeof(AlarmClockControl), "AlarmClockControl.bmp")]
[DefaultEvent("AlarmSounded")]
[DefaultProperty("ShowDigitalTime")]
[ProvideProperty("TimeZoneModifier", typeof(PictureBox))]
public partial class AlarmClockControl : ScrollableControl, ISupportInitialize, ISupportInitializeNotification, IExtenderProvider {
DateTime primaryAlarm = DateTime.Now;
bool primaryAlarmSet = false;
DateTime backupAlarm = DateTime.Now.AddMinutes(15);
bool backupAlarmSet = false;
Collection<MessageToSelf> messagesToSelf = new Collection<MessageToSelf>();
bool initializing = false;
ClockFace face = ClockFace.Both;
private Hand hourHand = new Hand(Color.Black, 1);
private Hand minuteHand = new Hand(Color.Black, 1);
private Hand secondHand = new Hand(Color.Red, 1);
string digitalTimeFormat = "dd/MM/yyyy hh:mm:ss tt";
// Mapping of components to numeric timezone offsets
Hashtable timeZoneModifiers = new Hashtable();
int timeZoneModifier = 0;
public AlarmClockControl() {
InitializeComponent();
this.DoubleBuffered = true;
this.PaddingChanged += this.alarmClockControl_PaddingChanged;
}
#region ISupportInitializeNotification Members
public event EventHandler Initialized;
// Must not be visible at design-time
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsInitialized {
get { return !this.initializing; }
}
#endregion
#region ISupportInitialize
public void BeginInit() { this.initializing = true; }
public void EndInit() {
if( !this.DesignMode ) {
// Check alarm values
if( primaryAlarm >= backupAlarm )
throw new ArgumentOutOfRangeException("Primary alarm must be before Backup alarm");
//Initialize timer
timer.Interval = 1000;
timer.Tick += this.timer_Tick;
timer.Enabled = true;
}
this.initializing = false;
// Notify dependent design-time components
if( this.Initialized != null ) {
this.Initialized(this, EventArgs.Empty);
}
}
#endregion
#region IExtenderProvider
public bool CanExtend(object extendee) {
// Don't extend self
if( extendee == this ) return false;
// Extend suitable controls
return ((extendee is PictureBox) ||
(extendee is Panel));
}
#endregion
#region Mouse input handling
// Track whether mouse button is down
private bool mouseDown = false;
protected override void OnMouseDown(MouseEventArgs e) {
if( this.DesignMode ) return;
mouseDown = true;
SetForeColor(e);
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e) {
if( this.DesignMode ) return;
if( mouseDown ) SetForeColor(e);
base.OnMouseMove(e);
}
protected override void OnMouseUp(MouseEventArgs e) {
if( this.DesignMode ) return;
SetForeColor(e);
mouseDown = false;
base.OnMouseUp(e);
}
private void SetForeColor(MouseEventArgs e) {
if( (e.Button & MouseButtons.Left) == MouseButtons.Left ) {
int red = (e.X * 255 / (this.ClientRectangle.Width - e.X)) % 256;
if( red < 0 ) red = -red;
int green = 0;
int blue = (e.Y * 255 / (this.ClientRectangle.Height - e.Y)) % 256;
if( blue < 0 ) blue = -blue;
this.ForeColor = Color.FromArgb(red, green, blue);
}
}
#endregion
#region Keyboard input handling
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e) {
// Specify the arrow keys as input chars
switch( e.KeyData ) {
case Keys.Up:
case Keys.Left:
case Keys.Down:
case Keys.Right:
e.IsInputKey = true;
return;
}
// The rest can be determined by the base class
base.OnPreviewKeyDown(e);
}
protected override void OnKeyDown(KeyEventArgs e) {
Point location = new Point(this.Left, this.Top);
switch( e.KeyCode ) {
case Keys.I:
case Keys.Up:
--location.Y;
break;
case Keys.J:
case Keys.Left:
--location.X;
break;
case Keys.K:
case Keys.Down:
++location.Y;
break;
case Keys.L:
case Keys.Right:
++location.X;
break;
}
this.Location = location;
base.OnKeyDown(e);
}
//protected override bool IsInputKey(Keys keyData) {
// // Make sure we get arrow keys
// switch( keyData ) {
// case Keys.Up:
// case Keys.Left:
// case Keys.Down:
// case Keys.Right:
// return true;
// }
// // The rest can be determined by the base class
// return base.IsInputKey(keyData);
//}
#endregion
[Category("Behavior")]
[Description("Primary alarm for late risers.")]
public DateTime PrimaryAlarm {
get { return this.primaryAlarm; }
set {
if( !this.initializing ) {
if( value >= this.backupAlarm ) {
throw new ArgumentOutOfRangeException("Primary alarm must be before Backup alarm");
}
}
this.primaryAlarm = value;
this.primaryAlarmSet = true;
// Fire AlarmChanged event
if( this.AlarmChanged != null ) {
this.AlarmChanged(this, new AlarmChangedEventArgs(value));
}
this.Invalidate();
}
}
[Category("Behavior")]
[Description("Backup alarm for very very late risers.")]
public DateTime BackupAlarm {
get { return this.backupAlarm; }
set {
if( !this.initializing ) {
if( value < this.primaryAlarm ) {
throw new ArgumentOutOfRangeException("Backup alarm must be after Primary alarm");
}
}
this.backupAlarm = value;
this.backupAlarmSet = true;
// Fire AlarmChanged event
if( this.AlarmChanged != null ) {
this.AlarmChanged(this, new AlarmChangedEventArgs(value));
}
this.Invalidate();
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsPrimaryAlarmSet {
get { return this.primaryAlarmSet; }
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsBackupAlarmSet {
get { return this.backupAlarmSet; }
}
[Category("Behavior")]
[Description("Stuff to remember for later.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<MessageToSelf> MessagesToSelf {
get {
if( this.messagesToSelf == null ) {
this.messagesToSelf = new Collection<MessageToSelf>();
}
return this.messagesToSelf;
}
set { this.messagesToSelf = value; }
}
[Category("Behavior")]
[Description("Sets the timezone difference from the current time.")]
[DefaultValue(0)]
[DisplayName("TimeZoneModifier")]
public int GetTimeZoneModifier(Control extendee) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -