I took the project "A Time-Of-Day Picker control" from ClearlyDotNet (http://www.codeproject.com/KB/miscctrl/timeframe.aspx), and with a very small effort (less than 1 hour
From the source project I've just added two properties for the lines colors (GridDarkColor, GridLightColor) ...

So this is the code for the TimeFrame:
- Code: Select all
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Globalization;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;
namespace AC.ExtendedRenderer.Toolkit
{
public class TimeFrame : System.Windows.Forms.UserControl
{
#region Component Designer generated code
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// TimeFrame
//
this.Name = "TimeFrame";
}
#endregion
#region Nested Classes
#region TimeToolTip
internal class TimeToolTip
{
public string Text;
}
#endregion
#region TimeFrameObject definition
internal class TimeFrameObject
{
public RectangleF Bounds;
private bool selected = false;
public bool Highlighted = false;
public virtual bool Selected
{
get
{
return selected;
}
set
{
selected = value;
}
}
public TimeFrameObject( RectangleF rec )
{
Bounds = rec;
}
public bool Contains( PointF p )
{
return this.Contains( p.X, p.Y );
}
public bool Contains( float x, float y )
{
return Bounds.Contains( x, y );
}
}
#endregion
#region _Day definition
internal class _Day : TimeFrameObject
{
public int Row;
public DayOfWeek DOW
{
get
{
return (DayOfWeek)Row;
}
set
{
Row = (int)value;
}
}
public _Day( int row ) : this( new RectangleF(0,0,0,0), row )
{
}
public _Day( RectangleF rec, int row ) : base( rec )
{
Row = row;
}
public override bool Selected
{
get
{
int ColCount = 0;
for( int j = 0; j < TimeFrame.s_NumTimeIntervals; ++j )
{
if( CellMatrix[ Row, j ].Selected )
{
++ColCount;
}
}
return( ColCount == TimeFrame.s_NumTimeIntervals );
}
set
{
for( int j = 0; j < s_NumTimeIntervals; ++j )
{
CellMatrix[ Row, j ].Selected = value;
}
}
}
}
#endregion
#region TimeSlot definition
internal class TimeSlot : TimeFrameObject
{
public int Column;
public TimeSlot( int col ) : this( col, new RectangleF(0,0,0,0) )
{
}
public TimeSlot( int col, RectangleF rec ) : base( rec )
{
Column = col;
}
public override bool Selected
{
get
{
int RowCount = 0;
for( int i = 0; i < TimeFrame.s_NumDays; ++i )
{
if( CellMatrix[ i, Column ].Selected )
{
++RowCount;
}
}
return( RowCount == TimeFrame.s_NumDays );
}
set
{
for( int i = 0; i < TimeFrame.s_NumDays; ++i )
{
CellMatrix[ i, Column ].Selected = value;
}
}
}
}
#endregion
#region Cell Definition
internal class Cell : TimeFrameObject
{
public int X;
public int Y;
public override string ToString()
{
return( "{" + X + ", " + Y + "}" );
}
public Cell( int x, int y ) : this( new RectangleF(0,0,0,0), x, y )
{
}
public Cell( RectangleF rec, int x, int y ) : base( rec )
{
X = x;
Y = y;
}
}
#endregion
#region TopLeftCell Definition
internal class TopLeftCell : TimeFrameObject
{
public TopLeftCell() : base( new RectangleF(0,0,0,0) )
{
}
public TopLeftCell( RectangleF rec ) : base( rec )
{
}
public override bool Selected
{
get
{
int Count = 0;
for( int i = 0; i < s_NumDays; ++i )
{
for( int j = 0; j < s_NumTimeIntervals; ++j )
{
if( CellMatrix[ i, j ].Selected )
{
++Count;
}
}
}
return( Count == ( s_NumDays * s_NumTimeIntervals ) );
}
set
{
for( int i = 0; i < s_NumDays; ++i )
{
for( int j = 0; j < s_NumTimeIntervals; ++j )
{
CellMatrix[ i, j ].Selected = value;
}
}
}
}
}
#endregion
#endregion
#region Constants
private const int c_ToolTipXPad = 12;
private const int c_LeftMargin = 20;
private const int c_RightMargin = 5;
private const int c_Header = 10;
private const int c_Footer = 10;
private const int c_NumDays = 7;
private const int c_NumTimeIntervals = 48;
private const int c_TimeDisplayInterval = 8;
private const int c_TimeGridVerticalInterval = 2;
#endregion
#region Statics
private static TimeSpan c_ts = new TimeSpan( 1,0,0,0,0 );
public static int s_NumDays = c_NumDays;
public static int s_NumTimeIntervals = c_NumTimeIntervals;
#endregion
#region Member Variables
private int m_LeftMargin = c_LeftMargin;
private int m_RightMargin = c_RightMargin;
private int m_Header = c_Header;
private int m_Footer = c_Footer;
private int m_NumDays = s_NumDays;
private int m_NumTimeIntervals = s_NumTimeIntervals;
private int m_TimeDisplayInterval = c_TimeDisplayInterval;
private int m_TimeGridVerticalInterval = c_TimeGridVerticalInterval;
internal static Cell[,] CellMatrix;
private Timer HoverTimerStart = new Timer();
private Timer HoverTimerStop = new Timer();
private MouseEventArgs LastMouseHover = null;
private _Day[] Days;
private TimeSlot[] TimeSlots;
private TopLeftCell TopLeft;
private RectangleF Grid;
private float x_grid_inc = 0.0F;
private float y_grid_inc = 0.0F;
private TimeToolTip ttInfo = null;
private TimeFrameObject tfoLastHighlighted = null;
private TimeFrameObject tfoLastSelected = null;
private SolidBrush m_sbBack = new SolidBrush( SystemColors.Control );
private SolidBrush m_sbGridBack = new SolidBrush( Color.White );
private SolidBrush m_sbInfoBack = new SolidBrush( SystemColors.Info );
private SolidBrush m_sbInfoText = new SolidBrush( SystemColors.InfoText );
private SolidBrush m_sbHotTrack = new SolidBrush( Color.Red );
private SolidBrush m_sbSelected = new SolidBrush( SystemColors.Highlight );
private SolidBrush m_sbForeColor = new SolidBrush( SystemColors.ControlText );
private SolidBrush m_sbGridDark = new SolidBrush(Color.Black);
private SolidBrush m_sbGridLight= new SolidBrush(Color.Gray);
#endregion
#region Properties
protected override Size DefaultSize
{
get
{
return new Size( 310, 160 );
}
}
public TimeSpan[][][] TimeFrames
{
get
{
ArrayList TimeSpanDays = new ArrayList();
long t_inc = c_ts.Ticks / (long)NumTimeIntervals;
TimeSpan tsi = new TimeSpan(t_inc);
for (int i = 0; i < NumDays; ++i)
{
ArrayList TimeSpansPerDay = new ArrayList();
TimeSpan[] ts = null;
bool bAdjacent = false;
for (int j = 0; j < NumTimeIntervals; ++j)
{
if (CellMatrix[i, j].Selected)
{
if (!bAdjacent)
{
ts = new TimeSpan[2];
ts[0] = new TimeSpan(j * t_inc);
bAdjacent = true;
}
}
else
{
if (bAdjacent)
{
ts[1] = new TimeSpan(j * t_inc);
TimeSpansPerDay.Add(ts);
}
bAdjacent = false;
}
}
if (bAdjacent)
{
ts[1] = new TimeSpan(NumTimeIntervals * t_inc);
TimeSpansPerDay.Add(ts);
}
TimeSpanDays.Add(TimeSpansPerDay);
}
TimeSpan[][][] all = new TimeSpan[TimeSpanDays.Count][][];
for (int i = 0; i < TimeSpanDays.Count; ++i)
{
ArrayList al = (ArrayList)TimeSpanDays[i];
all[i] = new TimeSpan[al.Count][];
al.CopyTo(all[i]);
}
return all;
}
set
{
int day = 0;
//clear all
ClearContent();
foreach (TimeSpan[][] tss in value)
{
foreach (TimeSpan[] ts in tss)
{
long t_inc = c_ts.Ticks / (long)NumTimeIntervals;
TimeSpan tsi = new TimeSpan(t_inc);
long start = ts[0].Ticks / tsi.Ticks;
long end = ts[1].Ticks / tsi.Ticks;
for (long time = start; time < end; time++)
CellMatrix[day, time].Selected = true;
}
day++;
}
Invalidate();
}
}
#region Display Intervals
[Description("The number of days to display, starting with 0==Sunday")]
[DefaultValue(c_NumDays)]
public int NumDays
{
get { return m_NumDays; }
set
{
m_NumDays = value;
s_NumDays = m_NumDays;
SetLimits();
}
}
[Description("The logical number of time intervals in the 24 hour time period")]
[DefaultValue(c_NumTimeIntervals)]
public int NumTimeIntervals
{
get { return m_NumTimeIntervals; }
set
{
m_NumTimeIntervals = value;
s_NumTimeIntervals = m_NumTimeIntervals;
SetLimits();
}
}
[Description("The number of text time markers at the bottom of the grid")]
[DefaultValue(c_TimeDisplayInterval)]
public int TimeDisplayInterval
{
get { return m_TimeDisplayInterval; }
set { m_TimeDisplayInterval = value; }
}
[Description("The number of vertical lines to display in the time period")]
[DefaultValue(c_TimeGridVerticalInterval)]
public int TimeGridVerticalInterval
{
get { return m_TimeGridVerticalInterval; }
set { m_TimeGridVerticalInterval = value; }
}
#endregion
#region Colors
public Color GridDarkColor
{
get
{
return m_sbGridDark.Color;
}
set
{
m_sbGridDark = new SolidBrush(value);
}
}
public Color GridLightColor
{
get
{
return m_sbGridLight.Color;
}
set
{
m_sbGridLight = new SolidBrush(value);
}
}
public Color Selected
{
get
{
return m_sbSelected.Color;
}
set
{
m_sbSelected = new SolidBrush( value );
}
}
public Color HotTrack
{
get
{
return m_sbHotTrack.Color;
}
set
{
m_sbHotTrack = new SolidBrush( value );
}
}
public Color GridBack
{
get
{
return m_sbGridBack.Color;
}
set
{
m_sbGridBack = new SolidBrush( value );
}
}
public override Color BackColor
{
get
{
return m_sbBack.Color;
}
set
{
m_sbBack = new SolidBrush( value );
}
}
public override Color ForeColor
{
get
{
return m_sbForeColor.Color;
}
set
{
m_sbForeColor = new SolidBrush( value );
}
}
#endregion
#region Percentages
private float Header
{
get
{
return this.Height * ( m_Header / 100.0F );
}
}
[
Category( "Percentages" ),
Description("Specifies the vertical percentage of space used for the Time Slots above the Grid."),
DefaultValue(c_Header)
]
public int HeaderPercentage
{
get
{
return m_Header;
}
set
{
m_Header = value;
}
}
private float Footer
{
get
{
return this.Height * ( m_Footer / 100.0F );
}
}
[
Category( "Percentages" ),
Description("Specifies the vertical percentage of space used for the Grid."),
DefaultValue(c_Footer)
]
public int FooterPercentage
{
get
{
return m_Footer;
}
set
{
m_Footer = value;
}
}
private float LeftMargin
{
get
{
return this.Width * ( m_LeftMargin / 100.0F );
}
}
[
Category( "Percentages" ),
Description("Specifies the horizontal percentage of space used for the displays of days."),
DefaultValue(c_LeftMargin)
]
public int LeftMarginPercentage
{
get
{
return m_LeftMargin;
}
set
{
m_LeftMargin = value;
}
}
private float RightMargin
{
get
{
return this.Width * ( m_RightMargin / 100.0F );
}
}
[
Category( "Percentages" ),
Description("Specifies the horizontal percentage of space used for the space next to the right of the Grid."),
DefaultValue(c_RightMargin)
]
public int RightMarginPercentage
{
get
{
return m_RightMargin;
}
set
{
m_RightMargin = value;
}
}
#endregion
#endregion
public TimeFrame()
{
HoverTimerStart.Stop();
HoverTimerStart.Interval = 500;
HoverTimerStop.Stop();
HoverTimerStop.Interval = 4000;
HoverTimerStart.Tick += new EventHandler( OnHoverTimerStart );
HoverTimerStop.Tick += new EventHandler( OnHoverTimerStop );
SetLimits();
TopLeft = new TopLeftCell();
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
}
#region Member Functions
#region OnEvents
protected override void OnResize( EventArgs e )
{
if( this.Width < DefaultSize.Width ) this.Width = DefaultSize.Width;
if( this.Height < DefaultSize.Height ) this.Height = DefaultSize.Height;
Grid = new RectangleF( LeftMargin, Header,
this.Width - ( LeftMargin + RightMargin ),
this.Height - ( Footer + Header ) );
TopLeft.Bounds = new RectangleF( 0, 0, Grid.X, Grid.Y );
x_grid_inc = Grid.Width / NumTimeIntervals;
y_grid_inc = Grid.Height / NumDays;
//Reset sizes
for( int i = 0; i < NumDays; ++i )
{
for( int j = 0; j < NumTimeIntervals; ++j )
{
CellMatrix[ i, j ].Bounds = new RectangleF( Grid.X + (j * x_grid_inc), Grid.Y + (i * y_grid_inc), x_grid_inc, y_grid_inc );
}
}
for( float i = 0; i < NumTimeIntervals; ++i )
{
TimeSlots[ (int)i ].Bounds = new RectangleF( Grid.X + (i * x_grid_inc), 0.0F, x_grid_inc , Header );
}
for( float i = 0; i < NumDays; ++i )
{
Days[ (int)i ].Bounds = new RectangleF( 0.0F, Grid.Y + (i * y_grid_inc), LeftMargin, y_grid_inc );
}
this.Invalidate( true );
}
protected override void OnPaint( PaintEventArgs e )
{
Draw( e.Graphics );
}
protected override void OnMouseDown( MouseEventArgs e )
{
TimeFrameObject tfo = GetTimeFrameObject( e );
if( tfo != null )
{
if( e.Button == MouseButtons.Left )
{
tfo.Selected = ! tfo.Selected;
tfoLastSelected = tfo;
this.Invalidate( true );
}
}
}
protected override void OnMouseMove( MouseEventArgs e )
{
ClearToolTopState();
TimeFrameObject tfo = GetTimeFrameObject( e );
if( e.Button == MouseButtons.Left )
{
if( tfo is Cell )
{
Cell cellNewSelected = (Cell)tfo;
if( tfoLastSelected is Cell )
{
Cell cellLastSelected = (Cell)tfoLastSelected;
if( cellLastSelected != cellNewSelected )
{
SelectCellBlock( cellLastSelected, cellNewSelected );
}
}
}
else if( tfo is TimeSlot )
{
TimeSlot tsNewSelected = (TimeSlot)tfo;
if( tfoLastSelected is TimeSlot )
{
TimeSlot tsLastSelected = (TimeSlot)tfoLastSelected;
if( tsLastSelected != tsNewSelected )
{
if( tsNewSelected.Column > tsLastSelected.Column )
{
for( int j = tsLastSelected.Column; j < tsNewSelected.Column; ++j )
{
TimeSlots[ j ].Selected = tsLastSelected.Selected;
}
}
else if( tsNewSelected.Column < tsLastSelected.Column )
{
for( int j = tsNewSelected.Column; j < tsLastSelected.Column; ++j )
{
TimeSlots[ j ].Selected = tsLastSelected.Selected;
}
}
}
}
}
else if( tfo is _Day )
{
_Day dNewSelected = (_Day)tfo;
if( tfoLastSelected is _Day )
{
_Day dLastSelected = (_Day)tfoLastSelected;
if( dLastSelected != dNewSelected )
{
if( dNewSelected.Row > dLastSelected.Row )
{
for( int i = dLastSelected.Row; i < dNewSelected.Row; ++i )
{
Days[ i ].Selected = dLastSelected.Selected;
}
}
else if( dNewSelected.Row < dLastSelected.Row )
{
for( int i = dNewSelected.Row; i < dLastSelected.Row; ++i )
{
Days[ i ].Selected = dLastSelected.Selected;
}
}
}
}
}
}
if( tfoLastHighlighted != null )
{
tfoLastHighlighted.Highlighted = false;
}
if( tfo != null )
{
tfo.Highlighted = true;
tfoLastHighlighted = tfo;
}
if( e.Button == MouseButtons.None )
{
if( Grid.Contains( e.X, e.Y ) )
{
LastMouseHover = e;
HoverTimerStart.Start();
}
}
this.Invalidate( true );
}
protected override void OnLoad( EventArgs e )
{
SetStyle( ControlStyles.DoubleBuffer, true );
SetStyle( ControlStyles.AllPaintingInWmPaint, true );
SetStyle( ControlStyles.UserPaint, true );
}
#endregion
#region ToolTip Methods
private void ClearToolTopState()
{
LastMouseHover = null;
ttInfo = null;
HoverTimerStop.Stop();
HoverTimerStart.Stop();
}
private void OnHoverTimerStop( object sender, EventArgs e )
{
if( Grid.Contains( LastMouseHover.X, LastMouseHover.Y ) )
{
ClearToolTopState();
this.Invalidate( true );
}
}
private void OnHoverTimerStart( object sender, EventArgs e )
{
if( LastMouseHover != null )
{
if( Grid.Contains( LastMouseHover.X, LastMouseHover.Y ) )
{
HoverTimerStart.Stop();
HoverTimerStop.Start();
ttInfo = new TimeToolTip();
ttInfo.Text = GetToolTipText( LastMouseHover );
this.Invalidate( true );
}
}
}
private string GetToolTipText( MouseEventArgs e )
{
string TipText = string.Empty;
if( Grid.Contains( e.X, e.Y ) )
{
Cell cell = (Cell)GetTimeFrameObject( e );
if( cell.Selected )
{
int end = cell.Y;
int start = cell.Y;
for( end = cell.Y; end < NumTimeIntervals; ++end )
{
if( ! CellMatrix[ cell.X, end ].Selected )
{
break;
}
}
for( start = cell.Y; start >= 0; --start )
{
if( ! CellMatrix[ cell.X, start ].Selected )
{
break;
}
}
++start;
long t_inc = c_ts.Ticks / (long)NumTimeIntervals;
DateTime dtStart = new DateTime( start * t_inc );
DateTime dtEnd = new DateTime( end * t_inc );
string strStart = dtStart.ToString( "hh:mm tt" );
string strEnd = dtEnd.ToString( "hh:mm tt" );
TipText = strStart + " to " + strEnd;
}
}
return TipText;
}
#endregion
public static string SerializeTimeFrames(TimeSpan[][][] TimeFrames)
{
string result = "";
int Counter = 0;
foreach (TimeSpan[][] tsa in TimeFrames)
{
result += Counter;
foreach (TimeSpan[] ts in tsa)
{
result += "," + ts[0].ToString() + " " + ts[1].ToString();
}
result += "#";
++Counter;
}
return result;
}
public static TimeSpan[][][] DeSerializeTimeFrames(string SerializedTimeFrames)
{
TimeSpan[][][] tss = new TimeSpan[8][][];
for (int i = 0; i < tss.Length; i++)
{
tss[i] = new TimeSpan[48][];
for (int j = 0; j < tss[i].Length; j++)
{
tss[i][j] = new TimeSpan[2];
}
}
int DayCounter = 0;
string[] Days = Microsoft.VisualBasic.Strings.Split(SerializedTimeFrames, "#", -1, Microsoft.VisualBasic.CompareMethod.Text);
for (DayCounter = 0; DayCounter < Days.Length - 1; DayCounter++)
{
int IntCounter = 0;
string[] Intervals = Microsoft.VisualBasic.Strings.Split(Days[DayCounter], ",", -1, Microsoft.VisualBasic.CompareMethod.Text);
for (IntCounter = 1; IntCounter < Intervals.Length; IntCounter++)
{
int SpanCounter = 0;
String[] Span = Microsoft.VisualBasic.Strings.Split(Intervals[IntCounter], " ", -1, Microsoft.VisualBasic.CompareMethod.Text);
for (SpanCounter = 0; SpanCounter < 2; SpanCounter++)
{
try
{
tss[DayCounter][IntCounter][SpanCounter] = TimeSpan.Parse(Span[SpanCounter]);
}
catch (Exception ex)
{
}
}
}
}
return tss;
}
public static void ClearContent()
{
//clear all
for (int r = 0; r < c_NumDays; r++)
{
for (int c = 0; c < c_NumTimeIntervals; c++)
{
CellMatrix[r, c].Selected = false;
}
}
}
private void SetLimits()
{
Days = new _Day[ m_NumDays ];
TimeSlots = new TimeSlot[ m_NumTimeIntervals ];
CellMatrix = new Cell[ NumDays, NumTimeIntervals ];
//Create Cells
for( int i = 0; i < NumDays; ++i )
{
for( int j = 0; j < NumTimeIntervals; ++j )
{
CellMatrix[ i,j ] = new Cell( i, j );
}
}
// Create TimeSlots
for( int j = 0; j < NumTimeIntervals; ++j )
{
TimeSlots[ j ] = new TimeSlot( j );
}
// Create Days
for( int i = 0; i < NumDays; ++i )
{
Days[ i ] = new _Day( i );
}
}
private TimeFrameObject GetTimeFrameObject( MouseEventArgs e )
{
TimeFrameObject tfo = null;
if( Grid.Contains( e.X, e.Y ) )
{
tfo = CellMatrix[ (int)( ( e.Y - Header ) / y_grid_inc), (int)( ( e.X - LeftMargin ) / x_grid_inc) ];
}
else if( ( e.X > Grid.X ) && ( e.X < ( Grid.X + Grid.Width ) ) && ( e.Y < Grid.Y ) )
{
tfo = (TimeFrameObject)TimeSlots[ (int)( ( e.X - LeftMargin ) / x_grid_inc) ];
}
else if( ( e.X < Grid.X ) && ( e.Y < ( Grid.Y + Grid.Height ) ) && ( e.Y > Grid.Y ) )
{
tfo = (_Day)Days[ (int)( ( e.Y - Header ) / y_grid_inc) ];
}
else if( TopLeft.Contains( e.X, e.Y ) )
{
tfo = TopLeft;
}
return tfo;
}
private void SelectCellBlock( Cell cellLast, Cell cellNew )
{
if( cellNew.X < cellLast.X )
{
if( cellNew.Y < cellLast.Y )
{
for( int i = cellNew.X; i <= cellLast.X; ++i )
{
for( int j = cellNew.Y; j <= cellLast.Y; ++j )
{
CellMatrix[ i, j ].Selected = cellLast.Selected;
}
}
}
else
{
for( int i = cellNew.X; i <= cellLast.X; ++i )
{
for( int j = cellLast.Y; j <= cellNew.Y; ++j )
{
CellMatrix[ i, j ].Selected = cellLast.Selected;
}
}
}
}
else
{
if( cellNew.Y < cellLast.Y )
{
for( int i = cellLast.X; i <= cellNew.X; ++i )
{
for( int j = cellNew.Y; j <= cellLast.Y; ++j )
{
CellMatrix[ i, j ].Selected = cellLast.Selected;
}
}
}
else
{
for( int i = cellLast.X; i <= cellNew.X; ++i )
{
for( int j = cellLast.Y; j <= cellNew.Y; ++j )
{
CellMatrix[ i, j ].Selected = cellLast.Selected;
}
}
}
}
}
private void Draw( Graphics g )
{
g.FillRectangle( m_sbBack, 0,0,this.Width,this.Height );
g.FillRectangle( m_sbGridBack, Grid );
DrawTopLeft( g );
DrawDays( g );
DrawTimes( g );
DrawTimeSlots( g );
DrawGrid( g );
DrawToolTip( g );
}
private void DrawToolTip( Graphics g )
{
if( ( ttInfo != null ) && ( LastMouseHover != null ) )
{
Font font = new Font( Control.DefaultFont.FontFamily, 8 );
SizeF sf = g.MeasureString( ttInfo.Text, font );
RectangleF lBounds = new RectangleF( LastMouseHover.X + 1, LastMouseHover.Y - ( 2 + sf.Height ), sf.Width, sf.Height + 1 );
if( ( lBounds.Y < 0 ) && ( ( lBounds.X + lBounds.Width + c_ToolTipXPad ) > this.Width ) )
{
lBounds.Y = LastMouseHover.Y;
lBounds.X = lBounds.X - ( lBounds.Width + 3 );
}
else if( ( lBounds.Y > 0 ) && ( ( lBounds.X + lBounds.Width + c_ToolTipXPad ) > this.Width ) )
{
lBounds.X = lBounds.X - ( lBounds.Width + 3 );
}
else if( ( lBounds.Y < 0 ) && ( ( lBounds.X + lBounds.Width + c_ToolTipXPad ) < this.Width ) )
{
lBounds.Y = LastMouseHover.Y;
lBounds.X += c_ToolTipXPad;
}
g.FillRectangle( m_sbInfoBack, lBounds );
g.DrawRectangle( Pens.Black, Rectangle.Round( lBounds ) );
g.DrawString( ttInfo.Text, font, m_sbInfoText, lBounds.X, lBounds.Y );
}
}
private void DrawTopLeft( Graphics g )
{
if( tfoLastHighlighted != null )
{
if( tfoLastHighlighted is TopLeftCell )
{
g.FillRectangle( m_sbHotTrack, tfoLastHighlighted.Bounds );
}
}
}
private void DrawGrid( Graphics g )
{
for( int i = 0; i < NumDays; ++i )
{
for( int j = 0; j < NumTimeIntervals; ++j )
{
if( CellMatrix[ i, j ].Highlighted )
{
g.FillRectangle( m_sbHotTrack, CellMatrix[ i,j ].Bounds );
}
else if( CellMatrix[ i, j ].Selected )
{
g.FillRectangle( m_sbSelected, CellMatrix[ i,j ].Bounds );
}
}
}
Pen GridLight = new Pen(m_sbGridLight);
Pen GridDark = new Pen(m_sbGridDark);
//Draw Vertical Lines
for( float i = 0; i <= NumTimeIntervals; ++i )
{
if( ( i % TimeGridVerticalInterval ) == 0 )
{
if( ( i % TimeDisplayInterval ) == 0 )
{
g.DrawLine(GridDark, Grid.X + (i * x_grid_inc), 0, Grid.X + (i * x_grid_inc), Grid.Y + Grid.Height);
}
else
{
g.DrawLine(GridLight, Grid.X + (i * x_grid_inc), 0, Grid.X + (i * x_grid_inc), Grid.Y + Grid.Height);
}
}
}
//Draw Horizontal Lines
for( float i = 0; i <= NumDays; ++i )
{
g.DrawLine(GridDark, 0, Grid.Y + (i * y_grid_inc), Grid.X + Grid.Width, Grid.Y + (i * y_grid_inc));
}
GridLight.Dispose();
GridDark.Dispose();
}
private void DrawDays( Graphics g )
{
Font font = new Font( Control.DefaultFont.FontFamily, FindEmSize( g, Days[ 0 ].Bounds ) );
for( int i = 0; i < NumDays; ++i )
{
_Day d = Days[ i ];
SizeF sf = g.MeasureString( d.DOW.ToString(), font );
if( d.Highlighted )
{
g.FillRectangle( m_sbHotTrack, d.Bounds );
}
g.DrawString( d.DOW.ToString(), font, m_sbForeColor, CenterRectangle( d.Bounds, sf ).Location );
}
}
private void DrawTimes( Graphics g )
{
Font font = new Font( Control.DefaultFont.FontFamily, Control.DefaultFont.Size );
DateTime dt;
long t_inc = c_ts.Ticks / (long)NumTimeIntervals;
for( int i = 0; i <= NumTimeIntervals; ++i )
{
if( ( i % TimeDisplayInterval ) == 0 )
{
dt = new DateTime( i * t_inc );
string strDate = dt.ToString( "htt" );
SizeF sf = g.MeasureString( strDate, Control.DefaultFont );
g.DrawString( strDate,
Control.DefaultFont, m_sbForeColor,
( Grid.X + (i * x_grid_inc) ) - ( sf.Width / 2.0F ), Grid.Y + Grid.Height + 1 );
}
}
}
private void DrawTimeSlots( Graphics g )
{
if( tfoLastHighlighted != null )
{
if( tfoLastHighlighted is TimeSlot )
{
g.FillRectangle( m_sbHotTrack, tfoLastHighlighted.Bounds.X, 0, tfoLastHighlighted.Bounds.Width, tfoLastHighlighted.Bounds.Height );
}
}
}
private RectangleF CenterRectangle( RectangleF recLarge, SizeF sizeSmaller )
{
RectangleF recNew = new RectangleF( recLarge.Location, recLarge.Size );
recNew.X = recLarge.X + ( ( recLarge.Width / 2.0F ) - ( sizeSmaller.Width / 2.0F ) );
recNew.Y = recLarge.Y + ( ( recLarge.Height / 2.0F ) - ( sizeSmaller.Height / 2.0F ) );
return recNew;
}
private float FindEmSize( Graphics g, RectangleF rec )
{
float i = 1.0F;
while( true )
{
Font f = new Font( Control.DefaultFont.FontFamily, i );
SizeF sf = g.MeasureString( DayOfWeek.Wednesday.ToString(), f );
if( ( sf.Width > rec.Width ) || ( sf.Height > rec.Height ) )
{
break;
}
++i;
}
return i > 2 ? i - 1 : 1;
}
#endregion
}
}
and this is the class for kryptonize it:
- Code: Select all
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using ComponentFactory.Krypton.Toolkit;
namespace AC.ExtendedRenderer.Toolkit
{
[System.Drawing.ToolboxBitmapAttribute(typeof(System.Windows.Forms.Control))]
public class KryptonTimeFrame : TimeFrame
{
private IPalette _palette;
private PaletteRedirect _paletteRedirect;
private PaletteBackInheritRedirect _paletteBack;
private PaletteBorderInheritRedirect _paletteBorder;
private PaletteContentInheritRedirect _paletteContent;
private IDisposable _mementoBack;
#region ... Constructor ...
public KryptonTimeFrame()
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
// add Palette Handler
if (_palette != null)
_palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(OnPalettePaint);
KryptonManager.GlobalPaletteChanged += new EventHandler(OnGlobalPaletteChanged);
_palette = KryptonManager.CurrentGlobalPalette;
_paletteRedirect = new PaletteRedirect(_palette);
_paletteBack = new PaletteBackInheritRedirect(_paletteRedirect);
_paletteBorder = new PaletteBorderInheritRedirect(_paletteRedirect);
_paletteContent = new PaletteContentInheritRedirect(_paletteRedirect);
InitColors();
}
#endregion
private void InitColors()
{
this.BackColor = _palette.ColorTable.ToolStripGradientBegin;
this.ForeColor = _palette.GetContentShortTextColor1(PaletteContentStyle.LabelNormalControl, PaletteState.Normal);
this.Font = _palette.ColorTable.MenuStripFont;
this.HotTrack = _palette.GetBackColor1(PaletteBackStyle.ButtonStandalone, PaletteState.Tracking);
this.Selected = _palette.GetBackColor2(PaletteBackStyle.ButtonNavigatorStack, PaletteState.Pressed);
this.GridDarkColor = _palette.ColorTable.ToolStripGradientEnd;
this.GridLightColor = _palette.ColorTable.ToolStripGradientMiddle;
}
#region ... Krypton ...
//Kripton Palette Events
private void OnGlobalPaletteChanged(object sender, EventArgs e)
{
if (_palette != null)
_palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(OnPalettePaint);
_palette = KryptonManager.CurrentGlobalPalette;
_paletteRedirect.Target = _palette;
if (_palette != null)
{
_palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(OnPalettePaint);
//repaint with new values
InitColors();
}
Invalidate();
}
//Kripton Palette Events
private void OnPalettePaint(object sender, PaletteLayoutEventArgs e)
{
Invalidate();
}
#endregion
}
}
UPDATE
I've added 3 methods, a serializer to store data into a string, a deserializer and the cleaner:
- Code: Select all
public static string SerializeTimeFrames(TimeSpan[][][] TimeFrames)
{
string result = "";
int Counter = 0;
foreach (TimeSpan[][] tsa in TimeFrames)
{
result += Counter;
foreach (TimeSpan[] ts in tsa)
{
result += "," + ts[0].ToString() + " " + ts[1].ToString();
}
result += "#";
++Counter;
}
return result;
}
public static TimeSpan[][][] DeSerializeTimeFrames(string SerializedTimeFrames)
{
TimeSpan[][][] tss = new TimeSpan[8][][];
for (int i = 0; i < tss.Length; i++)
{
tss[i] = new TimeSpan[48][];
for (int j = 0; j < tss[i].Length; j++)
{
tss[i][j] = new TimeSpan[2];
}
}
int DayCounter = 0;
string[] Days = Microsoft.VisualBasic.Strings.Split(SerializedTimeFrames, "#", -1, Microsoft.VisualBasic.CompareMethod.Text);
for (DayCounter = 0; DayCounter < Days.Length - 1; DayCounter++)
{
int IntCounter = 0;
string[] Intervals = Microsoft.VisualBasic.Strings.Split(Days[DayCounter], ",", -1, Microsoft.VisualBasic.CompareMethod.Text);
for (IntCounter = 1; IntCounter < Intervals.Length; IntCounter++)
{
int SpanCounter = 0;
String[] Span = Microsoft.VisualBasic.Strings.Split(Intervals[IntCounter], " ", -1, Microsoft.VisualBasic.CompareMethod.Text);
for (SpanCounter = 0; SpanCounter < 2; SpanCounter++)
{
try
{
tss[DayCounter][IntCounter][SpanCounter] = TimeSpan.Parse(Span[SpanCounter]);
}
catch (Exception ex)
{
}
}
}
}
return tss;
}
public static void ClearContent()
{
//clear all
for (int r = 0; r < c_NumDays; r++)
{
for (int c = 0; c < c_NumTimeIntervals; c++)
{
CellMatrix[r, c].Selected = false;
}
}
}
You'll find a sample project with sources attached.
It's a starting point ...
Regards /// Angel