I have written a few projects in WPF now. What I don't understand is, why is the designer so fragile ? It seems as soon as I create any sort of reusable control, and use it on a form, even though the control exists in the same code base as the form, the form will no longer be able to render properly, it will report errors, which are invariably 'can't create an instance of MyCoolControl'. Of course, at run time it works fine, and the code for the control is right there, so I don't really understand what the issue is. I have talked to other people who have THEIR controls inside seperate dlls, which is apparently the recommended way to resolve this 'issue'. They still have the same error, and the way they have solved it, is by putting those dlls in the GAC.
Wait a minute. If I want to create a control inside my WPF app ( which is surely the OO way to do things, create it once and reuse it ), then I should create it in a seperate dll, and THEN put that dll in the GAC, so that the designer will work properly ? Am I the only person who thinks that is insane ?
Of course, I've not seen VS 2010, there is some possibility that this has been fixed. But, for now, it's a constant annoyance.
Thursday, July 30, 2009
Tuesday, July 28, 2009
Pop unders/child windows
I am updating our website. So, in VS I open each image in my website, then I copy it to do a new screenshot in our updated UI. Then I save it from photoshop. Here's where the problem starts. VS opens a window telling me the image has been updated. I need to close this before VS becomes responsive again. Only, it's not a child window of the IDE, so I have to ALT-TAB looking for it every time, so I can close it. I know I've had other issues with popunder windows like this making other MS programs seem to freeze up. Is it that hard to set the owner of a window before you show it ? I don't know. I know it's frustrating to have to do over and over, because some basic UI rules were ignored.
Wednesday, July 22, 2009
Object Orientation in .NET ( has anyone at Microsoft heard of it ? )
It's not uncommon to be working with code and want to call an event explicitly. In this case, classes derived from the EventArgs class, have an Empty property, which returns an empty instance, useful for doing exactly that, without having to construct an object we will not use. However, while it's possible to use the 'new' keyword to override a property, doing MyMethod(this, RoutedEventArgs.Empty); returns a compiler error, as the Empty propertly returns EventArgs, not RoutedEventArgs. In other words, while RoutedEventArgs in particular represents a class where you are very likely to not examine the event arguments, you still cannot use the property, it is worthless.
This is true of ALL derived classes of EventArgs, although I can see how, for example, a mouse related event args can be assumed to contain data you need ( although this is often not true, if I handle the mouse left button click event, I don't often care about anything passed in ) The only place I can think of where this is almost sure to not be the case, is keyboard events, where usually I want to know what key was pressed. It is for this reason that I've never tried to use KeyEventArgs.Empty, that is, assuming I were to forget that the construct as a whole is useless.
In the same way when I use Bitmap.FromFile in C# in general, I need to cast the Image that is returned, to a Bitmap. This is because it's calling a base method, I guess. That makes sense, but then why not make the base method return a Bitmap, given that you can't alter a method by return type, however, if I called Image.FromFile and got back a Bitmap, I could quite happily assign the value to an Image, and it would downcast. In fact, all things being equal, it's possible that the class always returns a Bitmap, but always specifies an Image as the return type.
Yes, I am right. The Image.FromFile ultimately calls this:
As an aside, surely this code would be prettier if the exception came from a default case, instead of just sitting underneath like that. Do they have coding standards in Redmond ? In fairness, if my suggestion would compile at all, I am pretty sure that it didn't work in early versions at least, b/c the compiler could not work out that every case had a return value. So, perhaps this code has just not been looked at in a long time.
The return type here is an Image. Bitmap.FromGDIplus looks like this:
So, in a nutshell, even if I am using an Image, I get sent a Bitmap, but if I am using a Bitmap, or an Image, either way, the object is downcast to an Image for no good reason that I can see, before I get it back. No memory is saved, all that happens, is another reason for a meaningless cast.
Bitmap bm = (Bitmap) Bitmap.FromFile(@"c:\Image.jpg");
Is that really the best we can do ?
This is true of ALL derived classes of EventArgs, although I can see how, for example, a mouse related event args can be assumed to contain data you need ( although this is often not true, if I handle the mouse left button click event, I don't often care about anything passed in ) The only place I can think of where this is almost sure to not be the case, is keyboard events, where usually I want to know what key was pressed. It is for this reason that I've never tried to use KeyEventArgs.Empty, that is, assuming I were to forget that the construct as a whole is useless.
In the same way when I use Bitmap.FromFile in C# in general, I need to cast the Image that is returned, to a Bitmap. This is because it's calling a base method, I guess. That makes sense, but then why not make the base method return a Bitmap, given that you can't alter a method by return type, however, if I called Image.FromFile and got back a Bitmap, I could quite happily assign the value to an Image, and it would downcast. In fact, all things being equal, it's possible that the class always returns a Bitmap, but always specifies an Image as the return type.
Yes, I am right. The Image.FromFile ultimately calls this:
internal static Image CreateImageObject(IntPtr nativeImage) |
The return type here is an Image. Bitmap.FromGDIplus looks like this:
internal static Bitmap FromGDIplus(IntPtr handle) |
Bitmap bm = (Bitmap) Bitmap.FromFile(@"c:\Image.jpg");
Is that really the best we can do ?
Tuesday, July 7, 2009
Working with images in WPF is not straightforward
It's taken me a while to get my head wrapped around exactly what is going on here, but there's some serious issues with image controls in WPF. My first manifestation of all this was that I'd load a BitmapSource into an Image, and it would not be visible, the control would continue to have a width and height of 0. If I wrote code to try to manually set sizes ( even though I shouldn't have to ), the size of my image would come back as 0.
What happens is, images are loaded on another thread. So, when my code asks for the image size, it's 0. Of course, this means if I am debugging, then I introduce a delay, so the thread can run, and the size is there. So, if you want to do anything when an image is loaded, your best bet, is to use the size changed event on the Image control. I've found that I need to put the images inside a StackPanel, if I put them in a Grid, they are just never visible, if I use the * notation, which I always try to do, to create forms that can be resized smoothly.
What the framework desperately needs, is an ImageLoaded event, so you can write code to run when the image loads, THEN tell it to start loading. I don't understand how this was missed, I'd have thought that being able to load an image, then do something based on the size of the image, would be pretty common in a framework whose main claim to fame is a freeform user interface.
Thursday, July 2, 2009
Update : hotfix for bugs in XAML designer in VS 2008
With thanks to Mark for the link, http://code.msdn.microsoft.com/KB963035 is the hotfix for the issue I reported previously, where the VS2008 designer will freeze if you edit XAML. I remain confused how such a bug escaped testing, but at least there's a fix. I don't have it installed yet, but others tell me it's helped them.
Wednesday, July 1, 2009
Breaking Visual Studio is too easy
My first real WPF app started out fine, but over time, I found that I could build it perhaps once, then I'd get an out of memory exception and have to restart the IDE, or sometimes even reboot. You can imagine what a pain this was. I did some research and found that this is quite a common issue for a lot of people. There are other issues, for example, someone I know tells me that for him the linker crashes with an internal error inside the "IncrBuildImage" function, every second build. He's building native code. I don't know the answer to his issue, but I know how I solved mine.
The issue is that the compiler often can't deal with a WPF app that has a lot of resources in it ( my exe was 32 MB which included a lot of UI elements as PNGs ). There's two solutions here:
1 - make your UI elements XAML. This just makes sense, they take up less space, and scale to any size. Expression Design is actually awesome at taking Adobe Illustrator and other formats and turning them in to XAML. This is the approach I am taking going forward
2 - put all your resources in a dll. If you're showing big images, as I invariably am given the apps I write, then you may not want or be able to convert them to XAML. So, put them in a dll, which you never change, and therefore do not have to build more than once.
I would prefer not to have my images in a resource dll, but it's made me a lot more productive. If they fix this bug in VS2010, I may go back to how it was, but certainly this works, and it is an effective workaround for yet another Visual Studio bug.
I am actually travelling to the US for a couple of weeks starting tomorrow, so my post frequency may slow down, although I do have at least 10 other .NET issues bookmarked to write about, so with some luck I may manage to keep up my current post frequency of a couple every now and then. Doesn't sound too challenging, but if this post is two weeks old and it's on top, that's my excuse, and I'll be posting again for sure when I get back.
The issue is that the compiler often can't deal with a WPF app that has a lot of resources in it ( my exe was 32 MB which included a lot of UI elements as PNGs ). There's two solutions here:
1 - make your UI elements XAML. This just makes sense, they take up less space, and scale to any size. Expression Design is actually awesome at taking Adobe Illustrator and other formats and turning them in to XAML. This is the approach I am taking going forward
2 - put all your resources in a dll. If you're showing big images, as I invariably am given the apps I write, then you may not want or be able to convert them to XAML. So, put them in a dll, which you never change, and therefore do not have to build more than once.
I would prefer not to have my images in a resource dll, but it's made me a lot more productive. If they fix this bug in VS2010, I may go back to how it was, but certainly this works, and it is an effective workaround for yet another Visual Studio bug.
I am actually travelling to the US for a couple of weeks starting tomorrow, so my post frequency may slow down, although I do have at least 10 other .NET issues bookmarked to write about, so with some luck I may manage to keep up my current post frequency of a couple every now and then. Doesn't sound too challenging, but if this post is two weeks old and it's on top, that's my excuse, and I'll be posting again for sure when I get back.
Sunday, June 28, 2009
Things I hate about my Mac
It's not quite a year since I moved to Mac. My reasoning was simple. A Mac IS a PC, so I'm not choosing either/or, I am saying, I will buy a PC, will I also choose to have a Mac at the same time ? My Mac has 20 gig of RAM and 8 cores. It's a pretty sweet box. I generally love using the Mac, too, there just seems to be little things where the OS seems to work with you, instead of against you.
The whole point of my blog is to point out things that I've found to not work as I'd expect, in all aspects of my computing life, especially where I know the solution, and hopefully I can feature in the search results of people trying to solve the same problems I have solved. What I'm basically writing about today, is VMWare Fusion and Boot Camp. VMWare Fusion is a piece of software that lets me install virtual machines on my Mac, and to basically run OSX and have windows running in a window. This is how I've used my Mac for most of it's life, which means I can use Safari, Pages, XCode, etc. as needed, but still go over to Windows when I need to write some Windows code, open a newer format Office file, etc. This has not been without issue, VMWare loses it's internet connection frequently, and while I've been given step by step instructions for what to type into the console to reset it, I am new enough to Mac that I am still working my way up to power userhood, I don't fully follow what it is that I'm doing, so I needed to keep looking it up. The support also takes the form of a public forum and it took me a while to work out that the people who were incredibly rude to me ( I assume for being a Windows user ), were actually not employees of VMWare. This made me feel better, because I know some people who work at VMWare, and I've found them to be really great folks, in real life. I must say, the guy who told me how to get around the internet dropout issue, also did not work for VMWare.
The main reason I use VMWare and not Parallels, is that the question I asked when buying was "who has the best 3D support ?". As my apps are all WPF, I need good DirectX support. VMWare also works with Boot Camp drives, so I had tried to set up a boot camp partition in the past, but had failed in my efforts to do so, so I had kept using an old PC for final testing, 3D was definitely sluggish under VMWare.
As I was going to the US in May, I took my Mac in to the Mac store, and told them I'd buy a hard drive from them, if they set up Boot Camp for me with Windows XP. I made clear that I am well capable of doing such things, given the time to work it out, but my one attempt at Boot Camp had not worked out, and I plain do not have the time to dedicate a day to making this thing work. While I was away, I emailed to check progress, they told me the XP CD I had given them was broken. I assured them this was not the case, and gave them some suggestions ( they claimed the CD was not booting ).
I got back, and picked up my Mac. When I tried to start it, it would tell me that there was no bootable media. As you can imagine, this upset me. Now, all my source code is backed up off site, but it's invariably the case, even with a Time Machine, that some data is lost when a HDD dies. To cut a long story short, my Mac was returned to me in a state where it kept trying to boot from my Windows CD, and would not boot from anything else. Once I worked this out, I found that the machine would indeed claim that my boot CD was corrupt.
I managed to convince the Mac to boot back to OSX ( I confess I don't recall how, this took place over 2 days and was a whole lot of stress ). So, I reformatted my new hard drive, and tried to install again. Same error. I verified the CD again. Fast forward a few hours of me doing this, and variations on the theme, and we get to my first point. I had asked the Mac store to create three partitions, I hoped to create a multi boot hard drive that booted XP ( for my day to day life ), Vista ( for testing only ) and Windows 7. It turns out that you can only install an OS for Boot Camp, on a drive that has only one partition. Once I formatted with one partition, the whole process worked effortlessly, with the CD I had given the Mac store. I called them and explained all this, for the benefit of the next person to walk through their doors and ask for some help.
So, I next tried to repartition my drive after windows was installed. This utterly broke my machine again, and I had to reinstall Windows again. For a time, my Windows would boot, but I could not recover the space I had moved to other partitions. At the same time, Acronis True Image could no longer back up my drives, as it could not recognise them. I wrote to their tech support, and they responded to say 'We understand you cannot back up from your drives. If this is true, let us know and we will mark this issue as closed'. I sent an angry reply, and by the time they followed up two weeks later, I had moved to Ghost, which is a great piece of software, and which worked when True Image would not. So, my second point is, buy Ghost, not True Image.
Apparently, the Boot Camp instructions tell you to never use repartitioning software, this was the point at which I realised that what I asked the Apple people to do for me, and they agreed, was in fact utterly impossible. Of course, I've heard these people tell prospective clients that Macs never have viruses, so I should have known better than to think they were experts.
I tend to update my Mac once every few months, I don't really keep track of when things come out, I just update as I think of it. So, I recently ran the update, and got told that there was an OSX update. I installed this, and then found that VMWare no longer worked, I would start a WPF app and immediately be told that the 3D was broken. It turns out that ATI video cards combined with the new OSX update, doesn't work with VMWAre. VMWare say that they knew this was the case in advance ( but chose not to email their clients to tell us ), and that they blame ATI and Apple ( despite Parallels apparently working fine with this update ). I've followed up on this on the VMWare forums, as far as I can tell, no VMWare employee has responded to me, but some guy who likes to insult me has basically blamed ATI and said that I should never install any update without doing a full system backup first. This is probably good advice. I just didn't see it coming that VMWare was so fragile, or that they wouldn't bother to tell their clients that their system is about to break.
So, my days of running Windows and Mac at once are over for now. I also found that running a Boot Camp partition in VMWare is not wise, it seemed to mess it up a bit, in fact, at one stage, my XP was so confused, that it would just reboot over and over, it took three hours of going between safe mode and normal to get my PC back. I would love to set up a shared drive to put data on, that is visible to boot camp and VMWare, once this ATI issue is resolved. I am assuming when it is fixed, they won't bother to email their clients to tell them. I suspect that the end result will be that I'll fall out of love with VMWare, get used to using boot camp, and just not use VMWare again. Which is a shame, it was very cool when it worked.
The whole point of my blog is to point out things that I've found to not work as I'd expect, in all aspects of my computing life, especially where I know the solution, and hopefully I can feature in the search results of people trying to solve the same problems I have solved. What I'm basically writing about today, is VMWare Fusion and Boot Camp. VMWare Fusion is a piece of software that lets me install virtual machines on my Mac, and to basically run OSX and have windows running in a window. This is how I've used my Mac for most of it's life, which means I can use Safari, Pages, XCode, etc. as needed, but still go over to Windows when I need to write some Windows code, open a newer format Office file, etc. This has not been without issue, VMWare loses it's internet connection frequently, and while I've been given step by step instructions for what to type into the console to reset it, I am new enough to Mac that I am still working my way up to power userhood, I don't fully follow what it is that I'm doing, so I needed to keep looking it up. The support also takes the form of a public forum and it took me a while to work out that the people who were incredibly rude to me ( I assume for being a Windows user ), were actually not employees of VMWare. This made me feel better, because I know some people who work at VMWare, and I've found them to be really great folks, in real life. I must say, the guy who told me how to get around the internet dropout issue, also did not work for VMWare.
The main reason I use VMWare and not Parallels, is that the question I asked when buying was "who has the best 3D support ?". As my apps are all WPF, I need good DirectX support. VMWare also works with Boot Camp drives, so I had tried to set up a boot camp partition in the past, but had failed in my efforts to do so, so I had kept using an old PC for final testing, 3D was definitely sluggish under VMWare.
As I was going to the US in May, I took my Mac in to the Mac store, and told them I'd buy a hard drive from them, if they set up Boot Camp for me with Windows XP. I made clear that I am well capable of doing such things, given the time to work it out, but my one attempt at Boot Camp had not worked out, and I plain do not have the time to dedicate a day to making this thing work. While I was away, I emailed to check progress, they told me the XP CD I had given them was broken. I assured them this was not the case, and gave them some suggestions ( they claimed the CD was not booting ).
I got back, and picked up my Mac. When I tried to start it, it would tell me that there was no bootable media. As you can imagine, this upset me. Now, all my source code is backed up off site, but it's invariably the case, even with a Time Machine, that some data is lost when a HDD dies. To cut a long story short, my Mac was returned to me in a state where it kept trying to boot from my Windows CD, and would not boot from anything else. Once I worked this out, I found that the machine would indeed claim that my boot CD was corrupt.
I managed to convince the Mac to boot back to OSX ( I confess I don't recall how, this took place over 2 days and was a whole lot of stress ). So, I reformatted my new hard drive, and tried to install again. Same error. I verified the CD again. Fast forward a few hours of me doing this, and variations on the theme, and we get to my first point. I had asked the Mac store to create three partitions, I hoped to create a multi boot hard drive that booted XP ( for my day to day life ), Vista ( for testing only ) and Windows 7. It turns out that you can only install an OS for Boot Camp, on a drive that has only one partition. Once I formatted with one partition, the whole process worked effortlessly, with the CD I had given the Mac store. I called them and explained all this, for the benefit of the next person to walk through their doors and ask for some help.
So, I next tried to repartition my drive after windows was installed. This utterly broke my machine again, and I had to reinstall Windows again. For a time, my Windows would boot, but I could not recover the space I had moved to other partitions. At the same time, Acronis True Image could no longer back up my drives, as it could not recognise them. I wrote to their tech support, and they responded to say 'We understand you cannot back up from your drives. If this is true, let us know and we will mark this issue as closed'. I sent an angry reply, and by the time they followed up two weeks later, I had moved to Ghost, which is a great piece of software, and which worked when True Image would not. So, my second point is, buy Ghost, not True Image.
Apparently, the Boot Camp instructions tell you to never use repartitioning software, this was the point at which I realised that what I asked the Apple people to do for me, and they agreed, was in fact utterly impossible. Of course, I've heard these people tell prospective clients that Macs never have viruses, so I should have known better than to think they were experts.
I tend to update my Mac once every few months, I don't really keep track of when things come out, I just update as I think of it. So, I recently ran the update, and got told that there was an OSX update. I installed this, and then found that VMWare no longer worked, I would start a WPF app and immediately be told that the 3D was broken. It turns out that ATI video cards combined with the new OSX update, doesn't work with VMWAre. VMWare say that they knew this was the case in advance ( but chose not to email their clients to tell us ), and that they blame ATI and Apple ( despite Parallels apparently working fine with this update ). I've followed up on this on the VMWare forums, as far as I can tell, no VMWare employee has responded to me, but some guy who likes to insult me has basically blamed ATI and said that I should never install any update without doing a full system backup first. This is probably good advice. I just didn't see it coming that VMWare was so fragile, or that they wouldn't bother to tell their clients that their system is about to break.
So, my days of running Windows and Mac at once are over for now. I also found that running a Boot Camp partition in VMWare is not wise, it seemed to mess it up a bit, in fact, at one stage, my XP was so confused, that it would just reboot over and over, it took three hours of going between safe mode and normal to get my PC back. I would love to set up a shared drive to put data on, that is visible to boot camp and VMWare, once this ATI issue is resolved. I am assuming when it is fixed, they won't bother to email their clients to tell them. I suspect that the end result will be that I'll fall out of love with VMWare, get used to using boot camp, and just not use VMWare again. Which is a shame, it was very cool when it worked.
Subscribe to:
Posts (Atom)