Blog Has Moved

December 8, 2008

This blog is no longer being maintained. Please update your links to the following url.

http://dotnetgui.blogspot.com/

March 3, 2008

Question:

“I have been working with Windows Forms for a long time. I have a lot of good Winforms user controls that I want to keep using, but I would like to start using WPF to create better user interfaces. Is this an all or nothing deal? Can I create Winforms apps which use some WPF controls or WPF apps which use some of my existing Winforms controls?”

 

 

Answer:

No. This is not an all or nothing deal. You can leverage WPF in your existing Winform applications and vice versa.

Embedding a Winforms control in a WPF application:

  1. Add references to System.Windows.Forms and WindowsFormsIntegration dlls.
  2. Add a reference to the dll containing the Windows Form control you are going to be placing in your WPF app.
  3. Add a new xml namespace (xmlns) attribute to the root element of your xaml document … (usually a Window element)


    <Window

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

    . . .

     xmlns:zed=”clr-namespace:ZedGraph;assembly=ZedGraph”  

    In this example I am inserting a ZedGraph control. It is third party control used to graph out the movements of a Wiimote device. The class defined in the ZedGraph assembly which is in the ZedGraph namespace. I am using zed as a shorthand to reference that assembly.

  4. Add a WindowsFromsHost element in the panel where you want to insert your Winforms control.
  5. Add your Windforms control as the content of that WindowsFormsHost element.

     <WindowsFormsHost>

    <zed:ZedGraphControl x:Name=”graphControl”/>               

    </WindowsFormsHost>

    Warning:  If you have the attribute AllowsTransparency=True on the root Window element, the WindowsFormsHost will not be displayed. You will not get any compiler errors, but the content will simply not be displayed. The way WPF handles transparency is not supported by Windows Forms, so if the window allows transparency, the Winforms content cannot be properly rendered… I learned this the hard way. It took a while to figure out why my controls weren’t displaying on my GUI!

    Embedding a WPF control in a Winforms application:

 First, add ElementHost to the VisualStudio Toolbox going to the Tools menu and selecting Choose Toolbox Items.  A dialog is shown with a  list of controls that can be added to the toolbox. Make sure ElementHost is checked and click Ok.

Note: By dragging the ElementHost on to the form using the Winforms designer, Visual Studio automatically adds references to the necessary references to the necessary WPF assemblies like PresentationFramework.dll, PresentationCore.dll, etc.

 

  1. Drag an instance of the ElementHost control on to your Winforms application wherever you wish to insert WPF content.
  2. Create your WPF content (in the code behind) and set it as the Child of your ElementHost object.

    public

    Public Form1()

    {

    InitializeComponent();

    //Create WPF Content

    Viewer viewer = new Viewer();

    elementHost.Child = viewer;

    }

    Note: Viewer is a User control I created in WPF. In order for me to use it I added a reference to the assembly where the Viewer control was defined. In the above example, I also named the instance of the ElementHost object I placed on the GUI as elementHost.

How Do You Change the Cursor of a WPF App?

February 20, 2008

Changing the cursor of a WPF app is pretty simple. You can do it through procedural code as follows:

this.Cursor = Cursors.None;

There are several built in cursors such as a pen, cross, scroll, etc. You can also use a custom cursor as follows:

this.Cursor = new Cursor("CustomCursorImage.jpg"); 
Because Cursor is a dependency property, it can also be used in XAML. Here are two  examples on how to use custom cursors via XAML:

<Button Content="Wait" Cursor="Wait"/><Button Content="CustomCursorImage.jpg"/>

A Few WPF Dos and Don’ts

February 14, 2008

Do Not… Use absolute positioning

When laying out a UI, try to minimize the use of the Canvas panel. This panel uses absolute positioning. Using absolute positioning is not a very flexible way of laying out UIs. It is better to use relative positioning. This aids in localization of applications because the application can adapt to changes in size, and flow direction of the application. A Grid control is a much better choise for a localized application’s layout panel.

Do Not… Set a fixed size for GUI components 

Instead of setting an element’s size explicitly, use the margin, padding, and alignment properties. This allows the controls to size according to their content, which is desirable when creating globalized applications. When possible, provide extra space in margins to better accommodate longer strings.

Do… Use the appropriate visibility 

There are three values which may be used for an object’s visibility – Visibility.Visible, Visibility.Hidden and Visibility.Collapsed.

Visibility.Visible maps to visible = true. This means the object will be drawn on the screen.

Visibility.Collapsed maps to visible=false. When an object’s visibility is set to collapsed, it is not drawn on the screen. The area it would originally take up is collapsed.  For increased performance, it is recommended to use collapsed over hidden whenever possible.

Visibility.Hidden maps to visible=true. When an object’s visibility is set to hidden, it is not removed from its container. It still occupies the same area, but it is not visible. If the object is a large, complex object, you may notice a performance increase by hiding the object with Visibility.Collapsed instead of Visibility.Hidden.

Do… Use only one level of interoperability 

Although it is possible to host a WPF control inside a Win32 control which is in turn hosted inside a WPF application and vice-versa, it is not recommended.  Microsoft suggests keeping the level of interoperability to one (a WPF control hosted in a Win32 application or a Win32 control hosted in a WPF application). The way events are handled and messages queued is only intended to support a single level of interoperability. Messages and/or events may be lost or mishandled if more interoperability levels exist.

Do… Know the difference between Binary Resources and Logical Resources 

WPF introduces the concept of logical resources. They should not be confused with binary resources. Binary resources are what the rest of the .Net Framework considers a resource. These are traditionally items like image, video and audio files.  Logical resources are WPF-specific. Logical resources are .Net objects that can be stored within an element’s ’Resources’ property. This property is of type System.Windows.ResourceDictionary. Logical resources are typically used to define styles and templates. 

Do Not… Use the Embedded Resources build action 

Visual Studio provides several ways for defining the Build Action of a file that has been added to a project. If you are used to writing Windows Forms applications, you may be tempted to use the Embedded Resource Build Action. This is the appropriate method for embedding resources in a Windows Forms project. However, resources embedded with this build action cannot be referenced by XAML. The two relevant Build Actions for WPF include ‘Resource’ and ‘Content’.  The first embeds the resource into the assembly while the latter leaves it as a loose file but records the existence and relative location of the file.


Follow

Get every new post delivered to your Inbox.