C# transition between GDI+ and WPF

35

Solution 1

(I apologize in advance for the long post ... there was just so much I wanted to convey ... I hope it helps you.)

This is what we are doing now (migrating a Windows Forms application with heavy use of custom (GDI+) drawn controls to WPF). In fact, my role on the team was to build these GDI+ controls ... and now to build the WPF ones.

I agree with Bijington that making your application completely 100% WPF from the ground up is the way to go ... if you can convince the powers that be to go that route. However, we ourselves are converting our Windows Forms application in-place, taking advantage of the WPF interop capabilities. There are some limitations, but overall it has been an effective approach (and not as frustrating as I would have expected).

What I would suggest is that you take one of your GDI+ controls and build the same control in WPF. And then, when you are finished, throw it away and do it again. You will invariably learn something during the first effort ... and discover that there is a better way to do it instead. I would start with something small ... a custom button is a good place to begin.

Doing the above will give you a taste for what is going to be required for everything else you want to do.

One thing I would warn you about is WPF's learning curve, especially if you are coming from a Windows Forms background ... and especially if you are going to be building custom looking controls. As Abe has mentioned, it is a completely different world. WPF definitely brings a lot of power, but that power comes at a cost of learning how to use it. Abe mentions how custom controls in WPF are 'lookless' and that their 'look' can be provided with a ControlTemplate. This is just one of many ways in WPF to provide custom looking pieces of your user interface.

Let me enumerate some of those additional ways:

  1. Style an existing control using the styling capabilities of WPF.
  2. Take advantage of WPF's content model and/or controls derived from ContentControl. This allow you to stick arbitrary looking 'content' into visuals of a control (e.g. maybe sticking a custom drawn shape into the middle of a button).
  3. Compose a control out of other controls/elements by taking advantage of UserControl.
  4. Derive from an existing control/class in WPF, extending it's behavior and providing a different default set of visuals.
  5. Derive from FrameworkElement, creating a custom WPF element, by overriding some or all of the MeasureOverride, ArrangeOverride, and OnRender methods.
  6. And more .... if you can believe it.

In Windows Forms, it was like they gave you a hammer (UserControl) and a screwdriver (Control). However, in WPF ... they have given you the whole toolbox with all 100 tools. And this is part of the reason for the bigger than normal learning curve. However, now you can take that saw that you never had before and use it to saw off the end of a 2x4 instead of using the hammer and/or screwdriver to try and do the same thing.

Resources

(The good news is that there are a lot out of resources out there to help you.)

  1. Books
    • Programming WPF by Chris Sells & Ian Griffiths (in particular, chapter 18)
    • Pro WPF by Matthew MacDonald (in particular, chapter 24)
    • WPF Unleashed by Adam Nathan (in particular, chapter 16)
    • Applications = Code + Markup by Charles Petzold (in particular, chapters 10, 11, & 12)
    • Essential WPF by Chris Anderson (in particular, chapter 3)

      My favorite books are Charles Petzold's book and Adam Nathan's book. However, chapter 18 of Programming WPF by Sells & Griffiths is really great overview of the subject, and in particular coverage of the question: Do I really need a custom control?
  2. Forums
    • The WPF Forum
    • StackOverflow
      Here are two posts in particular that you will want to take a look at (one, two).
  3. MSDN
    I agree with Bijington that the MSDN documentation excellent.

  4. Blogs
    In one of the two StackOverflow posts that I reference in the Forums section above, I point to a set of blogs on my 'must read' list. In particular, I would especially point to the blogs of Pavan Podila and Kevin Moore. Kevin Moore used to be the WPF program manger for the WPF controls and he has a nice set of controls called the WPF Bag-o-Tricks that are useful, but more importantly, controls that you can learn from.

  5. Samples, Samples, and more Samples
    There are just a ton of samples out there. Almost too many! I would point to Family.Show (it was created as an end-to-end reference sample for WPF) and I would point to the WPF SDK samples and in particular to the Control Customization samples within that section.

Solution 2

There is a paradigm shift in how you develop controls for WPF. Instead of defining all the behavior and look for a control, you only define the intended behavior.

This is the hardest aspect of migrating to WPF. Your control class defines a contract of behavior, and exposes properties that will be used to render, and a ControlTemplate is used to define how the control looks.

This is also one of the most powerful features of WPF; at any point in the future, a consumer of your control can change how it looks without changing how it behaves. This allows for much easier theming of your controls.

Solution 3

This is actually a project i am working on at the moment although I have been lucky enough to be able to start again. If you can do this I would strongly recommend it, obviously keeping the core functionality of the old system/controls but start afresh. It is always nice to start from a base and to know where things went wrong/right previously.

Personally i have found the msdn website extremely useful, if not stackoverflow is a very good place for knowledge. I would be happy to give pointers if you need any.

Also if you ever have any questions about databinding this is the place to go: bea costa she has covered most stuff there.

On an extra note we have experienced a huge improvement in performance with using wpf over GDI.

Share:
35

Related videos on Youtube

Serg
Author by

Serg

Updated on April 16, 2022

Comments

  • Serg
    Serg about 2 years

    I have a anonymous function that is running in onconnect event. How to call my function OnConnect() instead anonymous function ?

    $this->server->on("connect", function (WebSocketTransportInterface $user) {
                $this->Logger->notice((" Connected " . $user->getIp()));
            });
    

    And

    public function OnConnect(WebSocketTransportInterface $user) {
        $this->Logger->notice((" Connected " . $user->getIp()));     
    }
    

    Something like

     $this->server->on("connect", OnConnect($user));
    
    • cplotts
      cplotts over 15 years
      I would be curious to know if you decide to take the leap into WPF ... and why or why not. And if you do, what your experience is after you have done it for a little bit. It would be great if you posted back here with that ... just an idea.
  • cplotts
    cplotts over 15 years
    The retained mode composition system in WPF does bring some compelling performance advantages ... in most situations.
  • serg10
    serg10 over 15 years
    Nice answer. Lots of detail. I am about to embark on a simillar project, so this is very useful. +1 cplotts.
  • cplotts
    cplotts over 15 years
    Thanks, I appreciate the compliment. I have felt the pain of changing my Windows Forms mindset into a WPF one ... and want to help others avoid as much of it as possible.
  • Roman Starkov
    Roman Starkov over 12 years
    And then, when you are finished, throw it away and do it again - I used to do this a very long time ago in Basic, but definitely not anymore... I suggest that you don't throw it away; C# + VS are extremely clean-up friendly. Clean it up instead. This takes much less time in my experience.