小新的技术天地

Make It Works !

博客园 首页 新随笔 联系 订阅 管理

作者:Werdna               翻译:小新0574

原文及代码链接:http://www.codeproject.com/cs/media/SystemPainter.asp

Introduction

System painter is a little utility for viewing .NET framework system defined hatches from System.Drawing.Drawing2D.HatchStyle and windows system colors and named colors from Color structure.

The example shows how to use different brushes and how to extend ListBox with owner drawn code.

System painter是一个用来查看.NET frameworkSystem.Drawing.Drawing2D.HatchStyle里的系统预定义的hatcheswindows系统颜色以及Color结构里的颜色的一个小工具。

Painters

The code uses 2 different painters (with easy ability to create new different ones). All painters implement IPainter interface. All the interface does it to get the name that will show in list box and Brush used for filling.

代码使用了2种不同的painters(同时很方便创建新的painters)。所有的painters实现了IPainter接口。所有的界面使用它来得到要显示在list box里的名字和用来填充的Brush

    public interface IPainter
    
{
        Brush PaintBrush
        
{
            
get;
        }


        
string Name
        
{
            
get;
        }

    }


We also have utility enumeration for available painters:

我们还有为可用painters准备的工具枚举:

    public enum PaintType
    
{
        Hatches,        
// draw hatches from HatchStyle
        SystemColors,    // draw system colors 
        Colors            // draw NamedColors (except system colors)
    }


First painter is the color painter. All it does is filling the listbox item with solid color:

第一个painter是一个颜色painter。它所做的就是用纯色填充listbox

 public class ColorPainter : IPainter
    
{
        Color color;
        
        
public ColorPainter(Color color)
        
{
            
this.color = color;
        }


        
public string Name
        
{
            
get return color.ToKnownColor().ToString(); }
        }


        
public Brush PaintBrush
        
{
            
get return new SolidBrush(color); }
        }

    }


And another one is Hatch painter that uses hatch brush:

另一个是使用hatch刷子的Hatch painter

 public class HatchPainter : IPainter
    
{
        HatchStyle style;    
        Color color1;    
// foreground color for hatch
        Color color2;    // background color for hatch

        
public HatchPainter(HatchStyle style, Color color1, Color color2)
        
{
            
this.style = style;
            
this.color1 = color1;
            
this.color2 = color2;            
        }


        
/// <SUMMARY>
        
/// for name just return hatch enum name
        
/// </SUMMARY>

        public string Name
        
{
            
get return style.ToString();    }
        }


        
/// <SUMMARY>
        
/// return HatchBrush with current style and colors
        
/// </SUMMARY>

        public Brush PaintBrush
        
{
            
get 
                
return new HatchBrush(style, color1, color2);
            }

        }

    .

That's it for painters. We have 3 different types and only 2 painters because SystemColors and Colors use the same painter.

这就是为painters所做的了。我们有3个不同的类型,但只有两个painters,因为SystemColorsColors使用同样的painter

ListBox

The implementation of the listbox is an owner drawn listbox. To do that all we have to do is:
 

Listbox实现的是一个自绘的listbox。为了做这些,我们所要做的是在构造器里写上这个:

  this.DrawMode = DrawMode.OwnerDrawFixed;

in constructor. We also have custom PaintType property on the listbox that decides what type of painter to use:

 

我们还有自定义的PaintType属性作用于listbox,这个属性决定了使用哪种类型的painter

 public PaintType PaintType
    
{
        
get return this.paintType; }
        
set 
        
{
            paintType 
= value;
            InitValues();
        }

    }


when we assign this property we initialize the items in the list:

当我们指派这个属性时,我们在列表里初始化项:

void InitValues()
{
    
this.Items.Clear();

    
if (paintType == PaintType.Hatches)
    
{
        
// for hatches we get all values from HatchStyle enumeration
        foreach (HatchStyle style in Enum.GetValues(typeof(HatchStyle)))
        
{
            IPainter painter 
= new HatchPainter(style, 
                 Color.Blue, Color.Transparent);
            Items.Add(painter);
        }

    }

    
else if (paintType == PaintType.Colors)
    
{
        
// for colors we get all color values from KnownColor
        
// and skip system colors
        foreach (KnownColor kcolor in Enum.GetValues(typeof(KnownColor)))
        
{
            Color color 
= Color.FromKnownColor(kcolor);
            
if (!color.IsSystemColor)
            
{
                IPainter painter 
= new ColorPainter(color);
                Items.Add(painter);
            }

        }


    }

    
else if (paintType == PaintType.SystemColors)
    
{
        
// for systemcolors we get all known colors
        
// and only use system colors
        foreach (KnownColor kcolor in Enum.GetValues(typeof(KnownColor)))
        
{
            Color color 
= Color.FromKnownColor(kcolor);
            
if (color.IsSystemColor)
            
{
                IPainter painter 
= new ColorPainter(color);
                Items.Add(painter);
            }

        }


    }


}


Depending on the type of painter that we want to use, we populate the list with IPainter values. Later when we draw the items we don't care about what type of list it is, because IPainter will tell us how to paint it. And finally the draw item code:

根据我们想用的painter类型,我们在列表里使用了IPainter 值。以后当我们绘制项时,我们不用介意list是什么类型了,因为IPainter会告诉我们怎么绘制它。最后的绘制项的代码:

// each item in the list IPainter
IPainter painter = (IPainter)Items[e.Index];

// get brush from painter
Brush brush = painter.PaintBrush;

// fill the item with painters brush
g.FillRectangle(brush, e.Bounds);
g.DrawLine(Pens.Black, e.Bounds.X, e.Bounds.Bottom
-1
  e.Bounds.Right, e.Bounds.Bottom
-1);

// draw box with painter name
string name = painter.Name;
int width = (int)g.MeasureString(name, Font).Width;

g.FillRectangle((e.State 
& DrawItemState.Selected) == 
  DrawItemState.Selected 
? Brushes.Yellow : Brushes.White,
  
3, e.Bounds.Top+3, width+3, Font.Height+5);

g.DrawRectangle(Pens.Black, 
3, e.Bounds.Top+3, width+3, Font.Height+5);
g.DrawString(painter.Name, Font, Brushes.Black, 
5, e.Bounds.Top+5);

brush.Dispose();

We fill the area with painters brush, draw line below each item to separate them, and draw a box with painters name.

我们使用painters刷子填充区域,在每项下面画线来隔离它们,用painters的名字画了一个box

posted on 2005-05-08 22:51  小新0574  阅读(1976)  评论(0编辑  收藏  举报