Index: /trunk/sources/HeuristicLab.Visualization.Test/MainForm.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization.Test/MainForm.Designer.cs	(revision 1044)
+++ /trunk/sources/HeuristicLab.Visualization.Test/MainForm.Designer.cs	(revision 1045)
@@ -37,5 +37,4 @@
       this.canvasUI.TabIndex = 3;
       this.canvasUI.Text = "canvasUI";
-      this.canvasUI.MouseDown += new System.Windows.Forms.MouseEventHandler(this.canvasUI_MouseDown);
       // 
       // label2
Index: /trunk/sources/HeuristicLab.Visualization.Test/MainForm.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization.Test/MainForm.cs	(revision 1044)
+++ /trunk/sources/HeuristicLab.Visualization.Test/MainForm.cs	(revision 1045)
@@ -4,10 +4,6 @@
 namespace HeuristicLab.Visualization.Test {
   public partial class MainForm : Form {
-    private MouseEventListener dragDropListener;
-
     public MainForm() {
       InitializeComponent();
-
-      CreateMouseEventListeners();
 
       canvasUI.MainCanvas.WorldShape = new WorldShape(new RectangleD(0, 0, 800, 600), new RectangleD(0, 0, 800, 600));
@@ -19,10 +15,4 @@
 
       canvasUI.Invalidate();
-    }
-
-    private void CreateMouseEventListeners() {
-      dragDropListener = new MouseEventListener();
-      dragDropListener.OnMouseMove += DragDrop_OnMouseMove;
-      dragDropListener.OnMouseUp += DragDrop_OnMouseUp;
     }
 
@@ -92,28 +82,4 @@
     }
 
-    private void canvasUI_MouseDown(object sender, MouseEventArgs e) {
-      mouseEventDemonstrationGraphics = canvasUI.CreateGraphics();
-
-      dragDropListener.StartPoint = e.Location;
-      lastActualPoint = e.Location;
-
-      canvasUI.MouseEventListener = dragDropListener;
-    }
-
-    private Point lastActualPoint;
-    private Graphics mouseEventDemonstrationGraphics;
-
-    private void DragDrop_OnMouseUp(Point startPoint, Point actualPoint) {
-      canvasUI.MouseEventListener = null;
-
-      canvasUI.Invalidate();
-      mouseEventDemonstrationGraphics.Dispose();
-    }
-
-    private void DragDrop_OnMouseMove(Point startPoint, Point actualPoint) {
-      mouseEventDemonstrationGraphics.DrawLine(Pens.Blue, lastActualPoint, actualPoint);
-      lastActualPoint = actualPoint;
-    }
-
     private void legendButton_Click(object sender, System.EventArgs e) {
       LegendForm form = new LegendForm();
Index: /trunk/sources/HeuristicLab.Visualization/CanvasUI.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/CanvasUI.cs	(revision 1044)
+++ /trunk/sources/HeuristicLab.Visualization/CanvasUI.cs	(revision 1045)
@@ -8,5 +8,5 @@
   public partial class CanvasUI : Control {
     private readonly Canvas mainCanvas = new Canvas();
-    private MouseEventListener mouseEventListener;
+    private IMouseEventListener mouseEventListener;
 
     public CanvasUI() {
@@ -20,5 +20,5 @@
     }
 
-    public MouseEventListener MouseEventListener {
+    public IMouseEventListener MouseEventListener {
       get { return mouseEventListener; }
       set { mouseEventListener = value; }
@@ -51,5 +51,5 @@
     private void CanvasUI_MouseMove(object sender, MouseEventArgs e) {
       if (mouseEventListener != null) {
-        mouseEventListener.MouseMove(e.Location);
+        mouseEventListener.MouseMove(sender, e);
       }
     }
@@ -57,5 +57,5 @@
     private void CanvasUI_MouseUp(object sender, MouseEventArgs e) {
       if (mouseEventListener != null) {
-        mouseEventListener.MouseUp(e.Location);
+        mouseEventListener.MouseUp(sender, e);
       }
     }
Index: /trunk/sources/HeuristicLab.Visualization/LineChart.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/LineChart.cs	(revision 1044)
+++ /trunk/sources/HeuristicLab.Visualization/LineChart.cs	(revision 1045)
@@ -49,6 +49,7 @@
     /// <param name="model">Referenz to the model, for data</param>
     public LineChart(IChartDataRowsModel model) : this() {
-      if (model == null)
+      if (model == null) {
         throw new NullReferenceException("Model cannot be null.");
+      }
 
       //TODO: correct Rectangle to fit
@@ -71,6 +72,4 @@
 
       UpdateLayout();
-
-      CreateMouseEventListeners();
 
       this.model = model;
@@ -117,6 +116,7 @@
       model.ModelChanged += OnModelChanged;
 
-      foreach (IDataRow row in model.Rows)
+      foreach (IDataRow row in model.Rows) {
         OnDataRowAdded(row);
+      }
     }
 
@@ -132,6 +132,7 @@
       row.ValueChanged += OnRowValueChanged;
       row.ValuesChanged += OnRowValuesChanged;
-      if (row.Count > maxDataRowCount)
+      if (row.Count > maxDataRowCount) {
         maxDataRowCount = row.Count;
+      }
 
       InitLineShapes(row);
@@ -139,6 +140,7 @@
 
     private void ZoomToFullView() {
-      if (!zoomFullView)
+      if (!zoomFullView) {
         return;
+      }
       RectangleD newClippingArea = new RectangleD(-0.1,
                                                   minDataValue - ((maxDataValue - minDataValue)*0.05),
@@ -164,5 +166,5 @@
       List<LineShape> lineShapes = new List<LineShape>();
       if (row.Count > 0) {
-        maxDataValue = Math.Max(row[0], this.maxDataValue);
+        maxDataValue = Math.Max(row[0], maxDataValue);
         minDataValue = Math.Min(row[0], minDataValue);
       }
@@ -197,11 +199,13 @@
       minDataValue = Math.Min(value, minDataValue);
 
-      if (index > lineShapes.Count + 1)
+      if (index > lineShapes.Count + 1) {
         throw new NotImplementedException();
+      }
 
       // new value was added
       if (index > 0 && index == lineShapes.Count + 1) {
-        if (maxDataRowCount < row.Count)
+        if (maxDataRowCount < row.Count) {
           maxDataRowCount = row.Count;
+        }
         LineShape lineShape = new LineShape(index - 1, row[index - 1], index, row[index], 0, row.Color, row.Thickness, row.Style);
         lineShapes.Add(lineShape);
@@ -211,10 +215,12 @@
 
       // not the first value
-      if (index > 0)
+      if (index > 0) {
         lineShapes[index - 1].Y2 = value;
+      }
 
       // not the last value
-      if (index > 0 && index < row.Count - 1)
+      if (index > 0 && index < row.Count - 1) {
         lineShapes[index].Y1 = value;
+      }
       ZoomToFullView();
 
@@ -224,6 +230,7 @@
     // TODO use action parameter
     private void OnRowValuesChanged(IDataRow row, double[] values, int index, Action action) {
-      foreach (double value in values)
+      foreach (double value in values) {
         OnRowValueChanged(row, value, index++, action);
+      }
     }
 
@@ -241,111 +248,69 @@
 
     public void EndUpdate() {
-      if (beginUpdateCount == 0)
+      if (beginUpdateCount == 0) {
         throw new InvalidOperationException("Too many EndUpdates.");
+      }
 
       beginUpdateCount--;
 
-      if (beginUpdateCount == 0)
+      if (beginUpdateCount == 0) {
         canvas.Invalidate();
+      }
     }
 
     #endregion
 
-    private MouseEventListener panListener;
-    private MouseEventListener zoomListener;
-
-    private void CreateMouseEventListeners() {
-      panListener = new MouseEventListener();
-      panListener.OnMouseMove += Pan_OnMouseMove;
-      panListener.OnMouseUp += Pan_OnMouseUp;
-
-      zoomListener = new MouseEventListener();
-      zoomListener.OnMouseMove += Zoom_OnMouseMove;
-      zoomListener.OnMouseUp += Zoom_OnMouseUp;
-    }
-
-    private RectangleD startClippingArea;
+    private RectangleShape rectangleShape;
 
     private void canvasUI1_MouseDown(object sender, MouseEventArgs e) {
       if (ModifierKeys == Keys.Control) {
-        zoomListener.StartPoint = e.Location;
-        canvas.MouseEventListener = zoomListener;
-
-        r = Rectangle.Empty;
-        rectangleShape = new RectangleShape(e.X, e.Y, e.X, e.Y, Color.Blue);
-        rectangleShape.Opacity = 50;
-
-        linesShape.AddShape(rectangleShape);
+        CreateZoomListener(e);
       } else {
-        panListener.StartPoint = e.Location;
-        canvas.MouseEventListener = panListener;
-
-        startClippingArea = linesShape.ClippingArea;
-      }
-    }
-
-    private void Pan_OnMouseUp(Point startPoint, Point actualPoint) {
+        CreatePanListener(e);
+      }
+    }
+
+    private void CreateZoomListener(MouseEventArgs e) {
+      ZoomListener zoomListener = new ZoomListener(e.Location);
+      zoomListener.DrawRectangle += DrawRectangle;
+      zoomListener.OnMouseUp += OnZoom_MouseUp;
+
+      canvas.MouseEventListener = zoomListener;
+
+      rectangleShape = new RectangleShape(e.X, e.Y, e.X, e.Y, Color.Blue);
+      rectangleShape.Opacity = 50;
+
+      linesShape.AddShape(rectangleShape);
+    }
+
+    private void OnZoom_MouseUp(object sender, MouseEventArgs e) {
       canvas.MouseEventListener = null;
-    }
-
-    private void Pan_OnMouseMove(Point startPoint, Point actualPoint) {
-      Rectangle viewPort = canvas.ClientRectangle;
-
-      PointD worldStartPoint = Transform.ToWorld(startPoint, viewPort, startClippingArea);
-      PointD worldActualPoint = Transform.ToWorld(actualPoint, viewPort, startClippingArea);
-
-      double xDiff = worldActualPoint.X - worldStartPoint.X;
-      double yDiff = worldActualPoint.Y - worldStartPoint.Y;
-
-      RectangleD newClippingArea = new RectangleD();
-      newClippingArea.X1 = startClippingArea.X1 - xDiff;
-      newClippingArea.X2 = startClippingArea.X2 - xDiff;
-      newClippingArea.Y1 = startClippingArea.Y1 - yDiff;
-      newClippingArea.Y2 = startClippingArea.Y2 - yDiff;
-
+
+      SetLineClippingArea(rectangleShape.Rectangle);
+      linesShape.RemoveShape(rectangleShape);
+
+      zoomFullView = false; //user wants to zoom => no full view
+
+      canvas.Invalidate();
+    }
+
+    private void DrawRectangle(Rectangle rectangle) {
+      rectangleShape.Rectangle = Transform.ToWorld(rectangle, canvas.ClientRectangle, linesShape.ClippingArea);
+      canvas.Invalidate();
+    }
+
+    private void CreatePanListener(MouseEventArgs e) {
+      PanListener panListener = new PanListener(canvas.ClientRectangle, linesShape.ClippingArea, e.Location);
+
+      panListener.SetNewClippingArea += SetNewClippingArea;
+      panListener.OnMouseUp += delegate { canvas.MouseEventListener = null; };
+
+      canvas.MouseEventListener = panListener;
+    }
+
+    private void SetNewClippingArea(RectangleD newClippingArea) {
       SetLineClippingArea(newClippingArea);
-      panListener.StartPoint = startPoint;
-
-      zoomFullView = false; //user wants to pan => no full view
-
-      canvas.Invalidate();
-    }
-
-    private void Zoom_OnMouseUp(Point startPoint, Point actualPoint) {
-      canvas.MouseEventListener = null;
-
-      RectangleD newClippingArea = Transform.ToWorld(r, canvas.ClientRectangle, linesShape.ClippingArea);
-      SetLineClippingArea(newClippingArea);
-      linesShape.RemoveShape(rectangleShape);
-
-      zoomFullView = false; //user wants to pan => no full view
-
-      canvas.Invalidate();
-    }
-
-    private Rectangle r;
-    private RectangleShape rectangleShape;
-
-    private void Zoom_OnMouseMove(Point startPoint, Point actualPoint) {
-      r = new Rectangle();
-
-      if (startPoint.X < actualPoint.X) {
-        r.X = startPoint.X;
-        r.Width = actualPoint.X - startPoint.X;
-      } else {
-        r.X = actualPoint.X;
-        r.Width = startPoint.X - actualPoint.X;
-      }
-
-      if (startPoint.Y < actualPoint.Y) {
-        r.Y = startPoint.Y;
-        r.Height = actualPoint.Y - startPoint.Y;
-      } else {
-        r.Y = actualPoint.Y;
-        r.Height = startPoint.Y - actualPoint.Y;
-      }
-
-      rectangleShape.Rectangle = Transform.ToWorld(r, canvas.ClientRectangle, linesShape.ClippingArea);
-      
+
+      zoomFullView = false;
       canvas.Invalidate();
     }
Index: /trunk/sources/HeuristicLab.Visualization/MouseEventListener.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/MouseEventListener.cs	(revision 1044)
+++ /trunk/sources/HeuristicLab.Visualization/MouseEventListener.cs	(revision 1045)
@@ -1,55 +1,116 @@
 ﻿using System.Drawing;
+using System.Windows.Forms;
 
 namespace HeuristicLab.Visualization {
-  /// <summary>
-  /// Helper class for different OnMouseMove and OnMouseUp implementations.
-  /// </summary>
-  public class MouseEventListener {
-    /// <summary>
-    /// Fired when the MouseMove method was called.
-    /// </summary>
-    public event MouseEventListenerHandler OnMouseMove;
+  public interface IMouseEventListener {
+    void MouseMove(object sender, MouseEventArgs e);
+    void MouseUp(object sender, MouseEventArgs e);
 
-    /// <summary>
-    /// Fired when the MouseUp method was called.
-    /// </summary>
-    public event MouseEventListenerHandler OnMouseUp;
+    event MouseEventHandler OnMouseMove;
+    event MouseEventHandler OnMouseUp;
+  }
 
-    private Point startPoint;
+  public delegate void SetNewClippingAreaHandler(RectangleD newClippingArea);
 
-    /// <summary>
-    /// Call this method to fire the OnMouseMove event.
-    /// </summary>
-    /// <param name="actualPoint"></param>
-    public void MouseMove(Point actualPoint) {
+  public delegate void DrawRectangleHandler(Rectangle rectangle);
+
+  public class PanListener : IMouseEventListener {
+    private readonly Rectangle viewPort;
+    private readonly RectangleD clippingArea;
+    private readonly Point startPoint;
+
+    public PanListener(Rectangle viewPort, RectangleD clippingArea, Point startPoint) {
+      this.viewPort = viewPort;
+      this.clippingArea = clippingArea;
+      this.startPoint = startPoint;
+    }
+
+    #region IMouseEventListener Members
+
+    public event SetNewClippingAreaHandler SetNewClippingArea;
+    public event MouseEventHandler OnMouseMove;
+    public event MouseEventHandler OnMouseUp;
+
+    public void MouseMove(object sender, MouseEventArgs e) {
+      PointD worldStartPoint = Transform.ToWorld(startPoint, viewPort, clippingArea);
+      PointD worldActualPoint = Transform.ToWorld(e.Location, viewPort, clippingArea);
+
+      double xDiff = worldActualPoint.X - worldStartPoint.X;
+      double yDiff = worldActualPoint.Y - worldStartPoint.Y;
+
+      RectangleD newClippingArea = new RectangleD();
+      newClippingArea.X1 = clippingArea.X1 - xDiff;
+      newClippingArea.X2 = clippingArea.X2 - xDiff;
+      newClippingArea.Y1 = clippingArea.Y1 - yDiff;
+      newClippingArea.Y2 = clippingArea.Y2 - yDiff;
+
+      if (SetNewClippingArea != null) {
+        SetNewClippingArea(newClippingArea);
+      }
+
       if (OnMouseMove != null) {
-        OnMouseMove(startPoint, actualPoint);
+        OnMouseMove(sender, e);
       }
     }
 
-    /// <summary>
-    /// Call this method to fire the OnMouseUp event.
-    /// </summary>
-    /// <param name="actualPoint">Actual point of the mouse</param>
-    public void MouseUp(Point actualPoint) {
+    public void MouseUp(object sender, MouseEventArgs e) {
       if (OnMouseUp != null) {
-        OnMouseUp(startPoint, actualPoint);
+        OnMouseUp(sender, e);
       }
     }
 
-    /// <summary>
-    /// Gets or sets the starting point of the mouse.
-    /// </summary>
-    public Point StartPoint {
-      get { return startPoint; }
-      set { startPoint = value; }
-    }
+    #endregion
   }
 
-  /// <summary>
-  /// Handler for the MouseEventListener events.
-  /// </summary>
-  /// <param name="startPoint">Starting point of the mouse.</param>
-  /// <param name="actualPoint">Actual point of the mouse.</param>
-  public delegate void MouseEventListenerHandler(Point startPoint, Point actualPoint);
+  public class ZoomListener : IMouseEventListener {
+    private readonly Point startPoint;
+
+    public event DrawRectangleHandler DrawRectangle;
+
+    public ZoomListener(Point startPoint) {
+      this.startPoint = startPoint;
+    }
+
+    #region IMouseEventListener Members
+
+    public event MouseEventHandler OnMouseMove;
+    public event MouseEventHandler OnMouseUp;
+
+    public void MouseMove(object sender, MouseEventArgs e) {
+      Rectangle r = new Rectangle();
+      Point actualPoint = e.Location;
+
+      if (startPoint.X < actualPoint.X) {
+        r.X = startPoint.X;
+        r.Width = actualPoint.X - startPoint.X;
+      } else {
+        r.X = actualPoint.X;
+        r.Width = startPoint.X - actualPoint.X;
+      }
+
+      if (startPoint.Y < actualPoint.Y) {
+        r.Y = startPoint.Y;
+        r.Height = actualPoint.Y - startPoint.Y;
+      } else {
+        r.Y = actualPoint.Y;
+        r.Height = startPoint.Y - actualPoint.Y;
+      }
+
+      if(DrawRectangle != null) {
+        DrawRectangle(r);
+      }
+
+      if (OnMouseMove != null) {
+        OnMouseMove(sender, e);
+      }
+    }
+
+    public void MouseUp(object sender, MouseEventArgs e) {
+      if (OnMouseUp != null) {
+        OnMouseUp(sender, e);
+      }
+    }
+
+    #endregion
+  }
 }
