65.9K
CodeProject 正在变化。 阅读更多。
Home

一天中的时间选择器控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.57/5 (16投票s)

2002年12月10日

1分钟阅读

viewsIcon

130023

downloadIcon

2528

一个简单的控件,允许用户选择一天中的时间段。

Sample Image - TimeFrame.jpg

引言

该控件使用双缓冲来提供一个界面,允许用户选择一天中的时间段。该控件的建模灵感来自于 Windows NT 中最初出现的一个控件,该控件允许用户指定登录域的有效时间。

关于该控件

该控件具有一个名为 TimeFrames 的属性,该属性返回一个三维 TimeSpan 对象数组。

public TimeSpan[][][] TimeFrames
  • 第一维代表日期
  • 第二维代表一个特定的连续时间段
  • 第三维只有两个元素,第一个是开始时间,第二个是结束时间

正如 Eric White 和 Chris Garrett 的著作“GDI+ 编程:使用 C# 创建自定义控件”中所建议的那样,屏幕的所有部分都分成单独的对象。由于控件的主要区域都可以进行热跟踪或选择,因此存在一个基本概念 TimeFrameObject,所有子区域都从该对象继承。这个基类包括对象的边界成员以及对象是否被热跟踪或选择。这大大减少了代码量。例如,此方法确定屏幕上的某个特定点的位置,并确定哪个 TimeFrameObject 包含该点。

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;
}

这简化了 OnMouseDown 事件处理程序为

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 );
        }
    }
}

就是这样

© . All rights reserved.