/*
* =============================================
* Wrote By Deboy Wang @ 2013/5/3
* If you have any question ,
* pls contact me with email: deboywang@126.com
* Copyright 2013
* =============================================
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace D8DentistryMS
{
/// <summary>
/// 牙科诊所管理软件中也许会使用的标记牙问题的自定义控件
/// 本控件可以表示恒牙,也可以表示乳牙
/// 用户可以通过鼠标点击来 选中或者取消选中 牙齿
///
/// 在牙科标记办法中,将人的牙齿标记如下:
///
/// 成年人牙齿(恒牙)
/// 第一象限 第二象限
/// 18 17 16 15 14 13 12 11 | 21 22 23 24 25 26 27 28
/// -------------------------------------------------
/// 48 47 46 45 44 43 42 41 | 31 32 33 34 35 36 37 38
/// 第四象限 第三象限
///
/// 婴幼儿牙齿(乳牙)
/// 第一象限 第二象限
/// 55 54 53 52 51 | 61 62 63 64 65
/// -------------------------------
/// 85 84 83 82 81 | 71 72 73 74 75
/// 第四象限 第三象限
/// </summary>
public class Teeth : Control
{
#region 自定义字段
private Color _SelectedColor = Color.OrangeRed;
private ToothType _TeethType = ToothType.AdultTeeth;
private float BUTTON_WIDTH = 10f;
private float BUTTON_HEIGHT = 12f;
private List<int> _SelectedTeeth = new List<int>();
#endregion
#region 自定义属性
/// <summary>
/// 用户点击选择牙齿的时候,被选中牙齿的颜色
/// </summary>
[Browsable(true), Category("Appearance")]
public Color SelectedColor
{
get { return _SelectedColor; }
set { _SelectedColor = value; }
}
/// <summary>
/// 设置或者获取 牙齿类型:恒牙 或 乳牙
/// </summary>
[Browsable(true), Category("Appearance"),DefaultValue(ToothType.AdultTeeth)]
public ToothType TeethType
{
get { return _TeethType; }
set {
if (_TeethType != value)
{
_TeethType = value;
_SelectedTeeth.Clear();
}
}
}
/// <summary>
/// 设置或者获取 用户选中的牙齿编号
/// </summary>
[Browsable(true), Category("Data")]
public List<int> SelectedTeeth
{
get
{
return _SelectedTeeth;
}
set
{
_SelectedTeeth = value;
this.Refresh();
}
}
#endregion
#region 重写控件事件
/// <summary>
/// 重写系统的Paint事件处理方法,实现牙齿排列图形和编号的绘制
/// </summary>
/// <param name="pe"></param>
protected override void OnPaint(PaintEventArgs pe)
{
if (this.Parent != null)
this.BackColor = Color.White;
Brush defaultb = new SolidBrush(Color.LightGray);
Brush selectedb = new SolidBrush(Color.White);
if (this.TeethType == ToothType.AdultTeeth)
{
#region 成年人牙齿排列
for (int i = 1; i < 9; i++)
{
//第二象限
if (this._SelectedTeeth.Contains(20 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(80 + BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(80 + BUTTON_WIDTH * i, 2));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(80 + BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(80 + BUTTON_WIDTH * i, 2));
}
//第三象限
if (this._SelectedTeeth.Contains(30 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(80 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(80 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(80 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(80 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT));
}
}
for (int i = 8; i > 0; i--)
{
//第一象限
if (this._SelectedTeeth.Contains(10 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(82 - BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(82 - BUTTON_WIDTH * i, 2));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(82 - BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(82 - BUTTON_WIDTH * i, 2));
}
//第四象限
if (this._SelectedTeeth.Contains(40 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(82 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(82 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(82 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(82 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT));
}
}
pe.Graphics.DrawLine(new Pen(Brushes.Gray, 1), new Point(2, 15), new Point(170, 15));
pe.Graphics.DrawLine(new Pen(Brushes.Gray, 1), new Point(85, 2), new Point(85, 28));
#endregion
}
else
{
#region 婴幼儿牙齿排列
for (int i = 1; i < 6; i++)
{
#region 第二象限
if (this._SelectedTeeth.Contains(60 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(50 + BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(50 + BUTTON_WIDTH * i, 2));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(50 + BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(50 + BUTTON_WIDTH * i, 2));
}
#endregion
#region 第三象限
if (this._SelectedTeeth.Contains(70 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(50 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(50 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(50 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(50 + BUTTON_WIDTH * i, 6 + BUTTON_HEIGHT));
}
#endregion
}
for (int i = 5; i > 0; i--)
{
#region 第一象限
if (this._SelectedTeeth.Contains(50 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(52 - BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(52 - BUTTON_WIDTH * i, 2));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(52 - BUTTON_WIDTH * i, 2, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(52 - BUTTON_WIDTH * i, 2));
}
#endregion
#region 第四象限
if (this._SelectedTeeth.Contains(80 + i))
{
pe.Graphics.FillRectangle(new SolidBrush(_SelectedColor), new RectangleF(52 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, selectedb, new PointF(52 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT));
}
else
{
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), new RectangleF(52 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT));
pe.Graphics.DrawString(i.ToString(), Font, defaultb, new PointF(52 - BUTTON_WIDTH * i, 6 +
BUTTON_HEIGHT));
}
#endregion
}
pe.Graphics.DrawLine(new Pen(Brushes.Gray, 1), new Point(2, 15), new Point(110, 15));
pe.Graphics.DrawLine(new Pen(Brushes.Gray, 1), new Point(55, 2), new Point(55, 28));
#endregion
}
base.OnPaint(pe);
}
/// <summary>
/// 重写系统的 OnMouseClick 事件处理方法,实现选中牙齿编号获取和设置
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(MouseEventArgs e)
{
// MessageBox.Show(GetClickNumber(e.Location).ToString());
int number = GetClickNumber(e.Location);
if (this._SelectedTeeth.Contains(number))
{
this._SelectedTeeth.Remove(number);
}
else
{
this._SelectedTeeth.Add(number);
}
this.Refresh();
base.OnMouseClick(e);
}
/// <summary>
/// 根据用户鼠标点击位置,获取牙齿编号
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
protected int GetClickNumber(Point p)
{
int no = 0;
if (this.TeethType == ToothType.AdultTeeth)
{
if (p.Y < 15 && p.X < 90)
{
no = 1 * 10 + (90 - p.X) / 10;
}
if (p.Y < 15 && p.X > 80)
{
no = 2 * 10 + (p.X - 80) / 10;
}
if (p.Y > 15 && p.X > 80)
{
no = 3 * 10 + (p.X - 80) / 10;
}
if (p.Y > 15 && p.X < 90)
{
no = 4 * 10 + (90 - p.X) / 10;
}
if (no % 10 < 9 && no % 10 > 0)
return no;
else
return -1;
}
else
{
if (p.Y < 15 && p.X < 60)
{
no = 5 * 10 + (60 - p.X) / 10;
}
if (p.Y < 15 && p.X > 50)
{
no = 6 * 10 + (p.X - 50) / 10;
}
if (p.Y > 15 && p.X > 50)
{
no = 7 * 10 + (p.X - 50) / 10;
}
if (p.Y > 15 && p.X < 60)
{
no = 8 * 10 + (60 - p.X) / 10;
}
if (no % 10 < 6 && no % 10 > 0)
return no;
else
return -1;
}
}
#endregion
#region 组件设计器生成的代码
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// 默认构造函数
/// </summary>
public Teeth()
{
InitializeComponent();
//设置控件初始大小
this.Width = 170;
this.Height = 30;
}
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
/// <summary>
/// 牙齿类型
/// </summary>
public enum ToothType
{
/// <summary>
/// 儿童乳牙
/// </summary>
BabyTeeth,
/// <summary>
/// 成年人恒牙
/// </summary>
AdultTeeth
}
}
控件运行效果图: