Help! Going mad.... (WPF Development)


(Bob Russell) #1

Please forgive this plea for help - I’ve been using WPF for development for the past few months and have concluded that my Ex Delphi experience has excluded me from some fundamental knowledge…

I know this should probably be directed to the general C# forums, but the RemObjects community has been so helpful over the past months, so …

I’m using VS 2015, plus DevExpress WPF (although my ignorance is re generic C# rather than anything to do with DevExpress). My project uses a couple of C# .cs files for some common routines (no problem). In my Delphi days, I typically used the MyForm.pas files to contain the visual object stuff plus methods to call other routines - these being in separate .pas files (e.g. rtnMyForm1.pas - the prefix rtn meaning they were just “routines” related to that form). The aim was to separate the Form logic from the background algorithms.
Assuming that some of the form logic can be delegated to the XAML, my desired structure would be (ignoring the XAML):

Window1.xaml.pas - just for the window objects and calls for events
a new item created rtnWindow1,pas file created as a Class File for all the other stuff re Window1
Window2.xaml.pas - just for the window objects and calls for events
a new item created rtnWindow2.pas file created as a Class File for all the other stuff re Window2

Then what is the correct way of calling the methods in rtnWindows1 or 2 from other files (e.g. rtnSomecommonRoutines.pas)

On exploring this I’m getting errors re static methods vs dynamic. I understand some of this but clearly not enough!! Whatever Delphi’s faults (and there were many!!!) it hid you from all this.

If anyone has a really minimalistic project, structured like this, I’d be grateful for an example.

So all comments welcome (from derision to sympathy) :smile:

Bob Russell


(marc hoffman) #2

Not a big WPF user myself here, so I’m not in the loop much WRT what is “official set practices” and such. What I have in Water (largely driven by how things work in Cocoa/Fire, so I can share structure, but it works well), is that I have a Controller and a Window (or a View, as it may be in Water). The Window/View is the .xaml file and it’s associated .xaml, The control gets instantiated by whomever needs to gets things rolling, and it creates the View/Window, passing itself as “controller” to the constructor. The Window/View class sets it’s DataContext property to the controller, in the .ctor, and it usually also exposes a property read it back, such as

property Controller: MyWhateverControiller read DataContext as MyWhateverControiller;

so I can access the controller more strongly typed when needed. Because the DataContext is the controller,r I can also se it directly in Data Bindings inside the Xaml (<CheckBox IsChecked="{Binding SomeOption}">Some Option</CheckBox>), and from button event handlers and such, I can just call Controller.DoWhatever.

(in my case, Controller.DoWhatever would be declared with a signature compatible that I can also hook it up directly to Cocoa UI (which doesn’t use code in the View/Window), so that the Controller class can be large shared between Fire and Water.


(marc hoffman) #3

I’m thinking I should extract one of Water’s views into a sample project that shows this (including the WPF/Cocoa code sharing. Maybe I’ll find time for that on the weekend…


(Patrick Lanz) #4

Hello Bob,
One thing that may help you is the notion of Partial types

When a class has the partial modifier, it can be separated in many source files. So you can implement the logic related to part of the window work in one file and other logic (for another work) in another file.

But the best way in WPF is, as Marc says, is to work with a views. You define a view for all that the window needs and, using change notifications, changing the data in the view changes the window content. Also, when the user changes something in the window, the data is changed automatically.


(Bob Russell) #5

Thanks to all for these thoughts. Marc, an example like you suggest would be great. I think I’m going to go back to first principles, and construct a framework bit by bit, just to re-check my understanding.

So thanks again. I’ll return if/when I make progress or get stuck!

Bob Russell


(mtiede) #6

Bob,

I put my 2 cents in for MVVM. I really like that pattern. You should be able to find lots of examples on the web. I started using it with Silverlight, but use it for WPF as well. I create folders for Views and Viewmodels. Then in the xaml PAGE/Window, I just add the namespace of the views and the viewmodels. And then instantiate a view and a viewmodel right in xaml. Then the Views and Viewmodels know absolutely nothing about each other (except for the view knowing the properties that it should find in its datacontext). Only the Page/Window knows about each. And generally, I don’t have any code behind in the Page or View unless it is something that is JUST UI and has nothing to do with state of the viewmodel. Hope that is a help.


(Bob Russell) #7

Many thanks for this. I’ve read a bit about MVVM but not really explored. It gives me the impression that there’s a kind of “rigidity” (for all the right reasons) that comes from separating the UI interaction from the code. Probably coming from my Delphi experience where there was always a LOT of coding (often based on specific login preferences) to control exactly how the UI should react - all logic determined at run time for the specific logged in user, and not able to be pre-specified in XAML at design time.

I’m sure all this is doable using MVVM, but as yet I have not been able to find a “real world” example. Lots of mini examples of specific techniques, but not as “complex” as needed to provide the insight I’m looking for.

Probably I should keep looking. At present I’m still trying to get over the most simple hurdles using simple WPF with DevExpress (e.g. why on my simple project with just 2 windows which compiled OK, did it suddenly stop compiling because it said Unknown Identifier on the InitializeComponent; line in the Window constructor - cue lots of web searches but no clear solution!)

Anyway the journey continues!

Thanks again


(marc hoffman) #8

Attached is a very rough first draft. it doesn’t;t really have much logic/data in the Window yet, but shows the basics of a shared WindowController+Window definition and how to launch it.

ToDos:

  • Code in AppDelegate/App.xaml could be shared, too
  • Add actual UI/data and shared + per-platform logic into the controller
  • Abstract some stuff into common base classes, as one would on a ore complex multi-window app

Right now the sample is C#, because (a) I lifted some base code from Fire and (b) it’s easiest to translate to the other languages form that, once finished.

SharedUI.zip (742.7 KB)


(mtiede) #9

Bob,

Some of the best tutorials I enjoyed were by Mike Taulty. He is a British fellow and goes quite quickly through his examples, but I like that. He gets right to the point and usually with pretty good examples. Unfortunately, I’m not able to find some of those first videos he posted. Probably because he has moved on from Silverlight which is where I think MVVM was first presented. Examples will be in C#, but you should be able to follow along.

I’m putting together a little simple framework example that you could look at. Maybe it is too simple for you, but it shows the sort of pattern that I typically use.

ExampleWPF-MVVM.zip (203.7 KB)

I’ve made the application start on a Page although I haven’t done anything in there yet to do page navigation, but typically, I do have Page navigation in Silverlight. Silverlight is where I’ve done much of my Oxygene coding. I loved Silverlight. So I’m not even quite sure how navigation is done in WPF, but it is probably similar to Silverlight. The few WPF apps I’ve done didn’t require it, but I thought you might so I started it with a Page.

Also, I typically don’t even put the Viewmodels in the same project with the main project. That way, when I compile, I KNOW I don’t have ANY reference to the View mixed up in there. And similarly, one could put the Views in a separate assembly and one could be sure that there was no reference to the Viewmodels in the Views. Having the Viewmodels specifically in a separate assembly would also allow potential reusability of the Viewmodels in some other project.

But my example shows my use of MVVM and the separation of concerns there and the pattern I typically use in my apps.

Note how simple the Page xaml code is. I use the Page to basically “marry” the View and the Viewmodel.

Also note the declarative programming that creates the instances of the View and the Viewmodel. That is something that you really can’t do in Delphi and I like a lot. The more declarative stuff you do the less likely you are to screw up some coding. (You could create the View and Viewmodel in code )

Also note how easy it is to bind the command to the button without the page knowing what the button is going to do and only the command knows the instance of the Viewmodel that is working with.

I threw this together rather quickly and I haven’t really done much programming for a year since I was “retired” last year. I suppose 50+ years of coding is enough :slight_smile:

Oh, I almost forgot. I don’t really have the Model part in this simple example. Typically, I am getting the data for the Viewmodel from a WCF service running in IIS on a web server. Then I add a service reference to the project with the Viewmodel and automatically generate the proxy code to get the data.

I could elaborate my example and put some code in there that creates its own data, but I hope you can do that part on your own. (I might look into adding that later today, but it is a busy day today so…)

Good luck. If you have any questions on my example, or your own, I’d be more than happy to offer advice. I know .Net and MVVM were a big learning curve for me years ago, but it was really worth it. And I’ve really enjoyed the power of RemObject’s Oxygene when I was doing Silverlight applications. I think Pascal derivatives are just so darn clean to read and consequently easy to understand and maintain.

Oh, and another thing. There are various MVVM frameworks out there, but I never found the need for them.


(Bob Russell) #10

Many thanks to all. This should keep me out of mischief for a good while! Seriously, it does help enormously to look at / modify real examples. I’ll feedback in due course!

Bob


(mtiede) #11

Bob,

Yeah, one of the things I like about the .Net routines is that most of the documentation includes example code. A big help. Sometimes the code is in C# and/or VB so if I see something I like, I can just copy paste translate it into Oxygene code. The translation isn’t the greatest sometimes, but it is a good starting point. Search through msdn for those .Net objects/properties/methods that you are looking for. (I think they are still in MSDN, but google or bing should let you find them. I prefer Bing)


(mtiede) #12

Bob,

Here is a little more code that includes a “model” object class, etc. The Viewmodel now uses a Load method of the Model to get the data into a property of the Viewmodel for the View to display. One of the purposes of the Viewmodel is to take data from the Model and transform it in some way so that it will be easier for the View to display. I’m not really doing any transformation in there. Just loading the data and stuffing it in a property of the Viewmodel.

ExampleWPF-MVVM.zip (404.6 KB)


(marc hoffman) #13

Was the SharedUI sample of any help? Feedback appreciated before/for-when I finish it.


(Bob Russell) #14

Hi Marc, Apologies for the lack of response - I looked at the project, and got a bit stuck, then other stuff occurred which needed sorting.

Am I right in seeing the SharedUI project as a Mac OS Cocoa project? I’m doing Windows WPF stuff here. I looked at some of the files in VS, but couldn’t compile/run it, so I didn’t really get a good feel for what was in it. Am I missing something obvious?

Regards Bob


(marc hoffman) #15

Well, the whole point is that its Cocoa and WPF, with the bulk shared cross platforms :wink:


(Bob Russell) #16

Oh Dear, I’m obviously missing a trick here. I’ll have another look …


(Bob Russell) #17

Hi Marc. Realised that this is a multi-project solution :slight_smile: So new ground for me. Managed to compile and run the SharedUI.WPF. (Built just that then changed the startup project to that then Start - is that the correct thing to do?)
Saw a single Window - Title: Window1

One question, I cannot view MainWindow.xaml in VS - it says: the *Object Reference not set to an instance of an Object". Again, am I not doing this correctly?

Your help and patience is much appreciated

Bob


(marc hoffman) #18

Hmm, that sounds like a bug in VS then. I’ll have someone check.


(Bob Russell) #19

Many thanks. How do you keep sane with all these questions? :smile:


(marc hoffman) #20

Happy hour at the beach tonight to look forward to ;).