Posted by: Zeeshan Amjad | July 25, 2009

VisualCollection class in WPF


ContainerVisual is a concrete class is used as a container for other visual object. Here is a sample code to demonstrate this class.

  1: using System;
  2: using System.Windows;
  3: using System.Windows.Media;
  4: using System.Windows.Input;
  5: 
  6: public class MyWindow : Window
  7: {
  8:     private ContainerVisual mv;
  9: 
 10:     public MyWindow()
 11:     {
 12:         Title = "ContainerVisual Class";
 13:         Width = 300;
 14:         Height = 200;
 15:         WindowStartupLocation = WindowStartupLocation.CenterScreen;
 16: 
 17:         mv = new ContainerVisual();
 18:         AddVisualChild(mv);
 19: 
 20:         MouseDown += new MouseButtonEventHandler(MyWindow.OnMouseDown);
 21:     }
 22: 
 23:     static void OnMouseDown(Object sender, MouseButtonEventArgs e)
 24:     {
 25:         MyWindow win = (MyWindow)sender;
 26:         Point point = new Point();
 27:         point.X = e.GetPosition(win).X;
 28:         point.Y = e.GetPosition(win).Y;
 29: 
 30:         Point screenPoint = win.mv.PointToScreen(point);
 31: 
 32:         String str = String.Format("Before Calling PointToScreen ({0}, {1})\nAfter Calling PointToScreen ({2}, {3})",
 33:             point.X, point.Y, screenPoint.X, screenPoint.Y);
 34: 
 35:         win.Content = str;
 36:     }
 37: }
 38: 
 39: public class wpf
 40: {
 41:     [STAThread]
 42:     public static void Main()
 43:     {
 44:         MyWindow win = new MyWindow();
 45: 
 46:         Application app = new Application();
 47:         app.Run(win);
 48:     }
 49: }
 50: 

The most important addition to ContainerVisual class is an addition of VisualCollection field. VisualCollection is one of very rare case in WPF that this class is not inherited by DependencyObject or DispatcherObject. This class directly inherits from the Object class. Here is a class diagram of this.

wpf_18

It is important to note that although this class is available only at the ContainerVisual and its subclasses, but Visual class still has two protected functions related to this named VisualChildernCount and GetVisualChild. VisualChildernCount always return 0 at Visual class level and GetVisualChild throws ArgumentOutOfRangeException. And it perfectly makes sense, because we don’t even have VisualCollection defined at this level. These functions are available only for its subclasses to override and provide proper implementation. It is one more reason to make Visual abstract class.

There is one more method to write something on the window and use Visual class functionality. Create an object of VisualCollection class and set Window class its parent at the time of it creation by passing its address in constructor. Then add the object of MyVisual class in the VisualCollection. Here is a sample program to show this method.

  1: using System;
  2: using System.Windows;
  3: using System.Windows.Media;
  4: using System.Windows.Input;
  5: 
  6: public class MyVisual : Visual
  7: {
  8: }
  9: 
 10: public class MyWindow : Window
 11: {
 12:     private MyVisual mv;
 13:     private VisualCollection vc;
 14: 
 15:     public MyWindow()
 16:     {
 17:         Title = "VisualCollection Class";
 18:         Width = 300;
 19:         Height = 200;
 20:         WindowStartupLocation = WindowStartupLocation.CenterScreen;
 21: 
 22:         mv = new MyVisual();
 23:         vc = new VisualCollection(this);
 24: 
 25:         vc.Add(mv);
 26: 
 27:         MouseDown += new MouseButtonEventHandler(MyWindow.OnMouseDown);
 28:     }
 29: 
 30:     static void OnMouseDown(Object sender, MouseButtonEventArgs e)
 31:     {
 32:         MyWindow win = (MyWindow)sender;
 33:         Point point = new Point();
 34:         point.X = e.GetPosition(win).X;
 35:         point.Y = e.GetPosition(win).Y;
 36: 
 37:         Point screenPoint = win.mv.PointToScreen(point);
 38: 
 39:         String str = String.Format("Before Calling PointToScreen ({0}, {1})\nAfter Calling PointToScreen ({2}, {3})",
 40:             point.X, point.Y, screenPoint.X, screenPoint.Y);
 41: 
 42:         win.Content = str;
 43:     }
 44: }
 45: 
 46: public class wpf
 47: {
 48:     [STAThread]
 49:     public static void Main()
 50:     {
 51:         MyWindow win = new MyWindow();
 52: 
 53:         Application app = new Application();
 54:         app.Run(win);
 55:     }
 56: }
 57: 

The output of this program is same as the previous program; the only difference is the caption of the window. Caption of the window of is “VisualCollection Class” in this program.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: