这里介绍了UltraWinGrid中IUIElementDrawFilter和IUIElementCreationFilter两个接口的使用方法。
Ultra控件实在是复杂,个人感觉功能强大,当然属性也有N多,还是老外的东西,网上找不到比较理想的资料,就比如下面这两个小问题,也是自己摸索出来的。
一、在UltraGridCell中绘制金额线。
这里使用到了IUIElementDrawFilter接口,这个接口是自定元素绘制过滤器,它有两个方法GetPhasesToFilter和DrawElement,GetPhasesToFilter是将你所需要绘制的元素过滤出来。DrawElement是对过滤出来的元素进行重画。代码如下:
Code
/// <summary>
/// 绘制金额显示
/// </summary>
public class CurrencyDrawFilter : IUIElementDrawFilter
{
UltraGridColumn column;
const int WIDTH = 9;
/// <summary>
///
/// </summary>
/// <param name="column">要绘制的列</param>
public CurrencyDrawFilter(UltraGridColumn column)
{
this.column = column;
column.DataType = typeof (Decimal);
}
/// <summary>
///
/// </summary>
/// <param name="drawParams"></param>
/// <returns></returns>
public DrawPhase GetPhasesToFilter(ref UIElementDrawParams drawParams)
{
if (drawParams.Element is CellUIElement)
return DrawPhase.BeforeDrawElement;
else
return DrawPhase.None;
}
/// <summary>
///
/// </summary>
/// <param name="drawPhase"></param>
/// <param name="drawParams"></param>
/// <returns></returns>
public bool DrawElement(DrawPhase drawPhase, ref UIElementDrawParams drawParams)
{
UltraGridCell cell = (UltraGridCell) drawParams.Element.GetContext(typeof (UltraGridCell));
if (cell.Column == column)
{
//画背景
Rectangle rect = drawParams.Element.Rect;
rect.Inflate(-1, 0);
drawParams.Graphics.FillRectangle(cell.Selected || cell.Row.Selected ? SystemBrushes.Highlight : SystemBrushes.Window, rect);
DrawCurrencyLine(drawParams.Element.Rect, drawParams.Graphics);
DrawCurrencyText(cell, drawParams.Element.Rect, drawParams.Graphics);
return true;
}
return false;
}
/// <summary>
/// 绘制金额线
/// </summary>
/// <param name="rect"></param>
/// <param name="g"></param>
private void DrawCurrencyLine(Rectangle rect, Graphics g)
{
Pen pen = null;
for (int i = 1; i < rect.Width/WIDTH; i++)
{
if (i == 2) pen = Pens.Red; //小数位
else if (i > 3 && ((i - 2)%3 == 0)) pen = Pens.LightSeaGreen; //千分位
else pen = Pens.LightGray;
Point p1 = new Point(rect.Right - i*WIDTH, rect.Top);
Point p2 = new Point(rect.Right - i*WIDTH, rect.Bottom);
g.DrawLine(pen, p1, p2);
}
}
/// <summary>
/// 绘制金额文本
/// </summary>
/// <param name="cell"></param>
/// <param name="rect"></param>
/// <param name="g"></param>
private void DrawCurrencyText(UltraGridCell cell, Rectangle rect, Graphics g)
{
try
{
string text = "¥" + (cell.Value == null || cell.Value == DBNull.Value || cell.Text == "0" ? "000" : (decimal.Parse(cell.Value.ToString())*100).ToString("0"));
//定义格式
Font font = System.Windows.Forms.Control.DefaultFont;
StringFormat sfrm = new StringFormat();
sfrm.LineAlignment = StringAlignment.Center;
sfrm.Alignment = StringAlignment.Center;
Brush brush = cell.Selected || cell.Row.Selected ? SystemBrushes.HighlightText : SystemBrushes.WindowText;
int left = rect.Right - WIDTH*text.Length;
int i = 0;
//循环输出每一个数字
for (int x = left; x < rect.Right; x += WIDTH)
{
Rectangle textRect = new Rectangle(x + 1, rect.Top, WIDTH, rect.Height);
if (textRect.Left < rect.Left) continue;
g.DrawString(text.Substring(i++, 1), font, brush, textRect, sfrm);
}
}
catch (System.Exception)
{
}
}
}
二、在新增行的时候让统计行不要上下移动。
这是一个令我非常头痛的问题,如果将AllowAddNew设为false,那么就无法添加新行,如果加上统计行的话,只要新增行,统计行就移到新增行的下方,输入文字后,它又下来了。我甚至已经绝望了,想做个Label来代替它。无意中看到它的一个接口IUIElementCreationFilter,想着试试看,不试不知道,一试。。。
IUIElementCreationFilter是元素创建过滤器,它有AfterCreateChildElements和BeforeCreateChildElements两个方法,我们只需在AfterCreateChildElements里修改一下元素就可以了:
Code
/// <summary>
/// 限制统计行在添加的时候不要上移
/// </summary>
public class SummaryCreationFilter : IUIElementCreationFilter
{
UltraGrid grid;
/// <summary>
/// 构造新对象。
/// </summary>
/// <param name="grid">要控制的grid。</param>
public SummaryCreationFilter(UltraGrid grid)
{
this.grid = grid;
}
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
public void AfterCreateChildElements(Infragistics.Win.UIElement parent)
{
if ( parent is SummaryFooterUIElement )
{
//重新设置对象的座标。
parent.Rect = new Rectangle(0, grid.Height - parent.Rect.Height, grid.Width, parent.Rect.Height);
}
}
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
public bool BeforeCreateChildElements(Infragistics.Win.UIElement parent)
{
return false;
}
}
前端只要构造这两个类就可以实现了:
grid.DrawFilter = new CurrencyDrawFilter(gridInfo.DisplayLayout.Bands[0].Columns["REAL_MONEY"]);
grid.CreationFilter = new SummaryCreationFilter(gridInfo);