在用友金蝶等财务软件中,经常需要输入货币类型的数据, 那么这种输入框要如何制作呢?
借助于强大的 DataGridView 控件, 我们可以轻易的制作出这种效果,见下图.
要扩展 DataGridView 的列类型,我们只需要从 DataGridViewColumn 类中派生出一个新的类,并且为这个列添加对应的单元格模板即可(从 DataGridViewCell 类中派生)。
代码其实超级简单, 新增一个 Column 类型
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
class
DataGridViewCurrencyColumn : DataGridViewColumn
{
public DataGridViewCurrencyColumn()
: base ( new DataGridViewCurrencyCell())
{
Resizable = DataGridViewTriState.False;
// 固定宽度
Width = 120 ;
}
public override sealed DataGridViewTriState Resizable
{
get { return base .Resizable; }
set { base .Resizable = value; }
}
}
{
public DataGridViewCurrencyColumn()
: base ( new DataGridViewCurrencyCell())
{
Resizable = DataGridViewTriState.False;
// 固定宽度
Width = 120 ;
}
public override sealed DataGridViewTriState Resizable
{
get { return base .Resizable; }
set { base .Resizable = value; }
}
}
新增一个 Cell 类型
主要是重载 OnPaint ,对单元格重新绘制,给数据的每一位都画上一条分隔线就行了
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
class
DataGridViewCurrencyCell : DataGridViewTextBoxCell
{
// 每一位数字的宽度
private const int P_WIDTH = 10 ;
public override Type ValueType
{
get { return typeof ( decimal ); }
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
DataGridViewElementStates cellState, object value, object formattedValue,
string errorText, DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
// 背景色
Color clr_background = (cellState & DataGridViewElementStates.Selected) !=
DataGridViewElementStates.Selected
? cellStyle.BackColor
: cellStyle.SelectionBackColor;
using (Brush bru = new SolidBrush(clr_background))
{
graphics.FillRectangle(bru, cellBounds);
}
// 边框
if ((paintParts & DataGridViewPaintParts.Border) != 0 )
{
PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
}
// 画出10个整数位,2个小数位
for ( int i = 1 ; i < 10 ; i ++ )
{
graphics.DrawLine(Pens.DarkCyan, cellBounds.Left + i * P_WIDTH, cellBounds.Top,
cellBounds.Left + i * P_WIDTH, cellBounds.Bottom - 1 );
}
graphics.DrawLine(Pens.Red, cellBounds.Left + 10 * P_WIDTH, cellBounds.Top, cellBounds.Left + 10 * P_WIDTH,
cellBounds.Bottom - 1 );
graphics.DrawLine(Pens.DarkCyan, cellBounds.Left + 11 * P_WIDTH, cellBounds.Top, cellBounds.Left + 11 * P_WIDTH,
cellBounds.Bottom - 1 );
// 文字
if (value == null )
return ;
var sf = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
decimal v = Convert.ToDecimal(value);
string s_int = (( int ) v).ToString();
// 两位小数
string s_dec = (v * 100 % 100 ).ToString( " 00 " );
string s_value = " ¥ " + s_int + s_dec;
for ( int i = 0 ; i < s_value.Length; i ++ )
{
string ch = s_value[s_value.Length - i - 1 ].ToString();
int x = cellBounds.Left + ( 12 - i - 1 ) * P_WIDTH;
int y = cellBounds.Top;
var rect = new RectangleF(x, y, P_WIDTH, cellBounds.Height);
graphics.DrawString(ch, cellStyle.Font, Brushes.Black, rect, sf);
}
sf.Dispose();
}
}
{
// 每一位数字的宽度
private const int P_WIDTH = 10 ;
public override Type ValueType
{
get { return typeof ( decimal ); }
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
DataGridViewElementStates cellState, object value, object formattedValue,
string errorText, DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
// 背景色
Color clr_background = (cellState & DataGridViewElementStates.Selected) !=
DataGridViewElementStates.Selected
? cellStyle.BackColor
: cellStyle.SelectionBackColor;
using (Brush bru = new SolidBrush(clr_background))
{
graphics.FillRectangle(bru, cellBounds);
}
// 边框
if ((paintParts & DataGridViewPaintParts.Border) != 0 )
{
PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
}
// 画出10个整数位,2个小数位
for ( int i = 1 ; i < 10 ; i ++ )
{
graphics.DrawLine(Pens.DarkCyan, cellBounds.Left + i * P_WIDTH, cellBounds.Top,
cellBounds.Left + i * P_WIDTH, cellBounds.Bottom - 1 );
}
graphics.DrawLine(Pens.Red, cellBounds.Left + 10 * P_WIDTH, cellBounds.Top, cellBounds.Left + 10 * P_WIDTH,
cellBounds.Bottom - 1 );
graphics.DrawLine(Pens.DarkCyan, cellBounds.Left + 11 * P_WIDTH, cellBounds.Top, cellBounds.Left + 11 * P_WIDTH,
cellBounds.Bottom - 1 );
// 文字
if (value == null )
return ;
var sf = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
decimal v = Convert.ToDecimal(value);
string s_int = (( int ) v).ToString();
// 两位小数
string s_dec = (v * 100 % 100 ).ToString( " 00 " );
string s_value = " ¥ " + s_int + s_dec;
for ( int i = 0 ; i < s_value.Length; i ++ )
{
string ch = s_value[s_value.Length - i - 1 ].ToString();
int x = cellBounds.Left + ( 12 - i - 1 ) * P_WIDTH;
int y = cellBounds.Top;
var rect = new RectangleF(x, y, P_WIDTH, cellBounds.Height);
graphics.DrawString(ch, cellStyle.Font, Brushes.Black, rect, sf);
}
sf.Dispose();
}
}