Planning the Spontaneous

It's more than just a blueprint.

Posts Tagged ‘.NET’

OOP

Posted by Robert Chow on 01/04/2010

OOP.  Object-orientated-programming.  Something that every programmer should be able to do nowadays writing a 3rd gen language.  With dynamic languages, I’m not entirely sure on how different it is, but I’m guessing the principles are the same.

But that’s not what I’m here to blog about.  I’ve managed to whip up a demo of the toolkit, OOP, or I’d like to call it, Object-Orientated-Paint.

Object-Orientated-Paint

So for those that use Microsoft Paint (and I still do), many will know how annoying it is to only have one canvas, and that every single dash or pixel “painted” on to the canvas is essentially there to stay unless another splash of paint writes over it.  It’s quite frustrating, especially when only a few minutes down the line do you realise that you forgot to draw something and therefore have to edit the whole picture.  Once you’ve edited that picture, you’ve also no way of going back either (the undo command only has a history of 3, something that has frustrated me rather a lot over the years).

So why better it by encapsulating each shape/splash of paint as an object?  It’s essentially what Microsoft Powerpoint uses.  True, you dont’ get the same precision and granularity to edit a particular shape as you would in Paint, but it’s a heck of a lot easier to use.  Although my knowledge is very limited in the area, I’m guessing you could make the same connection with C and C#.  C is a language (correct me if I’m wrong here) that is not designed for OOP, yet it allows you to reach the gutsy insides of a computer.  C# on the other-hand is designed to be used in OOP, and although it’s a lot harder to get to the lower-levels of computation, it is a lot faster, and ultimately easier to use.

Now jumping the gun a bit, it’s similar to Renderer and the toolkit.  Renderer is just a wrapper around OpenGl – it can do everything it wants, providing OpenGl supports it (although I haven’t wrapped around every single OpenGl call – that would be insane).  Yet if I were to use Renderer indirectly, via the toolkit, I am unable to do everything that Renderer supports – the toolkit limits my actions, yet makes the more commonly used functions of Renderer a lot easier to deal with.

Demo

Enough rambling.  I’ve implemented basic shapes in the toolkit, as well as very basic shape control.

Shapes.  Using the toolkit, I am able to ask for basic shapes.  Each shape has a fill colour, line colour and line width property.


Shapes Select.  I’ve also added picking functionality and shape control too.  When a user selects a fill/border of a shape, it will recognise it as a shape.  This is then decorated with a shape control.  This shape control has handles – these too are shapes.


Shapes Resize.  Clicking on a handle requires a couple of steps first before allowing to interact with it.  Although clicking on a border/fill will return the shape representing the handle, the handles act differently and need to be tested for.  Once this is done, we can notify the application that a handle is selected, not a shape.  This is important because if it was a shape, then the shape control will try to decorate the handle – clearly something that needs to be avoided.

Shapes Move.  clicking on a shape not only decorates it with a shape control, but it also allows you to drag and drop the shape too.


OOPhilosophy

Before this demo, I’ve had a lot of trouble creating similar objects. I’ve created bézier curves for the toolkit too, but I haven’t shown them because I ‘ve never been to happy with them.

If you recall from DrawCurve(Bézier);, near the end I was able to draw a master curve, encapsulating the bézier sub-curves.  To incorporate this into a scene graph, I needed an anchor, a node.  I did this by using a get property for the root of the curve.

public class Bezier : IRootNode
{
public Bezier()
{
RootNode = new Node(Matrix.Identity());
}

public INode RootNode { get; private set; }

private void CreateSubCurve()
{
var subCurve = new SubCurve();
RootNode.AddChild(subCurve.RootNode);
}

}

The problem with this is that once the Rootnode of the bézier curve is accessed, anything can be done with it.  A renderable can be assigned, all the children cleared, random children added.  It wasn’t very safe, and I never really did like it.

Why I never thought of simply inheriting from a model node in the first place, I’ll never know.  Not only does it allow me to change the node contents a lot easier, but it also means that I can change the interface, so that only a few select items can be modified.

public interface IShape
{
Colour FillColour { get; set; }
Colour BorderColour { get; set; }
double BorderThickness { get; set; }
}

internal class Shape : Node, IShape
{
public Shape(IFill fill, IBorder border) : base(Matrix.Identity())
{
Fill = fill;
Border = border;

base.AddChild((INode)Fill);
base.AddChild((INode)Border);
}

public Colour FillColour { get {…} set {…} }
public Colour BorderColour { get {…} set {…} }
public double BorderThickness { get {…} set {…} }

public IFill Fill { get; private set; }
public IBorder Border { get; private set; }

}

The only problem is that I have to cast from an IShape to an INode for when I want to add it to a graph, but at least the internals are protected from modification.  I suppose you could say someone could take an IShape and cast it into an INode and use it from there.  I guess there’s no stopping that.

Regardless, I’m finding it a lot easier to use the latter method than the former.  It took me only a week to create the shapes demo, but around two to get the bézier curves in the toolkit working.

Out of shape

Has anyone seen the statue designed for London 2012?  I thought I’d try and recreate it.  And if you ask me, I can’t say I’m particularly fond of it either.

Kapoor 2012.  Winning design for the London 2012 statue.  Apparently, it’s designed to stay.  No thanks.


OOP Kapoor 2012.  It might as well look like this.

As a side note, a couple of guys have released a rather nifty free tool, Paint.NET.  It’s a lightweight application that’s pretty much paint, but similar in the style and functionalities of Adobe Photoshop.  So those who can’t afford the extortionate prices of designer tools, well, I’d highly recommend giving it a try.   Did I also mention it’s free?

Advertisements

Posted in Computing, Placement | Tagged: , , , , , , , , , | Leave a Comment »

“{Binding OpenGl To WPF}” : Part 3

Posted by Robert Chow on 16/02/2010

So this is (hopefully) the last installment of my journey to creating my first WPF application using an OpenGl control.  You can find the first part here, and the second part here.  In this post, I am going to talk about where the magic happens behind a WPF form.

Model-View-View Model Pattern

So we have the GOF design patterns; these a best code practises and are just guidelines.  Similarly, there are also design patterns for implementing GUIs: Model-View-Presenter, Model-View-Controller and Model-View-View Model.  I don’t really know much about the former two, and I don’t claim to know too much about the MVVM pattern either, but it’s the one I am trying to use for developing my WPF applications.

In the pattern, we have the model, which is where all the code defining the application is; the view – this is the GUI; and the view-model, which acts as an abstraction between the view and the model.  The view is mostly written in XAML, and the view-model and model I have written in C#.  Technically, the view should never need to know about the model, and vice versa.  It is the view-model which interacts between the two layers.  I find it quite easy to look at it like this.

View Model Gear.  How the MVVM pattern may be portrayed in an image.  To be honest, I think the pattern should really be called the View-View Model-Model pattern, but of course, that’d just be stupid.  This image is from http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/CollectionsAndViewModels_EE56/.

Code Inline and Code Behind

You’ll notice for the majority of the time, I am using XAML to do most of the form.  The rest of the code that doesn’t directly interact with the view using the XAML is either code inline or code behind.  The code behind is essentially what we use to represents the view-model and the model.  The code inline is the extra code that is neither XAML or code behind.  It helps to define the view and is very rarely used, especially if the XAML can describe everything related to the view.  Incidentally, I used code inline at the start of the last post, where I defined a windows forms host using C# instead of doing it in the XAML.

In order to keep the intended separations of concerns in the MVVM pattern, the code behind has to interact with the view as little as possible, if not at all.  The flow of code should always travel in the direction of view to view-model, and never the other way round.  A way to do this is to introduce bindings.

Bindings

A binding in WPF is declared in the XAML and binds a XAML component to a property in the view-model.  In doing this, the component can take on the value specified in the view-model.  However, before we can create a binding, we have to form the connection between the view and the view-model.  To do this, we assign the view-model to the view data-context.  This is done in the logic in the code behind of the view.

/// <summary>
/// Interaction logic for Client.xaml
/// </summary>
public partial class Client : Window
{
public Client()
{
InitializeComponent();
this.simpleOpenGlControl.InitializeContexts();
this.DataContext = new ViewModel();

}
}

Having this data context means that the view can now relate to our view-model.

Now with the view-model in place, we can now bind components of the view to properties in the view-model.  Declare the binding in the XAML using the property name in the view-model.  The example depicts how I am able to retrieve the score in the demo to a label.

<Label Content={Binding Path=Score, Mode=OneWay, UpdateSourceTrigger=PropertyChanged} Grid.Row=“1” Grid.Column=“0” FontSize=“48” />

As you can see, the property I have bound to is “Score”, defined using Path.  The Mode and UpdateSourceTrigger properties are XAML defined enums to explain how we want the binding to relate to the property in the view-model.  Specifying that the binding is only OneWay tells the application that all we want to do is read the property value in the view-model.  This is usually TwoWay in cases such as a textbox where the user can edit a field.

The UpdateSourceTrigger is necessary.  Without this, the label content will never update.  As the code in the view is travelling in the direction of the view-model, there is minimum code going the other way.  As a result, the label content will not know if the value has changed in the view-model, and thus will not update.  To make sure the label content does update, we have to notify that the property value has changed.  To do this we have to implement an interface.

INotifyPropertyChanged

You can’t really get much closer to what it says on the tin than this.  Implementing this interface gives you an event handler, an event handler that “notifies” the XAML that a property has changed and will ask it to update accordingly.  Below is the code I have used to invoke a change on the property Score.

public event PropertyChangedEventHandler PropertyChanged;

public int Score
{
get
{
return this.score;
}
set
{
this.score = value;
OnPropertyChanged(“Score”);

}
}

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

As far as I’m aware, invoking the event with the property name tells the XAML that the value for the property with that particular name has changed.  The XAML will then look for that property and update.  As a result, it is vital that the string passed on is exactly the same as how the property is defined, in both the view-model and the XAML binding.

Invalidate

A problem I did come across was trying to invoke a method provided by a XAML component.  Using the simpleOpenGlControl, I need to invalidate the control so the image will refresh.  Of course, invoking this in the view-model directly would violate the MVVM model.  As a result, a little bit of logic was needed to solve this problem.

/// <summary>
/// Interaction logic for Client.xaml
/// </summary>
public partial class Client : Window
{
public Client()
{
InitializeComponent();
this.simpleOpenGlControl.InitializeContexts();
this.DataContext = this.viewModel = new ViewModel();

viewModel.SimpleOpenGlControlInvalidate = () => this.simpleOpenGlControl.Invalidate();
}

private ViewModel viewModel;
}

public class ViewModel : INotifyPropertyChanged
{
public Action SimpleOpenGlControlInvalidate
{
get;
set;
}

public int Score …

}

Assigning the method for use inside the view-model means that I can invoke this without having to go to the view, and therefore still keeping with the MVVM pattern.  Apparently, doing this causes a recurring memory leak, so when the view-model is finished with, you have to make sure that the action is nullified.

That pretty much concludes this 3-parter.  I’m sure there’ll be a lot more WPF to come in the near future, especially as I’m now trying to create all my future demos with it now.  It also means that I can use the XAML to create SilverLight applications too… or maybe not.

Posted in Computing, Placement | Tagged: , , , , , , , , , , , , , | Leave a Comment »

All Mapped Out

Posted by Robert Chow on 10/02/2010

So I went to the ESRI DeveloperHub conference yesterday to start out my research for the Mapper component.  Despite being held in Birmingham, I did feel like we were in Scotland.  The Scottish seemed to be everywhere – in the crowd and on the stage.

The first person I spoke to (is from, no awards for guessing where, Scotland) is in a similar company to IGI, dealing with oil and gas in the North Sea.  However, he isn’t part of the same background as I – he is a geochemist, and a map analyst.  Similarly, other attendees I spoke to are map analysts.  Yet I did come across a few developers.

Unfortunately for me, these developers specialised in working with and creating products using ArcGIS.  From what I learnt yesterday, this is a platform used for Geographic Information Systems, and is widely used in the majority of independent mapping applications.  With the start of the conference showcasing the new ArcGIS 10, I can now get a feel to what I am up against for when I come to create Mapper.  And yes, once again, there is a lot to do.  The rest of the day concentrated on using ArcGIS in server applications and wrapping it up in web-based APIs, such as Silverlight, JavaScript and Flex.  Although I did find this interesting at first, and rather attractive, I didn’t really get much out of it.  There were the odd moments of how an application could be and would be used, but for most of the time, there didn’t really seem to be much substance; the talks concentrated (very shallowly I’ll admit) on how each demonstration wrapped around the existing ArcGIS server platform to deliver the web-application.

From what I gathered, those working with ArcGIS were very attracted to projecting their current work using tools such as Silverlight, JavaScript and Flex; in fact the day ended with pretty much an advertisement on how ESRI provided training days on creating such applications.  Although interested, I wasn’t overly.  Not to mention I didn’t really know what GIS was until now.

All was not lost.  You know you’re a developer when you start laughing at something like this.

This Way To Java.  A sign posted for Java, Isle of Mull, Scotland. This image is from http://chillyinside.com/blog/

It was strange to see the level of developing that some people were coding at.  From the questions, they certainly knew their way around ArcGIS, and in terms of computer science, they seemed to know an awful lot more than me.  A lot of developers had heard of Python, and ArcGIS 10 was supporting it with ArcPy.  Yet despite more than 90% in the room as .NET developers, the majority had not heard of the Microsoft Design Patterns, in particular, the command pattern using the ICommand interface.

For the time being, I still want to complete both Grapher and Mapper before I finish my placement.  I think I can do it.  I am able to do it.

Posted in Computing, Placement | Tagged: , , , , , | 1 Comment »

“{Binding OpenGl To WPF}” : Part 2

Posted by Robert Chow on 03/02/2010

This is the second part of my journey to creating an application using WPF, wrapping the Renderer demo I made earlier. You can find the first part here.

Subconscious Intentions

So, initially in this post, I was going to introduce the concept of the model-view-viewmodel, and code inline and code behind.  Or at least, how I understand them.  Yet due to recent activity, that will have to wait till the next post.

The great thing about writing these blog posts is that in order for me to seem like I know what I’m doing, I have to do the research.  I’ve always been taught that during an exam, always answer the question as if the examiner doesn’t know anything about the subject bar the basics.  This way, you should answer the question in a detailed and chronological order, thus making complete sense and gaining full marks.  In a way writing these posts are quite similar.  Sure, I may have broken the rule more than a few times, especially when I’m rushing myself, but I try to explain the topics I cover in enough detail for others than myself to understand it.  After all, although I am writing this primarily for myself to refer back to for when I get stuck, it’s nice to know that others are benefiting from this blog too.

It’s not because I haven’t done the research that I can’t bring to the table what I know (or seem to know) about the model-view-viewmodel, code inline and code behind.  It’s because during the research and much tinkering around, that I thought I should cover the main drive for using WPF in the first place, and that is to incorporate an OpenGl control.

From Scratch

So a couple of weeks ago, I did actually manage to create an OpenGl control, and place it inside a WPF form.  The way I did this was a bit long-winded compared to how I used to, by creating it in a Win32 form.  Instead of using the SimpleOpenGlControl provided by the Tao framework, I went about by creating the control entirely from scratch.

For this, I could have done all the research, and become an expert at creating the control manually.  But that simply wasn’t my intention.  Luckily for me, the examples provided by Tao included the source code ,and a quick copy and paste, I more or less had the code ready and waiting to be used.

One thing I am more aware of now is that you need two things, a  rendering context and a device context.  The rendering context is where the pixels are rendered; the device context is the intended form for where the rendering context will sit inside.  Of course, the only way to interact with these are using their handles.

To create a device context in the WPF application, I am using a Windows Forms Host.  This allows you to host a windows control, which we will use as our device context.  The XAML code for this is relatively simple.  Inside the default grid, I have just inserted the WindowsFormsHost as the only child element.  However, for the windows control, I have had to take from a namespace other than the defaults provided.  To declare a namespace, declare the alias (in this case I have used wf, shorthand for windows forms) and then follow it with the namespace path.  Inside the control, we are also going to use the x namespace.  Using this, we can assign a name for the control, and thus allowing us to retrieve the handle to use as the device context.

<Window x:Class=“OpenGlControlInWPF.Client”
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml&#8221;
xmlns:wf=“clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms”
Title=“Client” Height=“480” Width=“640” WindowStyle=“SingleBorderWindow”>
<Grid ClipToBounds=“True”>
<WindowsFormsHost ClipToBounds=“True”>
<wf:Control x:Name=“control”/>
</WindowsFormsHost>
</Grid>
</Window>

With the form done, we can now dive into the code in the C# file attached to the XAML file.  It is here where we create the rendering context, and attach it to the device context.  I’m not really an expert on OpenGl at all when it comes to this kind of thing, so I’m not going to show the full code.  If you’re really stuck, the best place I can point you to is to look at NeHe’s first lesson, making an OpenGl window.  If you’re using the Tao framework and you installed all the examples, the source code should come with it.

The WPF interaction in the C# code is very minimal.  All we need to do with the XAML file is to retrieve the handle associated with the control we declared beforehand.  This is done simply by using the name we gave it in the XAML and letting Tao do the rest.  We hook this up to retrive a rendering context, and then we show the form.

Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();
// use this to create and describe the rendering context – see NeHe for details

IntPtr hDC = User.GetDC(control.Handle);
int pixelFormat = Gdi.ChoosePixelFormat(hDC, ref pfd);
Gdi.SetPixelFormat(hDC, pixelFormat, ref pfd);
IntPtr hRC = Wgl.wglCreateContext(hDC);
Wgl.wglMakeCurrent(hDC, hRC);

this.Show();
this.Focus();

All there is left to do is to go into the OpenGl loop of rendering the scene at each frame. Unfortunately, because I am used to the SimpleOpenGlControl provided by Tao, I’ve never needed to go into it whilst I’ve been on placement. All I had to do was to call simpleOpenGlControl.Invalidate() and the frame would automatically refresh for me.  As a result of this, I decided to place the draw scene method in a while(true) loop so the rendering would be continuous. And true to my thoughts, I knew this wouldn’t work.  As a result, the loop was “throttling” the application when running – I was unable to interact with it because all the runtime concentrated on rendering the scene – there was no interrupt handling so pressing a button or typing a key didn’t have any effect whatsoever.

I did try to look for answers to the throttling, and I stumbled across something else.  Another solution to hosting an OpenGl control in WPF.

The Better Solution

Going back to the first post of this multi-part blog, you might recall I am using a Canvas to host the OpenGl control.  I found this solution only a couple of days ago, due to a recent post on the Tao forums.  It uses this canvas in the C# code and assigns a WindowsFormsHost.  This in turn is assigned a SimpleOpenGlControl.  A SimpleOpenGlControl!  This means that I am able to use all the abstractions, methods and properties that the SimpleOpenGlControl has to offer without having to manually create my own.

First of we have to assign the canvas a name in the XAML code so we can reference it in the C# counterpart.

<Grid Background=“AliceBlue”>

<Border Grid.Row=“0″ Grid.Column=“0″ Background=“Black” BorderThickness=“1″ BorderBrush=”Navy” CornerRadius=“5″ Margin=“6, 6, 3, 3″>
<Canvas ClipToBounds=“True” Margin=“2″/ x:Name=“canvas”>
</Border>
</Grid>

The C# code for creating the SimpleOpenGlControl is short and sweet.  We create the WindowsFormsHost, attach a newly created SimpleOpenGlControl and attach the whole thing to the Canvas.  Here is the entire code for creating this.

namespace OpenGlWPFControl
{
using System.Windows;
using System.Windows.Forms.Integration;
using Tao.Platform.Windows;

/// <summary>
/// Interaction logic for Client.xaml
/// </summary>
public partial class Client : Window
{
public Client()
{
InitializeComponent();

this.windowsFormsHost = new WindowsFormsHost();
this.simpleOpenGlControl = new SimpleOpenGlControl();
this.simpleOpenGlControl.InitializeContexts();
this.windowsFormsHost.Child = this.simpleOpenGlControl;
this.canvas.Children.Add(windowsFormsHost);
}

private WindowsFormsHost windowsFormsHost;
private SimpleOpenGlControl simpleOpenGlControl;
}
}

Now we have the SimpleOpenGlControl set up, we simply just add the event for rendering and we’re nearly done. There is one problem however, and that is the windows forms host does not know what size to take. We add an event for when the canvas is resized to update the windows forms host size too.

public Client()
{

this.simpleOpenGlControl.Paint += new PaintEventHandler(simpleOpenGlControl_Paint);
this.canvas.SizeChanged += new SizeChangedEventHandler(canvas_SizeChanged);
}

void simpleOpenGlControl_Paint(object sender, PaintEventArgs e)
{
// do your normal opengl drawing here
this.simpleOpenGlControl.Invalidate();
}

void mainCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.windowsFormsHost.Width = this.canvas.ActualWidth;
this.windowsFormsHost.Height = this.canvas.ActualHeight;
}

A Revelation To An Even better Solution

So I said I was going to talk about other topics before delving into my journey of placing an OpenGl control inside a WPF application, and that’s because of what I found myself accomplishing last night.  In the first blog post of this multi-part series, I found myself using a Canvas to hold a Windows Forms Host, and in turn, to parent a SimpleOpenGlControl.  Yet with further understanding of WPF,  a revelation came.  The reason I was unable to insert a SimpleOpenGlControl directly into the application beforehand was because I wasn’t entirely aware of namespaces in XAML.  Soon after finding more about them, I find I am able to access the SimpleOpenGlControl by referencing Tao, and hence solving all the background work the C# had to do.

<Window
xmlns:tao=“clr-namespace:Tao.Platform.Windows;assembly=Tao.Platform.Windows”
…>
<Grid Background=“AliceBlue”>

<Border Grid.Row=“0” Grid.Column=“0” Background=“Black” BorderThickness=“1” BorderBrush=“Navy” CornerRadius=“5” Margin=“6, 6, 3, 3”>
<WindowsFormsHost Margin=“2” ClipToBounds=“True”>
<tao:SimpleOpenGlControl x:Name=“simpleOpenGlControl”/>
</WindowsFormsHost>
</Border>
</Grid>

So the only thing extra that to add to this is the event for rendering, which I included before. I can omit the need for having to resize the canvas, partially because there is now no canvas, and also because the WindowsFormsHost ClipTobounds property is true.

In the next part of this series I will hopefully be touching upon what I intended on touching upon in the first place, the model-view-viewmodel pattern.

Posted in Computing, Placement | Tagged: , , , , , , , , | 1 Comment »

“{Binding OpenGl To WPF}” : Part 1

Posted by Robert Chow on 02/02/2010

I’ll admit, it’s been a while.  But since I’ve been back, I’ve been working on a fair few things simultaneously, and they’ve taken a lot longer than planned.  But alas, here is one of them, in a multi-part blog.

Windows Presentation Foundation

Remember where I mention WPF a few times, but never really got into it?  Here’s a statement from the Microsoft website:

Windows Presentation Foundation was created to allow developers to easily build the types of rich applications that were difficult or impossible to build in Windows Forms, the type that required a range of other technologies which were often hard to integrate.”

Ha.

It’s not easy to develop on at all, especially for a developer just starting their first WPF project.  Not compared to creating a Win32 Form with a visual editor to say the least.

But it does allow you to build very rich applications that appeal to many by their look and feel alone.  And they look a lot better than Win32 forms too.

Remember that demo for Renderer?  I originally said I was going to try and incorporate fonts into it, but that’s still one bridge I have yet to cross.  Instead, I decided to learn a bit of WPF instead.  What do you think?

Demo In WPF.  Here I have incorporated the demo into a WPF form, and included panels on the right and bottom.  The right panel depicts the current state of the game, and allows the user to change the camera position and change the texture used when a cube face is picked.


Demo in Win32 Forms Mock.  I have included a mock of the original in a Win32 Form.  I think it’s fair to say the least that you would all rather use the WPF version.


XAML

The language of WPF is XAML, extensible-application-markup-language, and is very similar to XML.  It uses the open/close tag notation – one which I’m not particularly fond of, but it does mean that everything is explicit, and being explicit is good. Like all other languages, it’s very useful to know your ins and outs and what is available to use, and using XAML is no exception to this rule either. As a result, there are many ways, some better, some far worse, ways of creating the form I have made.  As I am no expert in this at all, I am going to leave it as it is, and take a look at the code I have generated for creating the form base.

To create this, I used Visual C# 2008 Express Edition.  This has proved rather handy as it updates the designer view as the code is changed.

Starting a WPF project gives you a very empty template.  With this comes 2 pieces of code, one in XAML and the other in C#.  For the time being, we are just going to concentrate on the XAML file.  This is where we create our layout.  The initial piece of XAML code is very simplistic, and doesn’t really mean too much.

<Window x:Class=“OpenGlWPFControl.Client”
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml&#8221;
Title=“Client” Height=“665” Width=“749”>
<Grid>
</Grid>
</Window>

The first few lines relate to the namespaces being used within the XAML file. The tags marked Grid relate to the box inside the window. This is a new concept different to the panels in a Win32 Form. Instead of having top, bottom, left and right panels, the grid can be split into a number of columns and rows using definitions.

Here I have split the grid into 4 components using 2 rows and 2 colums.  The code is relatively easy to deal with.  It also allows you to specify minimum, maximum and default dimensions.

<Grid Background=“AliceBlue”>
<Grid.RowDefinitions>
<RowDefinition Height=“*” MinHeight=“200”/>
<RowDefinition Height=“100”/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“*” MinWidth=“200”/>
<ColumnDefinition Width=“200”/>
</Grid.ColumnDefinitions>
</Grid>

Here, I have specified the default heights for each row and the default widths of each column.  The “*” is simply a marker to take what space is left.  As an extra,  I have also set the grid background colour.

Now that we have split the initial grid, we can now start to populate it.  This can be with other layout panels, like the grid, or a stackpanel or dockpanel and so forth to add extra layout details.  It can also be filled with more meaningful objects such as a label or a text box.

Starting off, I want to place the OpenGl control in the top-left panel.  For the time being, we are going to mock this using a Canvas.  This item will be used later in the C# code to attach the OpenGl control, but for the time being we are only handling XAML.  In addition, I have also decorated the canvas with a border.  Using a combination of the canvas and border properties, I have managed to achieve the rounded edges, making it more aesthetically appealing.

<Grid Background=“AliceBlue”>

<Border Grid.Row=“0” Grid.Column=“0” Background=“Black” BorderThickness=“1” BorderBrush=“Navy” CornerRadius=“5” Margin=“6, 6, 3, 3”>
<Canvas ClipToBounds=“True” Margin=“2”/>
</Border>
</Grid>

This piece of code stays within the Grid tags, as it is a grid child.  For where in the grid it sits, I have explicitly stated which row and column of the grid it sits inside the Border tag.

The bottom panel is done in a similar fashion, only this time the border decorates a textblock.  In order to scroll a textblock, this itself needs to be decorated using a scroll viewer.

<Grid Background=“AliceBlue”>

<Border Grid.Row=“1” Grid.Column=“0” Grid.ColumnSpan=“2” Background=“White” BorderThickness=“1” BorderBrush=“Navy” CornerRadius=“5” Margin=“6, 3, 6, 6”>
<ScrollViewer Margin=“2”>
<TextBlock/>
</ScrollViewer>
</Border>
</Grid>

There is only small change which we have to do so the panel is not confined to one grid space. This is done using the Grid.ColumnSpan property.

Now with only one panel left, I have decided to make my life that little easier by adding in extra grids.  These are done in the exact same way as the initial grid.  Using what I have done already, and combining it with new elements, the last panel is added.

<Grid>

