Introduction
I’ve been looking for quite a while on the Internet for programmers writing WPF applications in Eiffel. There is a lot of literature on WPF (the Windows Presentation Framework), but nothing that would explain how to use the Eiffel language to make one.
So here I come, and I hope this first article will help you getting started if you want to try it.
C# is clearly the best choice for WPF applications, and unless you’re an Eiffel fan there is no good reason to avoid C#. Eiffel is best for writing maintainable and reusable software, use it for the bulk of your application. Use C# for the user interface layer with WPF. However, if the user interface part of your application is simple, you might prefer to use Eiffel for everything.
Getting started
To get started, you’ll need to install EiffelStudio (currently 6.4) and a C complier (EiffelStudio requires one). I selected Visual Studio 2008 because I can create WPF programs in C# and investigate how it works, then try to obtain the same result with EiffelStudio.
You also need to install the .NET framework. I’m on Vista so I don’t really need it, but installed .NET 3.5 SP1 nonetheless.
There are other Eiffel compilers, but I don’t know much about them. If you don’t use EiffelStudio you’re welcome sharing your experience here!
Our first program
First of all, let’s create a WPF “Hello, World!” program to see how it looks. Visual Studio has a wizard for that, just do the following:
- Open Visual Studio, close any solution that could have been loaded at startup, select the File menu and Choose New / Project.
- In the Project wizard, select Visual C# on the left and WPF applications on the right. Give your application a name, for instance WpfSample and choose a location, where Visual Studio will create your program. Click OK, after a minute the solution is ready.
- In the Solution Explorer pane, double click on “Windows1.xaml” to bring up the Xaml designer (if not done automatically already), it should show an empty window in the design pane and the following lines in the window pane:

- Insert the following line into the grid element:

- Press F5 to save your work, compile and execute the program. It should pop a window looking like this:

Now, our goal is to do the same with EiffelStudio. It’s not an easy task, and while I could just give you the code sample, I will instead show you what happens if we follow the naive approach.
EiffelStudio doesn’t have a wizard for WPF applications, but has one for .NET, so let’s use it.
- Close the sample, close Visual Studio and open EiffelStudio. If you’re on Vista, I recommend starting it as administrator, at least for the first time, or some objects don’t compile.
- Select the File menu and New project. You might have the project dialog already up, if so just jump to the next step directly.
- Select a .Microsoft NET project and click Create.
- In the wizard, set the application name as WpfSample et select a location where to create the program, click Next.
- Change the root class name to APP, click Next then Finish.
This will create our sample application. It might take a few minutes if you’re creating a .NET application for the first time. At this stage, our sample cannot use WPF because only the core .NET objects are available in the project. If we want to have access to more, we need to include them, like you would include a library. In the .NET world, this is done by adding “assemblies”, a digest of grouped object interfaces. This step is pretty easy, since the list of assemblies is immediately visible in the project:

Right-click the assemblies node to bring up a context menu and select “add assemblies”, to pop up the assemblies selection window:

