PDA

View Full Version : .NET WPF and MXS Example


cyberdogs7
11-22-2010, 06:00 PM
I created a Maxscript Example file of an quick and easy way to create full WPF .Net UI's and tie the event's back to Maxscript functions. Hope this helps anyone looking to get into it.


WPF Example (http://www.chadmauldin.com/blog/maxscript/wpf-and-maxscript-example/)

Kickflipkid687
11-23-2010, 02:14 AM
Dude! You The Man! :d

Edit:

Not sure if this is caused my minimizing/maximizing max, but when I try to create the Point marker via the Menu at the top, it only works sometimes.... :S

cyberdogs7
11-23-2010, 05:01 AM
Weird, I am not seeing that error. This is just to provide a starting point though, so I wouldn't expect it to be perfect. (the dotnet.SetLiftimeControl statement needs to be removed to work on max 9 or 2009)


Hope it helps you!

JHN
11-23-2010, 08:52 AM
It doesn't run here


-- Error occurred in anonymous codeblock; filename: D:\_script_Depot\ProductionPipeline\; position: 5146; line: 110
-- Runtime error: dotNet runtime exception: External component has thrown an exception.

Stepping through it only the .show (last line) throws an exception.
Max2010/WinXP 32b

-Johan

Gravey
11-23-2010, 01:41 PM
Johan - I think you need at least .NET 3.5 installed for it to work and if I remember rightly, 2010 only comes with .NET 3.0

Chad - nice example. I've been playing with WPF myself quite a bit recently.
One nice thing to add to your example script would be making the WPF window become a child window of max so that it plays nicely with other max windows, just like using MaxForm.ShowModeless().
To do this, you'll need to remove the TopMost="True" in the xaml string and then in the code just before the call to the_window.show() you should put these two lines: wih = dotnetobject "System.Windows.Interop.WindowInteropHelper" the_window
wih.owner = dotnetobject "System.IntPtr" ( windows.getMAXHWND() )

PEN
11-23-2010, 02:33 PM
Well I think that 32 bit just isn't working at all with WPF. This is going to cause me problems as I never know what my clients are going to be using. WPF is definitely the way to go and will makes lots of what I do easier.

LoneRobot
11-23-2010, 02:49 PM
sweet, all these snippets are greatly appreciated. I've been learning Blend recently so am looking forward to making some custom WPF user controls.

PEN
11-23-2010, 02:50 PM
"Blend" Pete?

JHN
11-23-2010, 03:08 PM
http://www.microsoft.com/expression/products/blend_overview.aspx

Have not gotten around to it myself.

-Johan

*Hey, didn't there use to be a free version?

LoneRobot
11-23-2010, 03:36 PM
r.e. Blend - Didn't think there was a free version, maybe a beta release perhaps?

I decided that WPF is worth investing in so I have purchased it. Am slowly working through the new WPF learning curve but am excited about the possibilities for some kick-ass user control interaction for max, all data bound to an XML-based character pipeline.

cyberdogs7
11-23-2010, 04:23 PM
Yeah the Window.Show() method is a know issue with 32 bit systems. Seems the work around is to recompile the Dotnet integration DLL in debug mode. That was beyond the scope of what I was trying to show here.

I am a big fan of the WPF windows, I feel it makes UI's that are much more consistent, easier to code, and they look better as well. I also have the benefit of knowing the exact platforms I am deploying to though so the 32 bit bug is not an issue for me.

PEN
11-23-2010, 05:33 PM
WPF is definitly worth it. I have been doing something similar my self where the UI is being created from an XML file but I'm also storing more then just the UI there. I want to change it all over to C# and WPF now so I'm going to have to rethink the whole thing.

LoneRobot
11-23-2010, 08:43 PM
You might not have to re-think it that much Paul, you have probably done most of the work already. I have managed thus far to get a WPF version of my RigStudio selector control, built from the original serialized XML. The big thing for me is how integrated Data binding is to WPF. It will really simplify dealing with all this data stuff we seem to have to manage and present as TDs. Early days on this for me, but I'm brimming with ideas on what I think I could do with it. I just don't know how yet, nark! :surprised

Kickflipkid687
11-24-2010, 01:15 AM
How do you guys go about getting the XAML data converted for MXS? Do you manually place in the \ characters after each = and before " or does a program do that for you? If that makes sense?


Edit: Yeah, that child snippet works great :D. But I think max is still doing a GC() and killing the button events in the form :(

denisT
11-24-2010, 01:35 AM
I am a big fan of the WPF windows, I feel it makes UI's that are much more consistent, easier to code, and they look better as well.

you can call me old grumbler or retrograde freak but I'm positively against using WPF in custom UI development in MAX. Using of WPF controls makes the tool INCONSISTENT. And the sample is the Graphite Modeling Tools. The good idea, but the childish implementation.

denisT
11-24-2010, 01:40 AM
you can call me old grumbler or retrograde freak but I'm positively against using WPF in custom UI development in MAX. Using of WPF controls makes the tool INCONSISTENT. And the sample is the Graphite Modeling Tools. The good idea, but the childish implementation.

PS. I'm using the WPF a lot for stand-alone applications and really happy to have it my development.

Gravey
11-24-2010, 04:06 AM
you can call me old grumbler or retrograde freak but I'm positively against using WPF in custom UI development in MAX. Using of WPF controls makes the tool INCONSISTENT. And the sample is the Graphite Modeling Tools. The good idea, but the childish implementation.I think this can easily be overcome by creating a set of styles to 'maxify' the controls, especially the button control. The styles would then be reusable as well.

My biggest concern with wpf is that the image class it uses: "BitmapImage" cannot be explicitly disposed. I created an image control recently that works like windows explorer where image thumbnail place holders are added to the control and the thumbs are generated in the background so it doesn't lock up the UI. It works great but it seems to take a fair bit of RAM, especially compared to something like HitchHiker, and when I'm done with the control the RAM is not freed. Calling System.CG.Collect() when I'm done with the control doesn't help either.

LoneRobot
11-24-2010, 07:34 AM
you can call me old grumbler or retrograde freak but I'm positively against using WPF in custom UI development in MAX. Using of WPF controls makes the tool INCONSISTENT. And the sample is the Graphite Modeling Tools. The good idea, but the childish implementation.

I completely agree with this, Denis! Graphite UI drives me mad. :banghead: And I also like the idea of being an old grumbler - I think the graphite UI is just a spectacular example of how not to bed a new UI into an old one. Lets face it, Autodesk don't seem to notice if it looks like they've added a new feature with a crowbar and a piece of blu-tack. Remember the original fur interface? Remember the intitial CAT interface with softimage logos?

So the key to this is integration, you have to make the UI sit pretty yet not stand out too much. However, with the types of controls I use for character systems, it's been obviousl for a few years that the slider and angle rollout controls just don't cut it.

I'm for the new integration, but not with 'animating' controls flying around like the flash interfaces of the web heyday. It seems you can do both in WPF, it just depends on how you implement it. Separating the design part and the code part is integral to this as you can get someone designing the control who understands visuals, and leave the code behind to the bodkins. That's the theory, in reality I and most other people will be doing both!

LoneRobot
11-24-2010, 07:47 AM
I think this can easily be overcome by creating a set of styles to 'maxify' the controls, especially the button control. The styles would then be reusable as well.

Hi Joel. I will certainly be making a darkUI and lightUI style for WPF controls.

My biggest concern with wpf is that the image class it uses: "BitmapImage" cannot be explicitly disposed. I created an image control recently that works like windows explorer where image thumbnail place holders are added to the control and the thumbs are generated in the background so it doesn't lock up the UI. It works great but it seems to take a fair bit of RAM, especially compared to something like HitchHiker, and when I'm done with the control the RAM is not freed. Calling System.CG.Collect() when I'm done with the control doesn't help either.

That's interesting. I will look into that as it's just the sort of thing i'm going to end up doing too, especially if I port hitchhiker to WPF at some point in the future! Are you using the image control to host the thumbnail or making an image resource brush and painting the thumb onto a rectangle? I wonder if there is a trick to making WPF dispose of the resources explicitly, i mean if you can host video in controls it must have an adequate disposal method for redundant data. shouldn't it?

Gravey
11-24-2010, 10:16 AM
That's interesting. I will look into that as it's just the sort of thing i'm going to end up doing too, especially if I port hitchhiker to WPF at some point in the future! Are you using the image control to host the thumbnail or making an image resource brush and painting the thumb onto a rectangle? I wonder if there is a trick to making WPF dispose of the resources explicitly, i mean if you can host video in controls it must have an adequate disposal method for redundant data. shouldn't it?I called my control 'DelayedImageView'. It uses a ListView with a WrapPanel as the ItemsPanel and the ItemsSource is bound to an ObservableCollection of my custom "DelayedImage" class. For the items I'm using a DataTemplate to display the DelayedImage as an Image control and a TextBlock which are data bound to the class. I never thought of using an image brush and I'm not really sure what implications that will have but it might be worth a try.

I've done quite a bit of google and forum searching regarding the GC and disposal of BitmapImage and the standard answer seems to be that "the GC will only run when it feels it needs the memory, even if you explicitly call GC.Collect()" in fact it is recommended that you don't ever call GC.Collect() because it is supposedly smart enough to know the most efficient time to do it. I know I'd rather be able to have it work when I tell it to though...

If you're interested I'll see if I'm allowed to share the DelayedImageView. If I can't, I can provide more detail as necessary.

LoneRobot
11-24-2010, 10:56 AM
Hi Joel

You're right, in GDI city they like you to dispose of your painting resources in the correct bins. Im not sure what WPF is doing - i suspect it's not performing sneaky fly-tipping under the cover of darkness but it is always better to know you can clear up after yourself. I developed hichhiker with the performance monitor running side-by-side so I could make sure everything was being cleaned up efficiently.

I'm sure i'll have lots more questions to ask you as they crop up! My current contract is finishing in a couple of weeks so I will have a bit more time to dedicate to looking into this stuff. How have you found going from winforms to WPF? It is different, but not significantly IMHO.

Gravey
11-24-2010, 11:45 AM
sneaky fly-tippingyou mean cow tipping? or is that some funky local expression?How have you found going from winforms to WPF? It is different, but not significantly IMHO.I actually think it IS significantly different in that you can do quite a lot with very little effort. Xaml and data binding are brilliant. Its really just the image disposal issue that I mentioned which annoys me. Hopefully someone out there has found a more efficient way to handle large amounts of images.

LoneRobot
11-24-2010, 11:53 AM
I'd not heard of cow tipping. ;) Fly tipping could be the same, although it would be hard to turn over a sleeping fly.

When you compare what a pain it was to do certain things in winforms, it is a breath of fresh air on how easy it is to restyle controls and connect them to the data.

Cheers joel, - Not sure if I should be talking to anyone in Australia this close to the ashes though.:beer:

Gravey
11-24-2010, 12:46 PM
I'd not heard of cow tipping. ;) Fly tipping could be the same, although it would be hard to turn over a sleeping fly.could be fun trying though ;)Cheers joel, - Not sure if I should be talking to anyone in Australia this close to the ashes though.:beer:same to you buddy:beer:

LoneRobot
11-24-2010, 12:53 PM
could be fun trying though ;)

That would be tough, You'd have to be like Mr Miyagi!

denisT
11-24-2010, 03:48 PM
I think this can easily be overcome by creating a set of styles to 'maxify' the controls, especially the button control. The styles would then be reusable as well.


I'm absolutely sure that you can make your nice and elegant "maxy" stylish set of WPF controls. And Pete can, and Chad, and me... And we will bring our stuff in MAX. And it will make MAX speckled as Gypsy shawl. When I have opened Graphite Tools, Scene Explorer, and Slate Material Editor at same time, it makes me sick.

PEN
11-24-2010, 06:32 PM
I'm absolutely sure that you can make your nice and elegant "maxy" stylish set of WPF controls. And Pete can, and Chad, and me... And we will bring our stuff in MAX. And it will make MAX speckled as Gypsy shawl. When I have opened Graphite Tools, Scene Explorer, and Slate Material Editor at same time, it makes me sick.

Didn't you get the memo, they are unifying the UI, hence the addition of the Caddies, they look just like all the other UIs...don't they? I'm guessing it has been easier to unify it to all be different then unifying to make it all the same.

Track
11-25-2010, 09:09 AM
My biggest concern with wpf is that the image class it uses: "BitmapImage" cannot be explicitly disposed. I created an image control recently that works like windows explorer where image thumbnail place holders are added to the control and the thumbs are generated in the background so it doesn't lock up the UI. It works great but it seems to take a fair bit of RAM, especially compared to something like HitchHiker, and when I'm done with the control the RAM is not freed. Calling System.CG.Collect() when I'm done with the control doesn't help either.

Try so
(dotnetclass "System.gc").collect ()
(dotnetclass "System.gc").WaitForPendingFinalizers()
(dotnetclass "System.gc").collect ()

Interesting topic.


... as Gypsy shawl. When I have opened Graphite Tools, Scene Explorer, and Slate Material Editor at same time, it makes me sick.
P.S. 3ds max2009 - the last live version )).

Gravey
11-25-2010, 11:01 AM
Try so
(dotnetclass "System.gc").collect ()
(dotnetclass "System.gc").WaitForPendingFinalizers()
(dotnetclass "System.gc").collect ()I have tried this actually but it still doesn't work consistently. I read somewhere that an object can't be collected until all strong references to it go out of scope or something like that, which seems fair enough but as far as I know those conditions are satisfied when I try to collect and yet the problem remains...

CGTalk Moderation
11-25-2010, 11:01 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.