<Border Grid.Row=“0” Grid.Column=“1” Background=“White” BorderThickness=“1” BorderBrush=“Navy” CornerRadius=“5” Margin=“3, 6, 6, 3”>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“*”/>
<RowDefinition Height=“30”/>
<RowDefinition Height=“30”/>
<RowDefinition Height=“60”/>
</Grid.RowDefinitions>
<Grid Grid.Row=“0”>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row=“0” HorizontalAlignment=“Left” VerticalAlignment=“Bottom” FontSize=“36” Content=“Score:”/>
<Label Grid.Row=“1” HorizontalAlignment=“Right” VerticalAlignment=“Top” FontSize=“48” Content=“0”/>
</Grid>
<Grid Grid.Row=“1”>
<Grid.RowDefinitions>
<RowDefinition Height=“50”/>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“Auto”/>
</Grid.RowDefinitions>
<Label Grid.Row=“1” HorizontalAlignment=“Left” VerticalAlignment=“Bottom” FontSize=“24” Content=”Lives:”/>
<Label Grid.Row=“1” HorizontalAlignment=“Right” VerticalAlignment=“Bottom” FontSize=“24” Content=“0”/>
<Label Grid.Row=“2” HorizontalAlignment=“Left” VerticalAlignment=“Bottom” FontSize=“24” Content=“Level:”/>
<Label Grid.Row=“2” HorizontalAlignment=“Right” VerticalAlignment=“Bottom” FontSize=“24” Content=“0”/>
</Grid>
<Label Grid.Row=“3” HorizontalAlignment=“Center” VerticalAlignment=“Bottom” Content=“Camera Position”/>
<Grid Grid.Row=“4”>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column=“0” Margin=“15,0,15,0” Content=“&lt;&lt;”/>
<Button Grid.Column=“1” Margin=“15,0,15,0” Content=“>>”/>
</Grid>
<Button Grid.Row=“5” Margin=“15,15,15,15” Content=“Change Texture”/>
</Grid>
</Border>
</Grid>

As a result, we achieve a form created entirely from XAML.

Unfortunately however, there is no logic behind this. In part 2, we start looking at the other parts of the code and insert an OpenGl control into the application.

Posted in Computing, Placement | Tagged: , , , , , , , | 2 Comments »

ConfusedEventHandler += (s, e) => ConfusedEventHandler(Me.Extend(s, e));

Posted by Robert Chow on 21/01/2010

So I’ve just been informed that there are a couple more additions to event handling in .NET.

Before notifying an event handler of any new events, you MUST always check to see if it is null.  If it is, then don’t send any events – apparently you get really messed up runtime errors.

Secondly, you can subscribe to an event handler using a lambda method too – it’s quite a pretty neat trick.  As a result, it also allows you to subscribe more than the one method to the event handler.

Here’s the code for the main part of the demo, but rewritten to accomodate the two factors.  I’ve also added in the functionality of one of the subscribers being taken away part way through the program.

public class Program
{
public static event IncreaseNumberEventHandler numberIncreasedEventHandler;

public static IncreaseNumberEventHandler n52Subscribe;

public static void Main(string[] args)
{
public static Number n27 = new Number(27);
public static Number n39 = new Number(39);
public static Number n52 = new Number(52);
numberIncreasedEventHandler += (s, e) => {n27.Increase(s, e); n39.Increase(s, e);};
numberIncreasedEventHandler += (n52Subscribe = (s, e) => n52.Increase(s, e));

Run();
}

public static void Run()
{
for (int i = 0; i < 10; ++i)
{
if (i == 5)
{
numberIncreasedEventHandler -= n52Subscribe;
}
if (numberIncreasedEventHandler != null)
{
numberIncreasedEventHandler(null, new IncreaseNumberEventArgs(i));
}
}
}
}

And the output:

n27: 27 increased by 0 to 27
n39: 39 increased by 0 to 39
n52: 52 increased by 0 to 52
n27: 27 increased by 1 to 28
n39: 39 increased by 1 to 40
n52: 52 increased by 1 to 53
n27: 28 increased by 2 to 30
n39: 40 increased by 2 to 42
n52: 53 increased by 2 to 55
n27: 30 increased by 3 to 33
n39: 42 increased by 3 to 45
n52: 55 increased by 3 to 58
n27: 33 increased by 4 to 37
n39: 45 increased by 4 to 49
n52: 58 increased by 4 to 62
n27: 37 increased by 5 to 42
n39: 49 increased by 5 to 54
n27: 42 increased by 6 to 48
n39: 54 increased by 6 to 60
n27: 48 increased by 7 to 55
n39: 60 increased by 7 to 67
n27: 55 increased by 8 to 63
n39: 67 increased by 8 to 75
n27: 63 increased by 9 to 72
n39: 75 increased by 9 to 84

Posted in Computing, Placement | Tagged: , , , , , , , , , | Leave a Comment »

ConfusedEventHandler += new ConfusedEventHandler(Me.Confused);

Posted by Robert Chow on 20/01/2010

… Or at least that’s how I first felt when I started looking at event handling in .NET.

And I still do slightly – I’ve literally just looked at this 10 minutes ago, and I’m writing this down now while it’s still fresh in my head.

Observer Pattern

The observer pattern uses the notion of an Observer interface.  The state of each object that implements this can be updated through the interface.  The idea of using this interface allows a publisher to update all the objects in one swift movement.  Obviously, only those that are referenced by the publisher can be updated – those that are, are known as subscribers.  This design pattern is also a subset of the publish/subscribe pattern – any object that is subscribed will recieve any notifications sent by the publisher.

