I think a minimum and maximum block height are worthwhile additions for a transaction record.
The suggested maximum block - "Absolutely do not include this transaction in a block later than N" - is an excellent way to set up a transaction so that you know when it has, definitely, FAILED to be included in the block chain and you can do other stuff with the inputs.
Gmaxwell already pointed out why this is a bad idea.
Say you have a transaction which can only be included between before block 300,000 and it manages to get included in block 299,999.
By the time the chain hits 300,006, it will be considered a confirmed transactions. Other transactions can spend its outputs and also the outputs from those transactions can be spent. This means that lots of transactions can end up depending on that one transaction.
If there is a re-org that replaces block 299,999 with another block that doesn't include the transaction, then the transaction cannot be included in 300,000, so it must be discarded. This cancels all transactions that depend on that transaction and also all transactions that depend on those and so on.
Normally, if a re-org changes a block, you can normally just include the transaction in the next block.
Double spends are different. The point is that even with completely honest users, a maximum block height rule means that transaction (and all decedent transactions) can end up being invalidated.
But I'm not going to spearhead any attempt to hard fork in order to get these things added.
It wouldn't necessarily be a hard-fork, depending on how it is implemented. You are converting transactions which are "spend anytime" to "spend before height h". Forks which make the rules more strict are soft-forks.