WPF stands for Windows Presentation Framework. If you look closely to the list you will see the following lines:
- PresentationBuildTasks
- PresentationCore
- PresentationFramework
- PresentationFrameworkAero
- PresentationFrameworkClassic
- PresentationFrameworkLuna
- PresentationFrameworkRoyale
PresentationFramework is probably the assembly we are looking for, and PresentationFrameworkAero etc. interfaces for specific UI design. Let’s select PresentationFramework and click OK.
Theoretically, this should make the APPLICATION class available to us like it is in C# (identifiers are not case-sensitive in Eiffel). And indeed, the following code now compiles:
class APP inherit APPLICATION rename make as make_app end create make feature {NONE} -- Initialization make -- Run application. do make_app end end
However, if we try to execute it we get a “System.InvalidOperationException” that tells us there can be only one instance of the Application class in the same AppDomain.
Now that w have started running into issues with the .NET framework, it’s probably a good time to review the documentation available to us. I found this links: http://docs.eiffel.com/book/platform-specifics/net (a review of the .NET support in EiffelStudio). And there is of course http://msdn.microsoft.com the online documentation for Microsoft products. You can type “WPF <class name> class” in the search engine to easily find information about a class.
The page for the Application class confirms what the exception message states.
“Application implements the singleton pattern to provide shared access to its window, property, and resource scope services. Consequently, only one instance of the Application class can be created per AppDomain.“
After struggling with the environment, I eventually figured that you can’t inherit from APPLICATION. But you can create an instance of that class in your root class and use it as a starting point. Here is the modified code:
class APP create make feature {NONE} -- Initialization make -- Run application. local main_app: APPLICATION do create main_app.make end end
Of course, this code doesn’t do much but at least it works!
Adding a window
Looking closely, the APPLICATION class has a run method taking a window object as argument. If we can create it, there is a good chance it will display the window and return when it’s closed. So, our next step is to create that window object.
First, let’s add a new class to the project like Visual Studio does.
class WINDOW1 inherit WINDOW rename make as make_window end create make feature {NONE} -- Initialization make -- Our window do make_window end end
And let’s create the window object then call run.
class APP create make feature {NONE} -- Initialization make -- Run application. local main_app: APPLICATION main_win: WINDOW1 status: INTEGER do create main_app.make create main_win.mak status := main_app.run(main_win) end end
Problem: when the main_win object is created, an exception is thrown: “Declaration referenced in a method implementation can not be a final method ”. A search on the net for this error led me to the following page:
http://support.microsoft.com/kb/315528.
Again, I tried to fix the problem but eventually gave up. I just used a different approach which is to just create an object of the base WINDOW class. Just replace “main_win: WINDOW1” with “main_win: WINDOW”, remove the WINDOW1 class from the project, then recompile and run.
But we get a new exception: “System.InvalidOperationException: The calling thread must be STA ”.
Fixing the threading model
If you didn’t know yet, a thread in the .NET environment can be either in single-threading apartment (STA) mode or multi-threading apartment (MTA) mode. The WPF graphic engine requires STA, and unfortunately EiffelStudio creates the main thread with no apartment mode.
In C#, the problem is easily fixed by adding the [STAThread] attribute to the class. Since doing it in Eiffel is out of our league for now, let’s change the mode in the code before we call the run method:
feature {NONE} -- Initialization make -- Run application. local main_app: APPLICATION main_win: WINDOW status: INTEGER main_thread: SYSTEM_THREAD do create main_app.make create main_win.make main_thread := {SYSTEM_THREAD}.current_thread main_thread.set_apartment_state({APARTMENT_STATE}.sta) status := main_app.run(main_win) end end
Curiously, that code doesn’t work, we still get the same exception. It seems that the current thread mode cannot be changed. Fortunately, the current thread has nothing special that forces us to keep it, therefore we can create a new thread with the appropriate mode and use it as our true main thread, like this:
class APP create make feature {NONE} -- Initialization make -- Run application. local start: THREAD_START thread: SYSTEM_THREAD do create start.make(current, $ui_thread) create thread.make(start) thread.set_apartment_state({APARTMENT_STATE}.sta) thread.start end ui_thread -- Application main thread local main_app: APPLICATION main_win: WINDOW status: INTEGER do create main_app.make create main_win.make status := main_app.run(main_win) end end
And it works!
So, what about some XAML now?
Of course, it doesn’t say “Hello, world!” yet. At this stage, we have the option of adding the grid and the label from the code, or do it in some XAML script that the window would load. Only with the second approach would we make a true WPF sample, so we should try that. Fortunately, there yet another option that is more powerful: the XAML_READER class. An instance of this class can load XAML data, parse it and return an object of the type specified in the data. For instance, in the root element in XAML is <window… /> it will return a reference to an object of class WINDOW.
One thing to take into account is that XAML_READER reads streams, so we first need to read the XAML file and turn it into a stream. This can be accomplished with the FILE_STREAM class, obviously (this one didn’t take me long to figure out, fortunately).
Let’s see how it looks:
local fstream: FILE_STREAM main_win: WINDOW do create fstream.make_from_path_and_mode("Window1.xaml", {FILE_MODE}.open) fstream.flush main_win ?= {XAML_READER}.load(fstream)
So easy… This code reads the same XAML file as the C# file. Here is how the XAML file looks like:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPF Sample" Width="200" Height="100" > <Grid> <Label Width="75">Hello, world!</Label> </Grid> </Window>
Interestingly, the same code works for the APPLICATION class. We can create a XAML file looking as below:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x="http://schemas.microsoft.com/winfx/2006/xaml" > </Application>
And in the code create the application object the same way we created the window object:
local main_app: APPLICATION fstream: FILE_STREAM do create fstream.make_from_path_and_mode("App.xaml", {FILE_MODE}.open) fstream.flush main_app ?= {XAML_READER}.load(fstream)
Conclusion
And here is the final code, along with a screenshot of the execution result:
note description: "Project root class" class APP create make feature {NONE} -- Initialization make -- Run application. local start: THREAD_START thread: SYSTEM_THREAD do create start.make(current, $ui_thread) create thread.make(start) thread.set_apartment_state({APARTMENT_STATE}.sta) thread.start end ui_thread -- Application main thread local fstream: FILE_STREAM main_app: APPLICATION main_win: WINDOW status: INTEGER do create fstream.make_from_path_and_mode("App.xaml", {FILE_MODE}.open) fstream.flush main_app ?= {XAML_READER}.load(fstream) create fstream.make_from_path_and_mode("Window1.xaml", {FILE_MODE}.open) fstream.flush main_win ?= {XAML_READER}.load(fstream) status := main_app.run(main_win) end end

To be continued…
In my next posts, I will investigate how to make some progress with WPF:
- Handling events,
- Taking XAML data from resources instead of files,
- Adding attributes to objects,
- Inheriting from WINDOW and APPLICATION…
and much more!