Little Painter Step by Step-Day 6
来源:互联网 发布:ed2k协议软件下载 编辑:程序博客网 时间:2024/06/07 06:24
第六天:(目标:用Command方式实现Display)
今天我们要在Components中用Command的方式实现Display,我们首先创建两个工程DisplayAPI和DisplayImp。可以设想,我们会使用各种各样的Command,如DrawLineCommand,DrawCircleCommand等等,为了能统一的管理这些Command,使得它们能被集中处理,我们需要给它们一个基类ADisplayCommand,这个类从AUndoableCommand继承,由于我们是使用GDI+绘图,所以ADisplayCommand定义如下
public abstract class ADisplayCommand : AUndoableCommand
{
public Graphics CurrrentGraphics
{
get { return mGraphics; }
set { mGraphics = value; }
}
protected Graphics mGraphics;
}
我们还需要一个DisplayManager来管理这些display commands
public class DisplayManager
{
private static List<ADisplayCommand> mDisplayCommandList = new List<ADisplayCommand>();
public static void AddDisplayItem(ADisplayCommand command)
{
mDisplayCommandList.Add(command);
}
public static Boolean RemoveDisplayItem(ADisplayCommand command)
{
return mDisplayCommandList.Remove(command);
}
public static IEnumerator<ADisplayCommand> DisplayItems
{
get { return mDisplayCommandList.GetEnumerator(); }
}
}
当我们在Canvas上画线时,我们就不用再生成一个DrawInformation了,取而代之,我们将生成一个command,并将该Command添加到DisplayManager中,在Canvas重绘时,我们就遍历DisplayManager的所有Commands并一一执行,这样就达到了和之前使用DrawInformation同样的效果,不同的是,我们使用了抽象类的方式代替了原来的枚举方式,能降低代码的耦合,可以设想,当我以后需要添加画矩形的工具时,在这里我们仅仅从ADisplayCommand继承一个DrawRectangleCommand即可。
接下来是对Canvas的处理,在原来的代码中,我们是使用的Panel作为Canvas,现在我将创建一个从Control类继承的ACanvas类,对于ApplicationForm来说,它只知道ACanvas,至于具体使用的是什么,就由我们自己创建从ACanvas继承的类即可。
public abstract class ACanvas : Control
{
}
public class Canvas : ACanvas
{
public Canvas()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
IEnumerator<ADisplayCommand> displayCommandsEnum = DisplayManager.DisplayItems;
displayCommandsEnum.Reset();
while (displayCommandsEnum.MoveNext())
{
ADisplayCommand command = displayCommandsEnum.Current;
if (command == null) continue;
command.CurrrentGraphics = e.Graphics;
if (command.CanExecute(null))
command.Execute(null);
}
}
}
最后我们来实现DrawLineCommand
public class DrawLineCommand : ADisplayCommand
{
public DrawLineCommand(ACanvas canvas, Pen pen, Point startPoint, Point endPoint)
{
if (canvas == null) throw new ArgumentNullException("ACanvas");
if (pen == null) throw new ArgumentNullException("Pen");
m_Canvas = canvas;
m_Pen = pen;
m_StartPoint = startPoint;
m_EndPoint = endPoint;
}
public override void Execute(Object parameter)
{
mGraphics.DrawLine(m_Pen, m_StartPoint, m_EndPoint);
}
public override Boolean CanExecute(Object parameter)
{
if (m_Canvas == null)
return false;
if (m_Pen == null)
return false;
if (m_StartPoint.Equals(m_EndPoint))
return false;
return true;
}
public override void Undo()
{
DisplayManager.RemoveDisplayItem(this);
m_Canvas.Invalidate();
}
public override void Redo()
{
DisplayManager.AddDisplayItem(this);
m_Canvas.Invalidate();
}
private ACanvas m_Canvas;
private Pen m_Pen;
private Point m_StartPoint;
private Point m_EndPoint;
}
明天我们将对Tool进行抽象,并对我们的ApplicationForm进行重构- Little Painter Step by Step-Day 6
- Little Painter Step by Step-Day 1
- Little Painter Step by Step-Day 2
- Little Painter Step by Step-Day 3
- Little Painter Step by Step-Day 4
- Little Painter Step by Step-Day 5
- Little Painter Step by Step-Day 7
- Little Painter Step by Step-Day 8
- Little Painter Step by Step-Day 9
- NHibernate Step By Step(6)-关联关系
- MyCat1.6 Mysql集群Step by Step
- NHibernate Step by Step
- OGRE step by step
- step by step
- MinGW Step by Step
- 大杂烩---Step by Step
- sphinx4 STEP BY STEP
- EJB step by step
- 《孙子兵法》的“为将之道”
- WebBrowser控键实现对IE浏览器的各种控制
- 最近
- DIV滚动条
- 为客户定制开发进销存程序
- Little Painter Step by Step-Day 6
- STRUTS2_TREE加图片
- 用select 语句中的START WITH...CONNECT BY PRIOR子句实现递归查询
- 太喜欢 PoisonIvy了
- JAVA学习路线
- VB直接保存和显示ACCESS数据库中的图像数据
- javascript中存在几种对URL字符串进行编码的方法
- 加速firefox
- 用URL传参带特殊字符的问题!