类似Excel行头标题控件

实现了功能,还没有添加完整的事件和别的东西,核心代码如下:

 

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace UserControls
{
 /// <summary>
 /// Summary description for RowHeader.
 /// </summary>
 public class RowHeader : System.Windows.Forms.UserControl
 {
  #region Variable

  /// <summary>
  /// Required designer variable.
  /// </summary>
  private System.ComponentModel.Container components = null;

  /// <summary>
  ///
  /// </summary>
  protected BorderStyle borderStyle;
  /// <summary>
  ///
  /// </summary>
  protected Color borderColor; 
  /// <summary>
  ///
  /// </summary>
  protected Color selectedFieldBackColorFocused;
  /// <summary>
  ///
  /// </summary>
  protected Color selectedFieldBackColorNotFocused;
  /// <summary>
  ///
  /// </summary>
  protected int _nDraggingLineHeight = 2;
  /// <summary>
  ///
  /// </summary>
  protected RowHeaderFieldCollection _fields = RowHeaderFieldCollection.CreateInstance();

  /// <summary>光标是否显示为垂直拖动状态。</summary>  
  /// <remarks>
  /// 当鼠标在<see cref="RowHeaderField"/>的
  /// 下边框附近的某个范围内,或者在选中某
  /// 条线条之后,鼠标处于拖动状态即为true;
  /// 否则为false。
  /// </remarks>
  private bool _bShowHSplit = false;

  /// <summary> 被选中的线条是否显示为虚线。</summary>
  /// <remarks></remarks>
  private bool _bShowDashed = false;
  
  /// <summary></summary>
  private bool _bMouseDrag = false;

  /// <summary>鼠标是否按下。</summary>
  private bool _bMouseButtonLeftDown = false;

  /// <summary>鼠标一直处于按住状态。</summary>
  private bool _bMouseButtonLeftPress = false;

  /// <summary>鼠标是否松开。</summary>
  private bool _bMouseButtonLeftUp = false;

  /// <summary>鼠标当前位置的X坐标。</summary>
  private int _nMouseX = 0;

  /// <summary>鼠标当前位置的Y坐标。</summary>
  private int _nMouseY = 0;

  #endregion Variable

  #region Property

  /// <summary>
  /// 在<see cref="RowHeader"/>获得焦点时,
  /// 绘制选中<see cref="RowHeaderField"/>的背景色
  /// </summary>
  public Color SelectedFieldBackColorFocused
  {
   get { return selectedFieldBackColorFocused; }
   set
   {
    if ( selectedFieldBackColorFocused != value )
    {
     selectedFieldBackColorFocused = value;
     this.Invalidate();
    }
   }
  }

  /// <summary>
  /// 在<see cref="RowHeader"/>未获得焦点时,
  /// 绘制选中<see cref="RowHeaderField"/>的背景色
  /// </summary>
  public Color SelectedFieldBackColorNotFocused
  {
   get { return selectedFieldBackColorNotFocused; }
   set
   {
    if ( selectedFieldBackColorNotFocused != value )
    {
     selectedFieldBackColorNotFocused = value;
     this.Invalidate();
    }
   }
  }

  /// <summary> 设置或获取边框式样的值. </summary>
  /// <remarks>
  /// 通过编程或者属性BordStyle可以改变控件<see cref='RowHeader'/>的边框式样的值.
  /// </remarks>
  public BorderStyle BorderStyle
  {
   get { return borderStyle; }
   set
   {
    if ( borderStyle != value )
    {
     borderStyle = value;
     this.Invalidate();
    }
   }
  }

  /// <summary> 设置或获取边框颜色的值.</summary>
  /// <remarks>
  /// 该值表示<see cref='RowHeader'/>控件的边框颜色。
  /// </remarks>
  /// <value>
  /// 一个<see cref="Color"/>,表示行头控件的边框颜色。
  /// </value>
  public Color BorderColor
  {
   get { return borderColor; }
   set
   {
    if ( borderColor != value )
    {

     borderColor = value;
     this.Invalidate();
    }
   }
  }

  #endregion Property

  #region Paint the RowHeader and RowHeaderField

  /// <summary>
  /// 绘制控件<see cref="RowHeader"/>
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="pe"></param>
  protected void RowHeader_Paint(object sender,PaintEventArgs pe)
  {
   Graphics g = pe.Graphics;
   PaintBackColor(g);
   PaintBorders(g);
   PaintSelectedRowHeaderField(g);
   PaintHeaderFieldBackColorAndBorder(g);
   PaintRowHeaderField(g);
   RowHeader_DrawDraggingLine(g);
  }

  /// <summary>
  /// 绘制控件<see cref="RowHeader"/>的背景色
  /// </summary>
  /// <param name="g"></param>
  protected void PaintBackColor(Graphics g)
  {
   Rectangle rect ;
   
   rect= new Rectangle();
   rect.X = 0;
   rect.Y = 0;
   rect.Width = this.Bounds.Width;
   rect.Height = this.Bounds.Height;

   g.FillRectangle(new SolidBrush(Color.White), rect);
  }

  /// <summary>
  /// 绘制控件<see cref="RowHeader"/>的边框
  /// </summary>
  /// <param name="g"></param>
  protected void PaintBorders(Graphics g)
  {
   Rectangle recBounds = new Rectangle();

   //取得边框位置
   recBounds.X = 0;
   recBounds.Y = 0;
   recBounds.Width = this.Bounds.Width;
   recBounds.Height = this.Bounds.Height;

   switch (borderStyle)
   {
    case BorderStyle.Fixed3D:

     ControlPaint.DrawBorder3D(g,recBounds,Border3DStyle.Raised);
     break;

    case BorderStyle.FixedSingle:

     ControlPaint.DrawBorder(g,recBounds,BorderColor,ButtonBorderStyle.Solid);
     break;
   }
  }

  /// <summary>
  /// 绘制控件<see cref="RowHeader"/>的组成部分<see cref="RowHeaderField"/>的背景和边框
  /// </summary>
  /// <param name="g"></param>
  protected void PaintHeaderFieldBackColorAndBorder(Graphics g)
  {
   for ( int i = 0; i < _fields.Count; i++ )
   {
    if ( _fields[i].Selected )
     continue;

    RectangleF recField = new RectangleF();

    recField.X = _fields[i].X;
    recField.Y = _fields[i].Y;
    recField.Height = _fields[i].Height;
    recField.Width = _fields[i].Width - 1;

    g.FillRectangle(new SolidBrush(Color.FromKnownColor(KnownColor.Control)), recField);
    g.DrawRectangle(new Pen(borderColor, 1), recField.X,recField.Y,recField.Width,recField.Height);
   }
  }

  /// <summary>
  /// 绘制控件<see cref="RowHeader"/>的组成部分<see cref="RowHeaderField"/>
  /// </summary>
  /// <param name="g"></param>
  protected void PaintRowHeaderField(Graphics g)
  {
   for (int i = 0; i < _fields.Count; i++)
   {
    RectangleF recField = new RectangleF();

    recField.X = _fields[i].X;
    recField.Y = _fields[i].Y;
    recField.Height = _fields[i].Height;
    recField.Width = this.Width;

    string caption = (i + 1).ToString();
    DrawString(recField, g, caption, StringAlignment.Center, StringAlignment.Center, this.Font, this.ForeColor);
   }
  }

  /// <summary>
  /// 画被拖拽的线条
  /// </summary>
  /// <param name="g"></param>
  protected void RowHeader_DrawDraggingLine(Graphics g)
  {
   if ( _bShowDashed == true )
   {
    RectangleF rec = new RectangleF();

    rec.X = 0;
    rec.Y = _nMouseY - _nDraggingLineHeight / 2.0f;
    rec.Width = this.Width;
    rec.Height = _nDraggingLineHeight;

    g.FillRectangle(new HatchBrush(HatchStyle.Percent50,Color.FromKnownColor(KnownColor.Black),Color.FromKnownColor(KnownColor.Transparent)),rec);
   }
  }

  #endregion Paint the RowHeader and RowHeaderField

  # region Others

  /// <summary>
  /// 重设置<see cref="RowHeaderFieldCollection"/>中的元素<see cref="RowHeaderField"/>
  /// 的位置<see cref="RowHeaderField.X"/>和<see cref="RowHeaderField.Y"/>
  /// </summary>
  /// <remarks>当拖拽<see cref="RowHeaderField"/>时,应该调用此函数</remarks>
  protected void ResetRowHeaderFieldLocation()
  {
   for ( int i = 0;i < _fields.Count; i++ )
   {
    _fields[i].X = 0;
    _fields[i].Y = _fields.GetTotalHaightBeforeIndex(i);
   }
  }

  /// <summary>
  /// 重设置<see cref="RowHeaderFieldCollection"/>中的元素<see cref="RowHeaderField"/>
  /// 的位置<see cref="RowHeaderField.Height"/>和<see cref="RowHeaderField.Width"/>
  /// </summary>
  /// <remarks>当拖拽<see cref="RowHeaderField"/>时,应该调用此函数</remarks>
  protected void ResetRowHeaderFieldSize()
  {
   for ( int i = 0; i < _fields.Count; i++ )
   {
    if ( _fields[i].InDraging == true )
    {
     if ( _nMouseY - _fields[i].Y <= RowHeaderField.MinHeight )
      _fields[i].Height = RowHeaderField.MinHeight;
     else
      _fields[i].Height = _nMouseY - _fields[i].Y;
     //以后扩展X方向的拖拽
     break;
    }
   }
  }

  #endregion Others

  #region About Draw String

  /// <summary>
  ///
  /// </summary>
  /// <param name="rec"></param>
  /// <param name="g"></param>
  /// <param name="text"></param>
  /// <param name="horizontalAlign"></param>
  /// <param name="verticalAlign"></param>
  /// <param name="font"></param>
  /// <param name="fontColor"></param>
  public static void DrawString(RectangleF rec, Graphics g, string text, StringAlignment horizontalAlign, StringAlignment verticalAlign, Font font, Color fontColor)
  {
   SolidBrush sbCellFontColor = new SolidBrush(fontColor);

   RectangleF recF = new RectangleF();         //单元格内容字符串范围
   SizeF sz = new SizeF();            //单元格内容字符串尺寸

   StringFormat sf = new StringFormat(StringFormat.GenericDefault); //字符串格式
   sf.Alignment = horizontalAlign;          //对齐方式
   sf.Trimming = StringTrimming.EllipsisWord;

   int charsfitted = 0;
   int linesfilled = 0;

   //画字符串
   if (text != "" && rec.Width > 0)
   {
    sz = g.MeasureString(text, font, new SizeF(rec.Width, rec.Height), sf, out charsfitted, out linesfilled);

    switch(verticalAlign)
    {
     case StringAlignment.Far:

      recF = new RectangleF(rec.Left, (float)(rec.Top + Math.Ceiling(rec.Height - sz.Height)) - 1, rec.Width, sz.Height);
      break;

     case StringAlignment.Center:

      recF = new RectangleF(rec.Left, (float)(rec.Top + Math.Ceiling((rec.Height - sz.Height) / 2) + 1), rec.Width, sz.Height);
      break;

     default:

      recF = new RectangleF(rec.Left, rec.Top + 2, rec.Width, rec.Height);
      break;
    }

    g.DrawString(text, font, sbCellFontColor, recF, sf);
   }
  }

  /// <summary>
  /// 测量指定字符串的高度。
  /// </summary>
  /// <param name="text">一个<see cref="string"/>,表示要测量的字符串。</param>
  /// <param name="g">一个<see cref="System.Drawing.Graphics"/>对象。</param>
  /// <param name="f">一个<see cref="System.Drawing.Font"/>,表示绘制此字符串的<see cref="Font"/>对象。</param>
  /// <returns>一个<see cref="float"/>型的值,表示指定字符串的高度。</returns>
  public static float MeasureTextHeight(string text,System.Drawing.Graphics g,System.Drawing.Font f)
  {
   //测量字符串的高度
   SizeF sz = new SizeF();
   
   if (text == String.Empty) return 0;
   if (g == null) return 0;
   if (f == null) return 0;

   sz = g.MeasureString(text,f);
   return sz.Height;
  }


  #endregion About Draw String
  
  #region Mouse event

  /// <summary>
  ///
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  protected void RowHeader_MouseDown(object sender,MouseEventArgs e)
  {
   _nMouseX = e.X;
   _nMouseY = e.Y;

   if ( e.Button == MouseButtons.Left )
   {
    _bMouseButtonLeftDown = true; 
    _bMouseButtonLeftUp = false;
    _bShowDashed = _bShowHSplit ? true : false;
   }

   if ( _bShowDashed == true )
   {
    int indexDraged = _fields.GetIndexDraggedRegionByPostion(_nMouseX,_nMouseY);
    _fields.SetDraggedField(indexDraged);
   }
   else
   {
    int index =  _fields.GetIndexRegionByPostion(_nMouseX,_nMouseY);

    if ( index >= 0 && index <= _fields.Count )
     _fields[index].Selected = true;
   }

   this.Invalidate();
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  protected void RowHeader_MouseMove(object sender,MouseEventArgs e)
  {
   _nMouseX = e.X;
   _nMouseY = e.Y;

   if ( _bMouseButtonLeftDown == false )
   {
    if ( _fields.GetIndexDraggedRegionByPostion(_nMouseX,_nMouseY) >=0 )
     _bShowHSplit = true;
    else if ( _fields.GetIndexRegionByPostion(_nMouseX,_nMouseY) >=0 )
     _bShowHSplit = false;

    this.Cursor = _bShowHSplit ? Cursors.HSplit : Cursors.Default;
   }
   // 如果鼠标按下,同时光标为拖拽状态,选中线条为虚线时
   else if ( _bMouseButtonLeftDown == true && _bShowHSplit == true && _bShowDashed == true )
   {
    _bMouseButtonLeftPress = true;
    _bMouseDrag = true;
    ResetRowHeaderFieldSize();
    ResetRowHeaderFieldLocation();
   }

   this.Invalidate();
  }
  
  /// <summary>
  ///
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  protected void RowHeader_MouseUp(object sender,MouseEventArgs e)
  {
   _bMouseButtonLeftDown = false;
   _bMouseButtonLeftUp = true;
   _bMouseButtonLeftPress = false;
   _bShowDashed = false;

   _nMouseX = e.X;
   _nMouseY = e.Y;

   if ( _fields.IndexInDraging >= 0 )
   {
    _fields[_fields.IndexInDraging].InDraging = false;
   }

   this.Invalidate();
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="g"></param>
  protected void PaintSelectedRowHeaderField(Graphics g)
  {
   for ( int i = 0; i < _fields.Count; i++ )
   {
    if ( _fields[i].Selected == true )
    {
     RectangleF recField = new RectangleF();

     recField.X = _fields[i].X;
     recField.Y = _fields[i].Y;
     recField.Height = _fields[i].Height;
     recField.Width = _fields[i].Width - 1;

     if (this.Focused)
      g.FillRectangle(new SolidBrush(selectedFieldBackColorFocused), recField);
     else
      g.FillRectangle(new SolidBrush(selectedFieldBackColorNotFocused), recField);
     break;
    }
   }
  }


  #endregion Mouse event

  #region Constructor and Dispose
  
  /// <summary>
  /// RowHeader的构造函数
  /// </summary>
  public RowHeader()
  {
   // This call is required by the Windows.Forms Form Designer.
   InitializeComponent();

   int totalHaight = 0;

   this.SetStyle(ControlStyles.UserPaint,true);
   this.SetStyle(ControlStyles.DoubleBuffer,true);
   this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
   this.SetStyle(ControlStyles.Selectable, false);

   borderStyle = BorderStyle.FixedSingle;
   borderColor = Color.FromKnownColor(KnownColor.ControlDark);
   selectedFieldBackColorFocused = Color.FromArgb(254, 128, 62);
   selectedFieldBackColorNotFocused = Color.FromArgb(255, 192, 111);

   _fields = RowHeaderFieldCollection.CreateInstance();

   for ( int i = 0; i < 20; i++ )
   {
    RowHeaderField rhf = new RowHeaderField();
    rhf.ID = i;
    rhf.Index = i;
    rhf.Fields = _fields;
    rhf.Parent = this;
    rhf.Y = totalHaight;
    rhf.Height = RowHeaderField.DelfaultHeight;
    rhf.Width = this.Width;
    totalHaight = totalHaight + rhf.Height;

    _fields.Add(rhf);
   }
  }


  /// <summary>
  /// Clean up any resources being used.
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if(components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Component Designer generated code
  /// <summary>
  /// Required method for Designer support - do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {
   //
   // RowHeader
   //
   this.Name = "RowHeader";
   this.Size = new System.Drawing.Size(40, 401);
   this.SizeChanged += new System.EventHandler(this.RowHeader_SizeChanged);
   this.LostFocus += new EventHandler(RowHeader_LostFocus);
   this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.RowHeader_MouseUp);
   this.Paint += new System.Windows.Forms.PaintEventHandler(this.RowHeader_Paint);
   this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.RowHeader_MouseMove);
   this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.RowHeader_MouseDown);

  }
  #endregion

  private void RowHeader_SizeChanged(object sender, System.EventArgs e)
  {
   this.Invalidate();
  }

  #endregion Constructor and Dispose

  private void RowHeader_LostFocus(object sender, EventArgs e)
  {
   this.Invalidate();
  }
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值