Publish/Subscribe.  A publisher sends events to subscribers.  This image has been taken from http://msdn.microsoft.com/en-us/library/ms978603.aspx.

So yesterday, I set about creating my own observable pattern implementation.  Yet today I learnt that there is a .NET implementation using events.

Event Handling

So with a little help from Microsoft and a lot more help from CodeProject, I’m going to try and explain to myself how to use them.

We start of with declaring the publisher.  The publisher contains a list of all the methods that should be invoked when an event is recieved.  This is done using 2 keywords and the name.

event EventHandler eventHandler;

event – declares that this is an event handler.
EventHandler – this is the default delegate type for event handlers.  This 2nd keyword must always be a delegate type it seems.

To add a subscriber, this is relatively simple.

eventHandler += new EventHandler(method);

+= – this symbol implies that we are wanting to subscribe a method to the event handler.  Similarly, to unsubscribe use the -= operator instead.
method – this is the method to be invoked when the publisher recieves an event to be sent on.

So now that we have a publisher and subscribers, lastly is to send an event to the publisher so it can pass it on to the subscribers.

eventHandler(sender, new EventArgs());

sender – the object that sent the event.  This is not compulsory and can be null.
new EventArgs() – event arguments for the event just occurred.  Again, this is not compulsory and can be null.  The methods subscribed to the publisher can always be invoked regardless of event arguments.

It’s actually fairly easy really once you get your head around it – at first I got hurrendously confused because I kept seeing “event” everywhere.

And of course, the sample I’ve just shown is fairly useless – it’s a lot more useful when you use your own delegate type as the event handler in conjunction with your own event arguments – most probably derived from EventArgs.

Increase Number Event

Below is a simple demo I’ve made just to make it a little more understandable, and it was also particularly useful when I was trying to figure it all out.  It uses a publisher, numberIncreasedEventHandler, whereby the Number objects n27, n39, n52 all have their Increase method subscribed.  This is invoked during Run, passing on an IncreaseNumberEventArgs which increases each object by the number contained in the argument.

public delegate void IncreaseNumberEventHandler(object sender, IncreaseNumberEventArgs e);

public class IncreaseNumberEventArgs : EventArgs
{
public int Increase;

public IncreaseNumberEventArgs(int increase)
{
this.Increase = increase;
}
}

public class Program
{
public static event IncreaseNumberEventHandler numberIncreasedEventHandler;

public static void Main(string[] args)
{
Number n27 = new Number(27);
Number n39 = new Number(39);
Number n52 = new Number(52);
numberIncreasedEventHandler += new IncreaseNumberEventHandler(n27.Increase);
numberIncreasedEventHandler += new IncreaseNumberEventHandler(n39.Increase);
numberIncreasedEventHandler += new IncreaseNumberEventHandler(n52.Increase);
Run();
}

public static void Run()
{
for (int i = 0; i < 10; ++i)
{
numberIncreasedEventHandler(null, new IncreaseNumberEventArgs(i));
}
}
}

public class Number
{
int number;
string name;

public Number(int initialNumber)
{
this.number = initialNumber;
this.name = “n” + initialNumber;
}

public void Increase(object o, IncreaseNumberEventArgs e)
{
Console.WriteLine(name + “: “ + number + ” increased by “ + e.Increase + ” to “ + (number += e.Increase));
}
}

And the output:

n27: 27 increased by 0 to 27
n39: 39 increased by 0 to 39
n52: 52 increased by 0 to 52
n27: 27 increased by 1 to 28
n39: 39 increased by 1 to 40
n52: 52 increased by 1 to 53
n27: 28 increased by 2 to 30
n39: 40 increased by 2 to 42
n52: 53 increased by 2 to 55
n27: 30 increased by 3 to 33
n39: 42 increased by 3 to 45
n52: 55 increased by 3 to 58
n27: 33 increased by 4 to 37
n39: 45 increased by 4 to 49
n52: 58 increased by 4 to 62
n27: 37 increased by 5 to 42
n39: 49 increased by 5 to 54
n52: 62 increased by 5 to 67
n27: 42 increased by 6 to 48
n39: 54 increased by 6 to 60
n52: 67 increased by 6 to 73
n27: 48 increased by 7 to 55
n39: 60 increased by 7 to 67
n52: 73 increased by 7 to 80
n27: 55 increased by 8 to 63
n39: 67 increased by 8 to 75
n52: 80 increased by 8 to 88
n27: 63 increased by 9 to 72
n39: 75 increased by 9 to 84
n52: 88 increased by 9 to 97

I think I’m fairly calm and a lot less confused now…

(Before you say anything, yes I am aware that the code’s snazzed up a bit – it wasn’t the most readable at first, especially when there’s a massive chunk of it…)

Posted in Computing, Placement | Tagged: , , , , , , , , , | 1 Comment »