>WPF and shortcuts

November 1st, 2008

>

Forcing the user to sprout a third arm to use a mouse is considered bad programming.

All menus should have shortcuts.  To be frank almost all controls should have shortcuts.  To use a few seconds to add shortcuts to the controls as they are made is considered good.

Shortcuts in WPF is done by prefixing with underscore, like E_xit and _Open. (WinForm is done by prefixing with ampersand, like E&xit.  Web applications should have this too and there it is called Accesskey.

Then to add the nice “Ctrl-O” text beside Open and “Ctrl-S” beside Save is trickier in WPF.  By no special order these are the pages I had to read to understand CommandBinding and RoutedUICommand:
http://anuraj.wordpress.com/2008/06/23/shortcuts-keys-in-wpf-menu/
http://en.csharp-online.net/WPF_Concepts—Built-In_Commands
http://colbycavin.spaces.live.com/blog/cns!5FFDF795EBC7BEDF!129.entry

Pros and cons with HTC Touch Pro

October 14th, 2008

I have jotted down the pros and cons with a HTC Touch Pro mobile phone here. Typically personal experiences and not the stuff you can read about in reviews and ads.

– Slow. It is possible speed it up a little downloading an app and following the instructions. The app I used is called Advanced Config and can be found at xda-developers.com. But the unit is till Slow.

– Bad battery time. Especially when you use ActiveSync to talk bluetooth or anything else but the phone functionality. One can argue that too much communication (Bluetooth, WLAN, 3G…) is to blame the the fact remains: I bought the phone to use this stuff and when I do I have to charge it before the day is over.

+ The TouchFlo3D user interface is nicer than what Microsoft presents. When the TouchFlo3D doesn’t work any more the GUI falls back to Microsoft’s implementation. A graceful degradation sort of. Or like using a terminal window when KDE doesn’t make it.

– The TouchFlo3D still behaves like version 1 and sometimes mistakes a slide for a click or refuses to recognize my gestures at all.

– Crashes. All my WindowsCE machines since 1999 have crashed unexpectedly. Sometimes due to no reason at all. If not being freshly booted and put in the charger counts as a valid reason to crash (it was also connected to my WLAN at the time).

+ Easy to develop for. As long as you use dotnet and have the right development environment. Unlike developing for iPod or Xbox it is free to develop (these to others are free to develop for as long as you pay the respective companies a fee for deploying)

– WindowsMobile6.1 and Dotnet CompactFramework 3.5 does still not support WPF.

– The API for TouchFlo is not made public.

– It is Slow. Did I mention that?

– As a phone for making phone calls it is not very good. There are cheaper and better alternatives. I use my mobile phone for much more than calling so to me everything is a compromise; but if the phoning capabilities are very important – look for another solution. I can defend it being slow due to it being bogged down by applications and bad architecture, but I cannot defend it’s bad sound.

– ActiveSync. It uses ActiveSync for synchronization which is not very good on the phone and possibly the worst software written ever on the client.

+ GPS and bundled with Google maps. It should run Microsoft’s competitor too but I havn’t tried. The GPS feels slow.

+ Radio. But it requires the headset as aerial.

+ Charged through a USB port.

– Bad battery time.

– It is not a standard USB port. Normal USB works so it is not much of a problem.

– Uses the proprietary USB variant for headset. There is no 2,5mm plug for listening.

+ Supports 3G.

– Only comes in the installed language. Microsoft’s Hej Knekt!-licenses forbids HTC to change language. This means that on a swedish phone you might get the totally unusable swedish error messages. They are better translated today but are still totally ungoogleable.

+ Has a gravity sensor.  I have still to find a use for it but I think it is cool.

+ The camera seems quite good but is slow.

– The phone and the camera are slow.

+ Hardware accelerated 3D graphics.

– So slow that the caller often hangs up before I manage to answer.

+ The case looks good.

– The usability of the case is not thought through.  I requires two hands for pushing the phone out of the sleeve and it is way too easy to happen to press the on/off button while doing this.  The phone also manages to change it’s volume even though it is in it’s protective case and the phone is locked.

– The home page looks cool but one has to choose between either a good time indicator and bad calendar or a bad time indicator and a less bad calendar.  The home/front page calendar doesn’t always manage to show all events for the day.

+ Easy to read the time on the home page.

+ The keyboard is quite good.

– The swedish onscreen keyboard lacks functionality.  So did the Qtek9100.  The 9100 was updated after a while but after way too long.  The thinking by HTC seemed to be like “we cannot support functionality X with åäö so the swedish users shouldn’t be supported without them either”

– It uses ActiveSync.  Probably the worst software written ever.

+ Has no key for taking voice notes.

– Shifts volume even though locked and in its cover.

+ Has dual touch sensitivity below the screen.

+ A screen cover comes with the phone.

– Not reliable.  Can crash unexpectadly in the middle of the night and leave you without wake up chime in the morning.+ A better way of killing running applications than Windows Mobile 5.  What were Microsoft thinking when they wrote in the guidelines that it should _not_ be possible to stop applications? At the same time they removed the cancel button – very wise on a gadget like a PDA or phone.  Not!

+ When putting it in its case it can mimic the sounds of a sword being put in its scabbard from a Holly Wood movie.

– Slow.  In case I forgot to mention.

+ Shows the last you called and it is easy to choose one and change to another number of the same contact.  Like: call to a friend’s home, isn’t there, call mobile instead.

+ The web browser Opera that is bundled is nice.  Unfortunately it is crippled.

+ The cross/back button works quite good.

+ After one gets a hang of how to change application through TouchFlo and have moved the right applications to the Program choose; it is quite easy to open apps of your own choice.

+ If you have Visual Studio it is easy to develop for.

+ Finally there is a built-in method for closing all applications quickly.

– The case doesn’t stand the wear and tear of jeans and suitcases.

– It sometimes makes prank calls and answers calls from my pocket.

+ It does less prank calls and answers phone calls from my pocket than my earlier EricssonP910i and QTek9100.

– Almost impossible to use as a phone with headset while in your pocket.  Even inside its case in a loose jacket pocket it tends to turn the microphone off.

– For locking the phone it is easiest to hold the hang-up button.  This also works when using the phone, just hold the button down and the phone locks.  Well… every other time.  The other times it hangs up.

– The head set that is bundled is ok.  But it still gets a minus because the headset for the 9100 was superb.  Lock behind the neck made it balanced so you could have it hanging without getting slowly drawn off.  Fabric around the wire made it very tangle resistant.  The good designs with the old head set where thrown away and back to square -1 for this.

– Slow.  In case I forgot to write.

+ USB charger, I use the same cable for charging, communicating and other gadgets; less to carry.

– Spontanous crashes during night.  I wrote this before but this month it crashed several nights leaving me without alarm clock in the morning.

– The HTC GUI sometimes fails.  But it doesn’t fail to let the Microsoft GUI through, only to show a big black screen with words like tap if you wan to restart the htc gui”.  Tapping makes the HTC GUI start and crash and show a big black screen with words like tap if you want to restart the htc gui”.  Repeat until you get tired and reboot.

+ Multi touch under the screen.  A semi secret.

– Up and down on the main button are ok but left and right are so so.

+ Direction sensitive so it knows if you hold it vertically or horizontally.

+ A new UI for messages that bundles SMSes.

– A new UI for messages that is in other ways harder to use.

– It doesn’t make it as a phone.  You can get both much cheaper and at the same time much better phones.

+ Has a lot of horse power (that it unfortunately abuses)

– Slow.

– The button on the headset, is it really a button?  It is possible to doubleclick it to recall.  But it is not possible to hang up.  It may be possbible to answer calls but I havn’t tried since if I have the plugs in my ears I go deaf when they ring.

Operation cannot be performed on a shared row

October 6th, 2008

On http://msdn.microsoft.com/en-us/library/ha5xt0d9.aspx one finds some good advises on how to use Dotnet’s DataGridView with large data.  Amongst others one is told to care about Shared Row for data reuse.

A solution of mine was to populate the grid with objects of my own creation and then call SetValues; but when I refactored my solution and put the calls in the “right place” I got an InvalidOperationException exception with the message “Operation cannot be performed on a shared row.”

The SetValues call was made from a class that inherited DataGridViewRow.  The solution was to move the call out of the class (to my class that inherited the UserControl).

This article might hopefully help someone in the future with the same problem.

Update:

6.5 years later and no comment shows that I probably was alone with this problem. Or that my site doesn’t rate high enough.

Select Distinct is considered bad

September 15th, 2008

Correction; Considered a warning.

Here is a good rule-of-thumb: If you have to write an SQL with Select Distinct, do adjust your chair, get a cup of coffee, walk around the office but above all talk to someone else because Select Distinct is a symptom of something being wrong, either in the database or in your solution.

/* Select Distinct is normally not needed when your database is lagom normalized. But if you do need a Select Distinct then this is a very good example of a situation that needs to be documented.*/

>Retrieve the plain text from the RTF control in WPF

July 18th, 2008

>The rich text control in WPF is way more versatile than the Win32 one.
Versatility often means more complex and more complex means that the simpler things are sometimes lost. Like for instance retrieving the plain text from a RTF control.

It is not hard to do but I didn’t find any good example through google so here is an example of how to retrieve the plain text from a WPF rich text control:
    TextRange textrange = new TextRange(
        rtfControl.Document.ContentStart, rtfControl.Document.ContentEnd);
    string plainText = textrange.Text;

HTH

>Writing code or conducting it

July 7th, 2008

>

A friend of mine said something wise. A programmer’s job could be to conduct the code instead of writing it. Think of it like components that all handle their part very well and plays well together. The conductor is there to facilitate and point in the right direction. I believe he is on to something.

Defensive programming and Fail at once

July 3rd, 2008

There is something called defensive programming http://en.wikipedia.org/wiki/Defensive_programming that is supposedly something good. I believe so too but it might have a way of hiding bugs.

In defensive programming you recieve data and inspect it for flaws. When it is possible you manipulate the data so it is correct and usable again. This is good so as much your code works.

But when you are in a project where your code is just a cog in a bigger machinery this approach is not necessarily the best; by recieving and hiding flawed data a bug somewhere else is hidden.

In the example in Wikipedia a string limited to 1000 characters is manipulated. The suggested solution is to truncate the string and keep rowing as if there wasn’t a leak in the first place. Depending on the circumstances the bug might be at the caller and by removing the very bug instead of the symptoms the very problem disappears.

According to Fail at once an error should surface as soon and close to the source as possible. The chances for data resulting of the bug to propagate, is then smaller and the bug tracking is probably faster.

In the example it would have been better to throw an exception than to just keep on with data, now faulty in another way than to start with.

Or like this: if a user writes an essay of 2000 characters he probably wants to know that it cannot be saved the very moment ctrl-S is pressed instead of 2 days later when proof reading, when the last 1000 characters are gone both from mind and binary space. Or an operator of a tube bending machine prefers to know if his machine is faulty when he is working at it instead of two weeks later when the tubes are buried inside a wall somewhere.

About 4 years after I wrote the above I found that at least one more has the same opinion (pdf); someone way more known than I.

Fail at once – an explanation

June 29th, 2008

I have written 2 articles tagged as Fail at once without explaining what the filosophy behind the name is. Shame on me.

It is an old truth that the earlier a bug is found the cheaper it is to fix.
Automated tests tests things that can go wrong; but what if those things couldn’t even go wrong in the first place?


Code that won’t compile won’t make it into production. Ever.

It is cheapest to not write any errors at all.

Today Fail at once does two things: It stops compiling when it notices something is wrong and at all other times it tries to help the programmer do the right thing.
Typical example of the first is to always use type safe variables and the latter to name things in such a way that there is one very natural way to write the code. By using this explicitly and intelligently you get a leverage for writing better code faster.

Make sure your objects are fully populated – Fail At Once

June 18th, 2008

The default constructor
public Customer()
{
}

is seldom needed while working with business objects. Honestly – how do you need an object that is not fully populated? Do you have a Customer or do you not? A few situations comes to mind where an almost-Customer is needed but they all smell of refactoring, i.e. base class, sub class and two constructors.

To make sure I don’t have an object that is not fully populated I make sure the default constructor is not reachable. Either through creating other constructors or by making it private the times it is needed internally. Instead I create a constructor that takes all necessary parameters to fully populate itself. If there are variants I create more constructors. I am not afraid of writing code but I strongly dislike putting bugs into production. Hence Fail At Once.

Sometimes it is handy to have a “Set” method taking all parameters and calling it from the constructor but this is just a variant of the pattern above that objects that are not correctly populated are very seldom useful.

If you don’t like writing “normal” constructors them make them static and call them Create or something obvious.

Another advantage with this routine is when adding (or removing)  mandatory fields. Then there is one and only one place to update to make the compiler show you all places to update.

I have noticed that it is hard to make lists in the GUI without having a default constructor but this, I presume, is just the exception that confirms the rule.

Bugs that can’t compile will not go into production.

Do not type cast – Fail At Once

June 16th, 2008

Avoid casting types.

Why do I write about this? What has it do do with quality and projects and architecture? Well… each thing that cannot break doesn’t have to be tested and… cannot break. Less testing, less coding, less bugs.

When working with class libraries that are dependant on the generic type one cannot avoid type casting fully. The solution then is to encapsulate and wrap the cast through inheritance or composition.

If you wrap your type cast you have 1 test case instead of a test case per call.

What about datagrids and combo boxes that have an internal Rows or Items collection or Tag attribute? How can they become type safe without having to rewrite the whole control? Unfortunately I don’t have a perfect solution but as I have seen the evil in type casts I avoid them and instead of writing test cases and tests I spend some time looking for a type safe alternative. These are typically called row.OrderTag or combobox.CustomerItems. Overriding the method or attribute is not possible since one cannot change type; but one can override and set the [Obsolete] attribute to at least get a warning. Pepper this with a Debug.Fail( ”Please use the OrderTag property instead.” ) and things will stop in any test case that runs it. Many times one can even set the compiler to fail with [Obsolete(true)] to be totally sure the call is never made.

Another problem then is when two different types really are returned. Well… write two methods then. Even overload them; as long as the compiler understands your goal.

Final thought: How should one get this type of thinking into the spine of a project? It is not something that can be ordered but has to be understood and taken to heart by the involved. If someone has an idea please drop me a line; but until then being a good example is a good beginning.