Looking through the keyhole

A Minimal-Model Hypothesis of Consciousness

The process of creating a ‘model’ of the mind, encompassing it’s myriad facets of perception, consciousness, emotion, and intelligence (all very ill-defined terms in this context) has awakened me to some rather fascinating revelations concerning ourselves. It matters not whether the subject is human consciousness, or that some other animal species – the mechanisms are, in all relevant aspects, the same.

This is the story of the beginning of a very strange tale..  a vision not so much of ‘how things are’ (meaning the reality of the Universe that is ‘out there’), as it is of how little we can see of it. It follows that coming to a realization of how removed and incomplete our mental understanding is – is quite important for the advances that I want to make.

A photo of the Orion Nebula

An alternative way of looking at consciousness is evolving within my mind. The most remarkable aspect of it? How it impacts how one might regarding the physical world. Re-reading over how I have explained it, I’m struck by how little there is within this that is actually new. There is, at this point, not much that you can pick up off the table and hold forth as groundbreaking or visionary. But as it has brewed in my mind these past few months (ever since Burning Man 2013) – it’s importance has grown.

In the beginning…

(yeah, it has to start like that. Sorry.)

from out of the primordial soup of fertile molecules that gave rise to animate life, that mysterious designer called Evolution (let’s abbreviate that to Ev) needed to create a functional brain. No so much ‘intelligent’, but really just functional. In fact – the term “intelligent” can be misleading. It assumes facts not in evidence. “Functional” is the operative word — in that it functions just enough to accomplish it’s purpose. Functional enough to enable these evolving creatures to survive long enough to bear offspring, and perhaps to hang out a little longer to help nurture them, and that’s it.  Ev didn’t actually care whether the world-view of these evolving creatures had any accuracy. Ev simply needed functioning little brains, to power these creatures through a short life and get the job done. For these little brain-mechanisms to work, they needed a mental-model. That is, a model that described the world around them. Let’s use the term “mental-model”, because that closely describes what it actually is. It’s in the same sense that we use the term “model” in applied mathematics or engineering.

Since a brain is a relatively expensive piece of biological machinery (in terms of metabolic demands upon the rest of the body), Ev had to economize. Ev had to be creative and design a mental-model that is so simple, that this primitive brain could operate it. After all, out of the vast Universe — only the immediate environ need be represented within this model. And when we say “represented” here, it’s not a photographic-image of that environ. It is more accurately described as a simplistic set of rules, an abstract algebra that defines operations upon those sensory inputs that yields useful behavior. Imagine yourself as a primitive salamander-thingy being set loose upon the jungle. What is needed for your brain? What does it have to accomplish? Just to get food, mate or whatever other process serves your species for reproduction, and avoid bumping into trees and shit as you move about. Add a few other details such as avoid water (if you can’t swim) or to use it for escape from predators (if you can), seek shelter, and scratch your butt.

The important part of this story — is the realization of how limited the mental-model held by the brain is, relative to what would be needed to truly model the world around us. Do note that the term “truly” is truly lacking in definition. We are on a track for which words struggle to carry their normal weight.

Ev created our mental-model on a tight budget. She gave us functional parts, but not a real understanding. Everything we can conceive, is just a composition of primitive physical conceptualizations. Objects. Empty space between those objects. Ground. Water. Movement amongst those objects. Other critters. Relationships between critters only insofar as it behooves our family-life. And that’s .. it.  We can do some abstract stuff — and that’s what saves us in a certain way. When you imagine some modern-day thing that didn’t exist in the early eons of our evolution, note how your inner model of that thing, is really very very primitive — often with a thin veneer of abstract-logic overlaid on top of it. For example, note our mental image of the atom: a nucleus with electrons orbiting around it. That’s a simplistic picture that our mind feels comfy with. We graft some additional layers over top of this – orbits being limited to certain definite energy-levels, spin, color.. but if someone says atom what do you envision in your mind? How are these represented within highschool textbooks? We always return to that crude representation. One which, I believe, is absurdly off.

But the limitations go beyond that. Far beyond.

I am theorizing that our conception of the passage of time, of ‘things’ moving along a path, the substance of the space around us — and the distinction between matter and empty-space — all of these are fictions that enable our mental-model to be simpler. And more economical for the brain-mechanism to implement.

Note that I have used intentional language to describe Ev’s process of creating our minds. That’s intentional. It expresses the idea of purpose, in the way that we sometimes ascribe intention to the seemingly random processes of natural selection. But intention and purpose, are il-defined terms, and I use them here loosely. Please do not infer from it that I am naming Ev a god status, or visa versa.

Our conventional world-view of our sight, for example, is simply that of a eye, receiving the light of the outside world, and that light being converted into electrical impulses whereupon they travel down the nerve-bundles to our brain. We “see” the world around us (by this view). This is how that process is depicted within our textbooks.

I suggest a different world-view: that light — and all of the other inputs from our physical senses — from the outside world is filtered and interpreted and changed far, far more severely than we ever imagined. Picture a painting — rich in myriad colors and shapes and motions, far far richer and multi-dimensional than I can convey in words. Now picture within that painting, a tiny circle the size of a pinhead. That circle represents our own mental-model. It is gray, faint, fuzzy, totally distorted beyond all recognition. But it is the only mental-model we have. Inside of that circle, is all that we can conceive. Outside of that circle, is everything else — which does not fit within our mental-model and thus we are incapable of perceiving, or even of conceiving it.

That, is a very severe limitation. The boundary of that tiny little circle represents the boundary of our comprehension. The normal animal brain, bumps into that boundary and stops. That might be a fuzzy boundary, in that some minds venture beyond it just a bit more than the others.

This, then, is why the things that we learn, once we progress beyond the immediate physical world that we evolved within — can seem so absurd to us. The foremost examples that come to my mind include the phenomena associated with quantum physics. Relativity. Electromagnetic energy. The particle-wave duality. And dark matter – which is theorized to make up the majority of the matter of our Universe.

I think it is more likely that it is us that is absurd. Or  rather, our mental-model. All of those afore-mentioned epiphenomena are just the real world.

Here are some corollaries of this view:

Our brains are limited to the tiny-circle, when it is operating as it commonly does – in the normal, sane state. But when the mind is not normal, as for example when hallucinating or crazed in some way — we may perceive some pretty strange shit. The vast majority of the time — that is just junk observation. The drink, the drugs, the medical-condition that gave rise to your crazed state — these yield crap. The neural signals are scrambled and yield only nonsense.  But, in a vanishingly-small portion of those cases, what was perceived was real. Regardless of how crazy it was: if you saw little green dudes hanging upside-down from your ceiling, it is a (vanishingly-small, but non-zero) possibility that you were getting a glimpse of something beyond that tiny circle. What you saw, could have been real. But you sound crazy when you try to describe it to others.

BelugaWhaleAndHerNewborn

It is unfortunate that, in the vast majority of cases, people say nothing but stupid shit when coming back from such an experience. It is unfortunate because we could probably increase our understanding if we could only see what they saw. And if we had some means of discerning the nonsense from the narrow slivers of truth.

There is another, ‘area’, that is inevitably opened by these explorations, which we can usefully bifurcate into two topics:  magic, and religion.

While the explanations for how we came into being, and the origin of the Universe that are offered by the primary Abraham-based religious traditions are of course nonsensical, contemplating the implications of this theory of consciousness has lead me to wonder what else is radically different than what I had been assuming about the world. If all that we comprehend about the Universe is but a tiny dot on a page, then that begs the question: what else is out there? The question of whether there is a master creator, dissolves into smoke at this point for lack of any meaningful definition of intelligence, or intention. There is no way really to articulate what is the distinction between a universe that springs into existence as the result of a Big Bang, or is swept into being by a thought, or an intention, on the part some magical entity (both of which could be postulated to have occurred at the same time in the past, and to have left exactly the same evidence). But just because the fundamental underpinnings of one tradition of fairy-tales is proven false, does not mean that certain of the claims of those fairy-tales are not in fact ‘true’. You can rip apart an antique radio and prove that it contains only glass tubes and bits of metal and plastic; but someone else can then hook a source of voltage to it and show that beautiful music can come from it. Along this same line of thought: perhaps, just because we can demonstrate that all of the machinery of Life can be duplicated by assembling the right molecules into the right physical assemblage of human-being — does not disprove the possibility that there is ‘something’, that persists beyond the lifetime of that body.

I personally would group the reports of religious or spiritual experiences under the category of ‘paranormal’ phenomena. It is just a syntactical choice. If some ‘one’ has indeed floated over their own body during a medical emergency, or after a near-death experience (the salient point being that in this event they were revived such that they could give testimony concerning the event), then – if true – that would provide evidence that there is indeed something about a living thing that persists after death. Something non-material, in the sense of our present understanding of things material. What would you call that? Since I have never seen any definition of the term “soul” that has sufficient specificity to be of any use, that word is as good as any.  It should be borne in mind, however, that (I would suggest) humans have an unfortunate predilection for making things up. The vast majority of religious experiences, of paranormal phenomena, of miracles and other such – is fiction. Only a vanishingly-small proportion corresponds to an actual glimpse outside of the pinhole.

I think that Truth is more difficult to achieve, and more rare, than most of us had imagined.

Frog hidden amongst the algae

I’ll extend this exposition in the form of additional posts, before compiling into a cohesive paper. It would be good to get constructive feedback as this progresses.

Advertisements
Posted in Artificial-Intelligence, consciousness | Tagged , , , , , , | 1 Comment

Western Digital is readying it’s HGST 6-Terrabyte Helium-Filled drives to ship

Western Digital is ready to start shipping it’s latest disc-drives – the 6TB HGST HDDs. These are hermetically sealed with helium, which since it has one-seventh the density (mass per unit volume) of air, does not effect the rotating parts as much. These drives are a bump up for their line which previously maxxed-out at 4TB. These also consume 23-percent less power and run 4-5 degrees Centigrade cooler.

The shift to helium sounds like a sage move. Personally, I had to ponder a moment on that capacity-point. Six Terrabytes.

A little while back (in the eighties), I watched the design-engineers at the firm at which I was working, install a new disc drive into a computer we were going to use to control a bit of hardware. My own computer at this time had only floppy discs, with 360 Kilobytes per floppy. I was impressed by the speed and convenience their new disc drive gave them. No more loading floppies to access files. It seemed so fast – the light on the front would blink a few times and boom! the computer responded.

That was a 5MB disc drive.  Five Megabytes.  You might cogitate upon that for a moment: the new drive that Western Digital is now shipping is not a thousand times greater in capacity. Nope. That would be 5GB.  Let’s see..  these rascals are a million times greater!  Well, a bit more actually since we’re talking about 6TB and not 5TB.

So, let’s see. You could pile up one freakn million of those 5-1/4 inch Seagate disc drives. One million of them. To equal the capacity of this new drive — which by-the-way is substantially smaller and quieter.

Interesting.

Posted in Uncategorized | Leave a comment

Where are the good laptops?

It seems that it is getting hard to find a competent new laptop to purchase. My previous favorite, Lenovo, has eschewed their perfect keyboards and switched to a newer chicklet design. To make matters worse, they’ve abandoned the standard two-row-by-three-column layout of the editing keys (Home, Delete, End, Insert, Page-Up, Page-Down), and the cursor-movement keys are no longer set off in their separate, easily-typed format.

It was already bad enough that the previous 1920-by-1200 pixel resolution displays disappeared. My current laptop, a Thinkpad W500, had that resolution. It is starting to die intermittently, but I am loathe to give up that display for the loathsome 1920-by-1080 that all of the displays top out at now. Scanning the websites for the other laptop makers reveals that even with the few models sporting larger displays, there is nothing with a 1920-by-1200 pixel screen. Very annoying.

The saving grace is that newer, higher-resolution screens are starting to appear — Lenovo has announced their new W540 with a screen resolution of 2,880 by 1,620 pixels!. This would be awesome. But I am not seeing it in any one model that has all of the basic requirements just yet.

Here, then, is a list of what I would want to see in a new laptop:

1. Decent display resolution!!!  At an absolute minimum — 1920-by-1200. No, not all of us buy laptops to show HD moves, and we feel cheated by these 1920-by-1080 screens. We want that extra vertical band of pixels! Better: a 2650 x 1600 resolution display that is at a minimum 15.6 inches. Better yet would be to have a 17 or 18-inch option at this resolution. To be state-of-the-art (does anyone use that term anymore?) — the newest laptop displays such as Apple’s “Retina” display are the standard to beat. Why would a manufacturer expect users to shell out $2.2K+ for a new laptop, for anything less?

The proper layout of a keyboard

The proper layout of a keyboard

2. A keyboard whose design respects the ‘standard’ traditional Thinkpad layout and feel, meaning that the keys have a physical feel that makes it very easy to type, and a layout that matches the traditional PC desktop keyboard (cursor and editing keys are in the right places). This “standard” layout, is what my existing computers have. I have bought some excellent aftermarket keyboards with this exact layout.

The editing keys

Closeup of the page/editing keys

There is finely thought-out ergonomics at work here. Notice the bevelled edge of the keyboard well: when you slide your hand up there in a dark room or as your eyes are focused elsewhere — that edge serves to orient your hand. Your fingers instantly find their way to the Page-Up/Down keys. Through habit, then, your index finger always falls upon the Insert and Delete keys. You don’t have to re-focus your eyes to look at the keyboard to find those – it just happens subconsciously. And see that space between the column that contains the Insert & Delete keys, and the column to the left of them (the Pause and F12)? That little space your fingers will find by habit, to further home in upon their location. The excellent Lenovo Thinkpad W500, has this.  If a manufacturer foolishly messes with this, and changes the laptop’s keyboard — suddenly you’re stuck with having to replace everything and retrain yourself! The key-travel must be as on the W500 or W510, which is most definitely not a ‘chicklet’ keyboard. Professional users do type.Keyboard_W500_3w

3. Multi-touch display. Not essential all of the time — the mouse does fine. But when this laptop is sitting on the family table and you want to just touch it to have something happen – that’s nice to have. Very nice to have. If we’re going to pay North of $2K for a new cptr today, it seems dumb not to have the option of Touch. Think about this: your customer is contemplating pulling the trigger on a new laptop/workstation; he’s mulling it over for a day since it’s a chunk of change ($2500); he walks into a retail shop for pencils and strolls by the counter of laptops. One is showing Windows 8.1’s start screen. He reaches over and softly touches the Music tile, and it instantly leaps to attention, ready to sound out. Sweet. Do you think he’s not going to think about that, when he next goes to sit down and revisit your web-shop page to order?

4. Trackpoint. Okay – I realize most people aren’t used to these and prefer the touchpad. But I and a lot of other Thinkpad users like to have the Trackpoint nib, especially for those moments when the mouse is not at hand.

5. Battery life that exceeds 24 hours. Look, if an iPhone burning 64 bits and quad-cores can last a full workday, why would you expect a user of your W510 to feel happy about the lousy 2 hours it provides?! Do your engineering. Provide the option of a massive spare battery if you must, that connects to the underside. But give us life!

6. The fastest CPU and subsystems — to yield a system as fast and snappy as a desktop. For various reasons — today most laptops feel like you’re in a slow-motion movie even when simply doing the simplest of tasks. This should not be necessary. Be mindful that professional users couldn’t care less about games. So hyped-up graphics subsystems to drive those games aren’t what’s needed. What we want, is the thing to respond to us. Always. Instantly. No matter what.

That is not a long list. There is nothing revolutionary within it – these are the technologies that are available and have already been in production. And this doesn’t include all of the minor, common technologies that have already become common such as multiple USB 3.0 ports and a camera-memory-card reader.

jh

Posted in Personal Effectiveness, Uncategorized | 2 Comments

Mindth

Thought.

A project that has been a sort of a side-task for years, is starting to bear some fruit. Probably because this last month has been one of the rare instances when I had a little bit of time to actually focus on it.

For lack of a better term – I’m calling it Mindth for now.

Human-like thought had been a rather tough nut to crack. It was my feeling that most of the contemporary research directions were off-track, and I’ve been exploring into a different direction. There are myriad practical uses that are in need of something that brings to the table a more intelligent capability.

One area of practical use is that of machine configuration, such as for servers, workstations, and virtual machines (VMs).

The open-source project Muppet is a great example. It targets an area for which there is a great, immediate need — trying to simplify the process of setting up and configuring a server (or workstation, or VM — let’s use the term “box”). With Linux lamentably split into multiple diverging camps, and within each (for example, the Ubuntu family) relying upon multiple disparate ways of installing software, it becomes a bit of a nightmare to try to get things done. Add to this mix Windows, and then VMware or other virtualization environments, and you have a combinational-explosion of routes to explore to encompass all of the possible avenues and methods you need to know, to get even a fairly simple box set up to begin using it. But even Muppet does take a bit of researching to learn how to use it, and to set it up.

For small teams, or the lone worker — there just is not enough time to fiddle and tinker and google and nab books and ask colleagues for every little step of the way. Even for a substantial development or IT team, this complexity is a major obstacle. Certain tasks are easy — to you, or to someone who has spent many months working on this one area of expertise. But for those whose responsibilities span wide areas — taking the time to gain that expertise is just not feasible.

And it is quite unnecessary.

As one of the initial, practical applications of Mindth (outside of the proprietary applications which were done in the past) — I am creating a program with the ability to understand plain-English descriptions of what we want it to do. Specifically, to set up and configure a box, to install the requisite software applications, create VMs, optimize it and apply the known personalizations that the user likes — and to do some troubleshooting of problems. The knowledge upon which it draws, is expressed in plain simple English (I’m focusing on just English for the purposes of this discussion, but it is not limited to this one human language). For brevity I’ll use NL to refer to plain natural language (again, in this instance – that happens to be English).
To clarify: unlike most programming and script languages, with Mindth — the NL is unstructured other than the requirement of being understandable by a reasonably-knowledgeable human being. If a person can understand it, then Mindth should.

Mindth has a facility for comprehending your desires (ie, the goals), and can search what it knows, and what it can access and understand — to try to implement your desires.

KB-Net

One major facility is it’s crowdsourced-knowledge network. For example, within a given organization — you normally have knowledge that applies only to that organization, but which everyone needs to know. For example, the email addresses of various officers and IT specialists. The URLs of the team wiki. The servers that serve up web pages or run tests or hold the databases. Database passwords. Database schema. The location of the codebase. The components your code uses. How to access your version-control. Etc.  It can be a non-trivial amount of work to just get this information – to track down who knows what, and to keep up with changes. To address this need, the Mindth system includes a set of online services that are available only to this organization, that the instance of Mindth running on anyone’s desktop can access. When a server-address changes, that information is put into the Intranet Mindth knowledge-base (a fancy way of saying ‘you tell it to Mindth’) – and that information is transparently pushed down to every Mindth-instance that needs it.

Actually, this crowdsourced-knowledgebase (let’s call this KB-Net, for network-derived knowledge-base) exists at several levels, each of which has a definite scope. The lowest scope is at the level of the solitary developer himself. That information is private to him or her — it serves as a recorder for his notes (I’m going to adopt the convention of just using the masculine gender here, to refer to either gender: no discrimination is intended). The next higher scopes would apply to the organization, which may have multiple levels of scope (immediate team, department, company). And then the widest scope is Internet-connected and applies world-wide, as for example information that denotes how to install a given application.

Implementation

Currently, Mindth is being implemented on Ubuntu and Windows, using the programming-languages C#, F#, Python, and C++ where necessary. The main user-facing application is a desktop GUI that on Windows is composed using WPF. I am using Test-Driven-Development (TDD) for the lowest-level routines, where that makes sense. For exploring major ways of accomplishing things, I keep the TDD on hold, since following that to an excess would seriously slow down progress. Individual functions – those which are well-defined, must work without fail – I simply don’t have time to do extensive debugging with each change, and this is a system that must achieve consistent correctness, thus that is where TDD makes sense: a good balance of experimentation and disciplined process is essential. For the code that implements what we would call “thinking”, or feeling, or perceiving — I need the ability to tinker and experiment and to quickly evolve in new directions.
There are functions within Mindth that are taking a rather long time to run, despite my having re-implemented portions in C++ and exploiting every CPU-thread available. I’m exploring the possibility of taking advantage of the computing power of a high-end GPU card to make this faster.
With regard to programming languages, I personally am feeling a very good relationship with C# — it is turning out to be the best possible overall-systems programming language. F# presents an awesome opportunity to succinctly express some of the pattern-matching and logical-rule-resolution paradigms, and it mates very well with C#. C++ is the original, barebones pedal-to-the-metal (as in, very efficient) programming language; it falls a bit short when you need to express complex data-structures, but for speed and interfacing with electronics it is unsurpassed. Python.. what can you say about Python? At first it feels like a rather odd fellow, but it IS a great tool for tinkering interactively, for gluing things together, and for exploring some of the excellent open-source assets that are available. The toolbox needs all four.

The architecture itself, is a topic for later discussion.

We’ll see where this goes. I am having some fun.

Posted in Software Design | Tagged , | 3 Comments

Test-Driven Development (TDD): To free, or to constrain?

Praying Mantis, looking to put the bite onto your lovely butterfly

Praying Mantis, looking to put the bite onto your lovely butterfly

How many times have you reached for a nice shiny new tool and put it to good use, enjoyed its benefits .. and then after a spell realized that your shiny plaything has walked over to take its place along with all the other myriad factors that weigh you down with complexity and detail?

A: You factor out a bit of common functionality from your project code, and compose a cute little function that does just that. The API into your function is simple, your inputs are well-defined, and the output is deterministically decided by your inputs. You know exactly when it is correct; so you compose a suite of unit-tests to prove its’ correctness and add that to your continuous build/test process. Very nice. Have some coffee.

B: Your management has mandated that you shall be always as one with the Test-Driven-Development (TDD) buzzword. Everything you write, is unfinished until you also write the unit-tests, lots of them, and everything passes. No sweat – TDD has proven benefits, you say. Predictability. Reliance upon correct software. Every sprint (a term from the SCRUM process) has milestones, and tests to prove them. But those tests are no small amount of added work. And with each incremental bit of functionality, many existing tests now fail. So you have to go back and fix those. More late nights of coding. The frig empties of creamer. Oh, by the way — now some of your teammate’s code is failing. Oops. Well – they gotta get on board with the new functionality you just added – so they’re working late too. The show-and-tell is tomorrow. Maybe it will work – who knows? Everyone has been so buried in trying to meet the milestone, that no-one has had a spare moment to sit back and really see whether this project is going in a good direction.

What happened? How did you ever get from A to B? And is your job (and your company) still going to be around tomorrow — will you survive?

Let’s talk about this. and I’ll continue this story next week (check in Monday morning, 4/22).

Posted in Software Design, The Development Process | Tagged | 2 Comments

A Thought on the TDD strategy

Test-Driven-Development (TDD) has a good contribution to make to a project’s management strategy. It is a means by which one can know that a given kit of software (your end-product) does perform according to a specific specification (the suite of unit-tests), and can help to focus a developer’s mental energies toward meeting that specific goal. However, it can also bog your team down in detail if it is not used wisely.

TDD can feel wet and scratchy, but it can be nice if you treat it with understanding.

To illustrate this last point – a project I was on recently used TDD throughout, religiously. We had several disparate groups who met daily for our “scrum” update, and from these meetings it seemed that for any code-change, no matter how small – even just a minor change on one line, one could expect that many days would be needed to get all of the unit-tests to pass.

The problem was that we did not have a real direction to our TDD. Each was told to “write tests” for anything we added or changed. Thus, a developer would wind up looking at his code for any detail that could be “verified”: assert that this flag was true, that flag was false, how many results returned, what strings could be present, etc. Upon adding T-SQL code to add a database view, for example, unit-tests were added to verify the number of lines of T-SQL code, and that it contained such-and-such keyword, etc. Upon adding another bit of SQL, all of those previous unit-tests now fail: every detail has to be accounted for and updated.

A huge amount of time was being wasted. Still is.

It is vital to ask oneself: “What are these tests supposed to achieve?” Your work is to implement functionality within your end product. Do you really care about every detail of how that was done? Do you really need to test for every artifact of the implementation? What if the developer finds a superior way to implement, and achieves the same functionality? Do you really want him to have to re-write a huge battery of unit-tests?

And, if your developer is going through the tests, method-by-method, editing them to get them to pass, are they really serving their true purpose — which is to double-check that the functionality is actually working?

If the one over-riding goal of your software development work, is to produce a product that works (and I hope that it is) – then you really cannot afford to get bogged down by detail. You must move forward, solidly, or perish. No matter how large your team. Even IBM and Microsoft got ground down by excessive code and detail-work. Progress grinds to a standstill, and younger, more agile competitors come to eat your lunch. Software has to evolve, to improve, to become always more solid — and to do this you have to make real, steady forward progress. Not just write a zillion unit-tests for the sake of saying you “use TDD”.

Suggestion: Forge your goals related to TDD, and discuss this with your team leaders. Know how much time is being consumed by writing and running tests (which means – individually tracking this time). And talk about and understand (together) how best to use TDD to meet your goals. Use it where it makes sense, let it go where it does not!

The purpose of software, is to accomplish a specified functionality. Thus your tests should serve the purpose of verifying, to the maximum extent possible, that that functionality is indeed accomplished. But it should do this in the simplest and most concise way, and avoid duplication. Only test for the correct end-result, not the steps to get there. Factor out as much as possible of the infrastructure-code and share it amongst the team. If your API changes, then yes – you can expect a lot of rewriting of tests. But if it is a simple change of code to optimize the implementation, and it necessitates a massive number of test changes — this is a red-flag that you may be getting bogged down in test-itus!

On a different project that I considered to be pretty successful, we were writing low-level code that had to work on myriad platforms — versions of Windows or Unix, 32-versus-64 bit, environments with various components already installed (or not), etc. For this we used virtual machines (VMs) — VMWare in this case. One VM would represent a specific platform: one for Windows XP 32-bit, a bare install, another for Windows 8 beta 64-bit that already had .NET 4.5 installed, etc. One lovely thing about these VMs is that you can deploy them and do a lot of stuff using Windows Powershell, which in turn is easily callable from C# or a product like RobotMind. Products which in turn can be invoked via a right-click on a project within Visual Studio. Thus, instead of spending days setting up for, and running, and checking the results of each out of this plethora of tests, we could just define the whole set up front, right-click on our C# project when done coding, and select “Test this!” — and it would send the compiled code out to the proper test-VM (or set of VMs) on the dedicated test boxes, and deliver back the results (“Go”, or “No-go”). To keep things singing along, I dedicated a box just to running these VMs, one which had a PCIe SSD and oodles of RAM. I could open Remote Desktop on it (RDC) and see at a glance what was running, and what the results were. No manual file-copying, so setting configuration values.

Along with that, I strongly suggest that you look into continuous integration. And to integrate that into your build process, I suggest you carefully consider it in the context of your chosen version-control tool. I have found that you don’t necessarily want to just automatically build everything that gets checked in, when it is checked in. If you do, then everyone is afraid to tinker, or to check in partial results at the end of the day.

Instead, if your version-control tool gives you the ability to attach a “Label” or “Tag” to a given set of check-ins, then you can use that to signal to your continuous-build tool what to check out and build and run tests on. This way, you can merrily check in your work at the end of the day, even if it does not pass tests. If your workstation goes down overnight, or something else happens — your work is safely stored within the code repository. And it does not “break the build” because you did not label it as “Known Good” (or whatever nomenclature you decide to use). Your build server, when it runs nightly or continuously, can simply check out the current branch that is labelled “Known Good” and build it, and run the suite of tests. CruiseControl is probably the most well-known product in this space; I have used it in the past, and it worked well for us. FinalBuilder is another, very powerful product that merits a careful look. Most recently I have grabbed and deployed TeamCity (from JetBrains) and was absolutely delighted at how fast it is to fire up.

In summary, pay heed to your process. Watch out for that trap that ensnares many teams, of getting bogged down trying to meet the needs of the tools, of the processes (like TDD or bug-tracking), and of paperwork. When your developers start to sense that your process is weighing down their productivity (as measured by the actual, real-world functionality that is evolving – the kind that your customers will actually see) then it is time to seriously re-examine your whole process.

jh

Posted in Software Design, The Development Process | Tagged | 1 Comment

.NET Framework 4.5

Microsoft is continuing to improve and advance their .NET Framework. As of today (2012/2/4) the Microsoft .NET Framework version 4.5 is available as a “Developer Preview”. You can download it now, install it, and work with it – just be cognizant that this is not production-ready, at this time.

The most up-to-date information should be on msdn.

Downloading, Installing, and Getting Started

What’s New in version 4.5

Migration Guide


What’s New in 4.5 ?

The new features for the .NET Framework 4.5 relative to the earlier release (4.0) may be divided into these 7 categories. Click on the link in each to drill down to view more detailed information.

  1. .NET for Metro style applications

  2. Core Features and Improvements

  3. Web

  4. Networking

  5. Windows Presentation Foundation (WPF)

  6. Windows Communication Foundation (WCF)

  7. Windows Workflow Foundation (WF)


1. .NET for Metro style applications

Metro style apps are designed for specific form factors and leverage the power of the Windows operating system. A subset of the .NET Framework is available for building Metro style apps for Windows using C# or Visual Basic. This subset is called .NET APIs for Metro style apps. For more information about this subset, see .NET for Metro style apps.


2. Core Features and Improvements

  • Ability to limit how long the regular expression engine will attempt to resolve a regular expression before it times out.

  • Ability to define the culture for an application domain.

  • Console support for Unicode (UTF-16) encoding.

  • Support for versioning of cultural string ordering and comparison data.

  • Better performance when retrieving resources.

  • Zip compression improvements to reduce the size of a compressed file.

  • Ability to customize a reflection context to override default reflection behavior through the CustomReflectionContext class.

  • The Managed Extensibility Framework (MEF) gains support for generic types, a convention-based programming model, and multiple scopes.

  • Asynchronous File Operations that use the new task-based asynchronous features that were added to the C# and Visual Basic languages.


3. Web

The ASP.NET 4.5 Developer Preview includes these new features:

  • Support for new HTML5 form types, like email, tel, url, and search.

  • Support for model binders in Web Forms. These let you bind data controls directly to data-access methods, and automatically convert user input to and from .NET Framework data types.

  • Support for unobtrusive JavaScript in client-side validation scripts.

  • Improved handling of client script through bundling and minification for improved page performance.

  • Integrated encoding routines from the AntiXSS library (previously an external library) to protect from cross-site scripting attacks.

  • Support for WebSockets protocol.

  • Support for reading and writing HTTP requests and responses asynchronously.

  • Support for asynchronous modules and handlers.

  • Support for content distribution network (CDN) fallback in the ScriptManager control.

For more information about these features, see What’s New for ASP.NET 4.5 and Web Development in Visual Studio 11 Developer Preview.

Back to top


4. Networking

The .NET Framework 4.5 Developer Preview provides a new programming interface for HTTP applications. For more information, see the new System.Net.Http and System.Net.Http.Headers namespaces.

Also, the following networking improvements are included in the System.Net, System.Net.Mail, and related namespaces:

  • Improved internationalization and IPv6 support.

  • RFC-compliant URI support.

  • Support for Internationalized Domain Name (IDN) parsing.

  • Support for Email Address Internationalization (EAI).

Back to top


5. Windows Presentation Foundation (WPF)

In the .NET Framework 4.5 Developer Preview, Windows Presentation Foundation (WPF) contains changes and improvements in the following areas:

  • The new Ribbon control, which enables you to implement a ribbon user interface that hosts a Quick Access Toolbar, Application Menu, and tabs.

  • The new INotifyDataErrorInfo interface, which supports synchronous and asynchronous data validation.

  • New features for the VirtualizingPanel and Dispatcher classes.

  • Improved performance when displaying large sets of grouped data, and by accessing collections on non-UI threads.

  • Data binding to static properties, data binding to custom types that implement the ICustomTypeProvider interface, and retrieval of data binding information from a binding expression.

  • Repositioning of data as the values change (live shaping).

  • Better integration between WPF and Win32 user interface components.

  • Ability to check whether the data context for an item container is disconnected.

  • Ability to set the amount of time that should elapse between property changes and data source updates.

  • Improved support for implementing weak event patterns. Also, events can now accept markup extensions.

For more information, see What’s New in WPF Version 4.5 Developer Preview.

Back to top


6. Windows Communication Foundation (WCF)

In the .NET Framework 4.5 Developer Preview, the following features have been added to make it simpler to write and maintain Windows Communication Foundation (WCF) applications:

  • Websockets support to enable true bidirectional communication over ports 80 and 443 with performance characteristics similar to the TCP transport. Two new bindings have been added for this: NetHttpBinding and NetHttpsBinding

  • Simplification of generated configuration files.

  • Support for contract-first development. svcutl.exe3 has a /serviceContract switch allowing you to generate service and data contracts from a WSDL document.

  • Ability to configure ASP.NET compatibility mode more easily.

  • Changes in default transport property values to reduce the likelihood that you will have to set them.

  • Updates to the XmlDictionaryReaderQuotas class to reduce the likelihood that you will have to manually configure quotas for XML dictionary readers.

  • Validation of WCF configuration files by Visual Studio as part of the build process, so you can detect configuration errors before you run your application.

  • New asynchronous streaming support.

  • New HTTPS protocol mapping to make it easier to expose an endpoint over HTTPS with Internet Information Services (IIS).

  • Ability to generate metadata in a single WSDL document by appending ?singleWSDL to the service URL.

  • Support for configuring services in code.

  • Visual Studio XML Editor tooltips for every configuration element and its properties that is part of the service configuration file.

  • ChannelFactory caching support.

  • The WCF binary encoder adds support for compression.

  • UDP

    Support has been added for a UDP transport which allows developers to write services that use “fire and forget” messaging. A client sends a message to a service and expects no response from the service.

  • IDN Support

    Support has been added to allow for WCF services with Internationalized Domain Names. This type of messaging is useful when a WCF service sends a burst of simple messages to a large number of clients simultaneously, where the reliable delivery of each message is less important than sending the message to all clients at the same time.

For more information, see What’s New in Windows Communication Foundation on msdn.

Back to top


7. Windows Workflow Foundation (WF)

Several new features have been added to Windows Workflow Foundation (WF) in the .NET Framework 4.5 Developer Preview. These new features include:

  • Ability to create state machine workflows.

  • Enhanced Workflow Designer features such as the following:

    • Enhanced workflow search capabilities in Visual Studio, including Quick Find and Find in Files.

    • Ability to automatically create a Sequence activity when a second child activity is added to a container activity, and to include both activities in the Sequence activity.

    • Panning support, which enables the visible portion of a workflow to be changed without using the scroll bars.

    • A new Document Outline view that shows the components of a workflow in a tree-style outline view and lets you select a component in the Document Outline view.

    • Ability to add annotations to activities.

    • Ability to define and consume activity delegates by using the workflow designer.

    • Auto-connect and auto-insert for activities and transitions in state machine and flowchart workflows.

  • Storage of the view state information for a workflow in a single element in the XAML file, so you can easily locate and edit the view state information.

  • A NoPersistScope container activity to prevent child activities from persisting.

  • Support for C# expressions:

    • Workflow projects that use Visual Basic will use Visual Basic expressions, and C# workflow projects will use C# expressions.

    • C# workflow projects that were created in Visual Studio 2010 and that have Visual Basic expressions are compatible with C# workflow projects that use C# expressions.

  • Versioning enhancements:

    • The new WorkflowIdentity class, which provides a mapping between a persisted workflow instance and its workflow definition.

    • Side-by-side execution of multiple workflow versions in the same host, including WorkflowServiceHost.

    • In Dynamic Update, the ability to modify the definition of a persisted workflow instance.

  • Contract-first workflow service development, which provides support for automatically generating activities to match an existing service contract.

For more information, see What’s New in Windows Workflow Foundation.

James W. Hurst

Back to top

Posted in Uncategorized | Leave a comment

Silverlight 5 is available in beta now

The next version of Microsoft Silverlight will be version 5.  You can download a beta and related tools right now from here.  Microsoft has an announcement and description page here.

You’ll also want to download the Silverlight 5 Beta Tools for Visual Studio 2010 SP1.

Here’re some of the new goodies:

  • Extend features of the “Trusted Application” model to the browser. When enabled via a group policy registry key and application certificate, this means users won’t have to leave the browser to perform complex tasks.
    • Host HTML content within the Silverlight application
    • Read/write files to the user’s My Documents folder.
    • Launch other desktop programs.
    • Access devices and system capabilities by calling into application COM components.
    • Have full keyboard support in full screen.
    • Call existing unmanaged code directly from within Silverlight with PInvoke.
  • Text Improvements
    • Multicolumn text and linked text container allow text to flow around other elements.
    • Tracking/leading control
    • Pixel snapping improves text clarity
    • Text layout performance is better
    • OpenType support is improved
  • Databinding is enhanced!
    • You can now set breakpoints on a binding and step through binding failures!
    • Implicit DataTemplates
    • Binding in style setters
    • The DataContextChanged event is introduced.
  • Performance Improvements
    • Reduced network latency by using a background thread for networking
    • faster XAML parser
    • Support for 64-bit operating systems
    • graphics rendering improvements
    • Hardware decode and presentation of H.264
    • Improved power awareness
    • Remote-control support
Posted in Graphics, silverlight, Software Design | Tagged | Leave a comment

Evil Design

The Worst (and totally unnecessary) Flaw

What is the “feature”, or flaw, that you find most annoying about Windows 7?

For me, it’s when the dam thing simply crashes on you.

I sometimes use my laptop as a GPS system. Why? Because I like to have a nice big map, using up the entire 15.6 inch screen to show all the nearby roads and towns to help give me a sense of how to get there. I don’t like to use that synthesized voice that wants to tell me where to go. Sometimes it’s wrong. Sometimes I want to do a little more than just drive from A to B. I like to explore. To see what the region looks like, or at least what it’s maze of roads looks like. So I use Microsoft Streets and Trips, with a GPS sensor. I like maps.

So, here I am driving along, with my laptop on the seat next to me. And glancing over at it once in a while to see if I’m on track. Now, mind you — diverting your eyes away from the road is already dangerous enough. Ideally, the display should be right up there on the dashboard. But I digress.. Generally it works fine. A quick glance, and it helps me stay on track and not have to worry and fret about guessing which road I should be taking.

Then — suddenly this!

WTF?!!!

Now, mind you — if you’re sitting at your desk at home, quietly slurping a latte when this thing appears, no big deal. But while I’m driving? WTF!!!

BTW, there is no option to kill this. You can Postpone it, but not indefinitely. The biggest problem, is that my laptop is going to go offline for many minutes (I don’t have a SSD in this one yet) at what could be a dangerously crucial moment. This is dangerous! Microsoft does not know what we will be doing with your laptop at the moment it decides to do it’s update thingy. So this sort of thing is an absolute No-No!

And this should be a heads-up to any of you who design software, or systems, and provide it with any kind of message-box type of user interaction.

Rule Number 1: Do NOT jerk the system away from the user’s work to do your housekeeping, unless it is absolutely, definitely, essential. You do not want a user who is driving on a road at night, or flying a plane, or piloting a ship – to have to fiddle with the mouse-pad or pointer-nubby to click on the Postpone button. And then have to do it again in 10 minutes!

Microsoft Streets and Trips is Microsoft’s own product. Why can’t it detect that I have the software running. And my position is changing. Nothing should interrupt my usage of the product at this time. I am not even online: why do I give a shit about updating the software at this particular instant? I just want my tool to work for me, without distracting me from what I need to be doing.

What you (the designer of said software) should do, when you conclude it’s necessary to interrupt, is provide an opt-in message-box, that times out after so many seconds. And if it times out without the user doing anything, then it just lets the computer be, to keep doing it’s thing without interruption, until sometime later when the computer is idle and it is an appropriate time to prompt the user again.

That is a fundamental rule of design: Do not interrupt the user with your house-keeping.

Get Your Basic Operation Straight

It is my conviction, and this seems to be totally common-sense to me – that a software product should mature over time and with each succeeding version iteration. That is what I was told about, for example, IBM mainframe software: over time, it got increasingly solid. With each new version, more bugs were fixed, performance got better – enough that, if new functionality was introduced – it nonetheless was a more solid product that the version before. Shit worked.

So what is up with the Microsoft Windows design team?

We are now (as of 2012/2/4) on version 7. Windows has been out.. how long? .. since before the word “latte” was universally known here in the US. There are indeed some features that I like about it. But this thing has bugs in it’s basic operation for which there is no excuse!

For example, in Windows Explorer, nearly every time I select a folder, after a few seconds it seems to leap back to some other folder and select that. I often have to scroll down a second time and re-select the folder that I want to view, again. Why? This annoys the shit out of me.

It’s not only Microsoft, with their glaring flaws in otherwise good products like Windows, Word, Windows Media Player, and Windows Live Writer – Apple’s iTunes is so bad I still haven’t figured out how to do a totally basic operation like move an .mp3 audio file onto my iTouch so I can listen to educational audios while I’m driving. Nothing on it’s user-interface tells me clearly how to do it. Inexcusable! Especially after investing all that time to make a pretty UI. Give your product to an utter newbie (not a 13-year-old girl – they seem to already know everything!) and make careful note of what operations cause them to have to search for how to accomplish them. Then go back to the drawing-board and make those dead-simple obvious.

 

James W. Hurst

Posted in Software Design | Tagged | Leave a comment

A Virtual Keyboard for your WPF apps

Keywords: WPF, Silverlight, keyboard, Unicode, XAML

GermanLayout

Sometimes having a software-based ‘virtual keyboard’ for your desktop applications can be a help.  You can provide a way for your users to enter characters that they don’t have on their physical keyboard. You can also circumvent a stealthy keylogger by entering passwords this way. And for writing letters or posts to readers in other languages, it can be a huge timesaver.

Thus, the VirtualKeyboard project. You can get the complete Visual Studio solution from the CodePlex project here. I built it using Visual Studio 2013, however projects for earlier versions of Visual Studio (and targeting earlier versions of the .NET Framework) are included.

RussianLayout

This was a fun project done to do in Windows Presentation Foundation (WPF) – and I thought it’d provide a useful article to y’all because of the range of design techniques it uses. WPF yielded a few side-bennies like the fact that you can resize this Window and all the keys resize themselves appropriately. That was a freebee, by virtue of the Grid control.  Of course, I consider WPF to be a delight to design with; it’s the premier GUI-design platform out there and I have great respect for it’s creators. That said, this project does represent a significant amount of work. Let me rephrase that: a lot amount of work, to get it right. And then to boil it down to it’s essentials to the fairly compact application you see before you. I’m sharing this with you, to save you time on your projects and to illustrate techniques. Please give your feedback and contribute your own improvements so we can evolve this to make it even more useful. If you send me your suggestions, I’ll edit them into the code upon the next revision and cite you as the contributor. Multiple minds are always superior to just one.

We’ll walk through it’s design, have a little fun, and provide a link so you can download the entire demo application and source-code so you can put it to immediate use.

The VirtualKeyboard in operation:

It’s a non-modal dialog window, actually a WPF Window, which, if you integrate it into your application – allows you to provide a way for your user to invoke it and click on the key-buttons to insert characters into your application text fields.

DemoAppWithHands2

I’ve provided it with several language modes as a starter, and a brilliant gentleman named Iyengar Sesharaman did a beautiful job contributing two additional language sets – Sanskrit and Tamil – plus enhanced the code! My immediate need was for a memorization flash-card program to learn various language terms as in Arabic or Russian, so that’s what I created first. It also has French, German, and Spanish, which only actually add a few locale-specific characters. Perhaps you can tackle implementing a Mandarin keyboard and send to me to be included – I’d love to see!

You select the keyboard-layout via the ComboBox at the lower-right corner. Changing the language causes the keyboard to automatically update itself.

I found most of the keyboard-layout information on wikipedia and the like. I have to warn you though: that’s a good way to get utterly distracted and wind up delving into the historical underpinnings of ligatures and linguistics and whatever else catches your roving eye. But anyway – I strongly advocate for simplification via standardization. Hence, I try to select the one layout that is most appropriate as a standard for a given language/culture, but not go so far as to bastardize the standard US keyboard form itself. I can see that for some languages, that is not going to be an easy balance to choose. That arrangement should be chosen (by my reasoning) to most resemble what a native speaker would most likely be used to, within the confines of the standard keyboard layout. We are not selecting a Culture/Language for the GUI, after all. That’s a different topic altogether.

Anyway..

ColorfulFrog_wAs a further aid in typing, along the bottom edge, are thirteen extra typographic symbols you can type. I’ve needed these a lot.

In the demo-app pictured above you can see that there are two text fields. One is a TextBox, the other a RichTextBox. The virtual keyboard (VK) works the same with either one. Whichever text field has the current focus, that’s the one who receives whatever is typed into the VK.

The keyboard has provisions for saving it’s state, in that the next time you invoke it it’ll preset to the last language you used, and it’ll also remember whether you had it up whence you last exited your application, so it can auto-launch itself next time.

As a further convenience, just for kicks n giggles – when you move your application around on the screen, this keyboard Window can move in sync with it.

The key ToolTips are a convenience to the user, to help identify what the key is. I was tempted to insert the entire history of each glyph in there. However, this application/tool is for helping the person of the current Culture, type characters that happen to come from a foreign alphabet (relative to that user). Thus the ToolTips are in English (by default) to identify what those glyphs are. For this application, those ToolTips can be important.

When you click on the CAPS LOCK key, all the letters shift to uppercase. It stays in this state until you click CAPS LOCK again.

When you click on the SHIFT LOCK key, you have access to the shifted-state key symbols that you see on the keycaps, in addition to capital letters. This is the same as a physical keyboard does. In this case, after a ten-second timeout it drops back down to the unshifted state.

The Control and Alt keys do nothing. I just left them there so it looks more like a standard (US English) keyboard. But you can put those to use for something like the dead-letter keys that certain keyboards use languages. Or just remove them.

The Platform

This I originally created using Visual Studio 2010, on Windows 7 x64, and targeted the .NET Framework 4. Now I do my development using Visual Studio 2013 on Windows 8.1.  I did not test it on earlier versions.  I’m a believer in letting the vendors evolve our tools and taking advantage of the latest versions. If you’re one of those still stuck on version 1.0, because you’re so ultra-conservative – all I can say is: go away!  I have a separate library that this and all my other projects use, but I pared it down for this project download to just the bare minimum that it uses and included it with your source download. That ‘common’ base-level library is BaseLib, which I use for both desktop apps and web apps. Another library, BaseLibWpf, contains the WPF-specific common facilities; I separated that out because I didn’t want to be deploying desktop-specific assemblies with my online applications.

I set the configuration to target “Any CPU”. And that took a bit of tinkering. I’m unsure why. It kept flipping itself back to x64. When VS 2010 on Windows x64 suddenly seems to not be recognizing certain of your projects, check the build configuration. If one is x86 and the other x64, they will definitely cap your swagger! It can take several attempts before the setting sticks. (update: I haven’t seen that behavior as yet, with VS 2013).

I’m sure you want to know how to put it to use within your own program. Then we’ll chat about a few interesting aspects of it’s design, and then finally walk through the code itself.

Using it for your own application

The easiest way to tell how to use the VK in your own design, is to show you a simple demo-app that does just that. Let’s mosey through it in three steps.

Using it within your own Application is easy. The demo app that comes with your download is a pared-down WPF application that has a simple TextBox to receive the characters, and a Button for launching the virtual keyboard. And.. I added a 2nd text control, a RichTextBox, to illustrate using the VK for multiple input fields.

Here’s the XAML for the demo-app:

<Window x:Class=“JhVirtualKeyboardDemoApp.MainWindow”
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml&#8221;
Title=“JhVirtualKeyboard Demo Application, by James W. Hurst” Height=“247” Width=“359” Background=”{StaticResource dialogBackgroundBrush}>
<DockPanel LastChildFill=“True”>
<StackPanel Orientation=“Horizontal” HorizontalAlignment=“Right” DockPanel.Dock=“Bottom” Margin=“0,8,10,8”>
<Button Name=“btnVK” Margin=“5,0” Width=“96” Click=“btnVK_Click”>Virtual Keyboard</Button>
<Button Name=“btnClose” Margin=“5,0” Width=“80” IsCancel=“True” Click=“btnClose_Click”>Exit</Button>
</StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“*”/>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“*”/>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“Auto”/>
</Grid.RowDefinitions>
<Label Name=“lblTextBox” Margin=“25,0,0,0” Padding=“5,5,5,0”>TextBox:</Label>
<TextBox Name=“txtBox” Margin=“20,0,20,10” FontSize=“16” Grid.Row=“1” GotFocus=“txtBox_GotFocus” ToolTip=”{Binding Path=ToolTipForTextBox} IsEnabled=”{Binding Path=IsEnabled} ToolTipService.ShowOnDisabled=“True” />
<Label Name=“lblRichTextBox” Margin=“25,0,0,0” Padding=“5,5,5,0” Grid.Row=“2”>RichTextBox:</Label>
<RichTextBox Name=“txtrichBox” Margin=“20,0,20,5” Grid.Row=“3” GotFocus=“txtrichBox_GotFocus” ToolTip=”{Binding Path=ToolTipForRichTextBox} IsEnabled=”{Binding Path=IsEnabled} ToolTipService.ShowOnDisabled=“True” />
<CheckBox Name=“ckbxEnable” Margin=“20,10,0,0” Grid.Row=“4” Content=“Enable the text controls” IsChecked=”{Binding Path=IsEnabled} />
</Grid>
</DockPanel>
</Window>

Mainly there’s a TextBox and a RichTextBox. The DockPanel on line 1 is there simply as a convenience for sticking the buttons along the bottom. I’ve been in the habit of throwing the DockPanel in there everytime I create a new Window. Note that when you set a Label over another field, if you want it to get quite close you have to set it’s bottom-padding to zero as well as it’s bottom-margin. I leave the other sides at the default padding value of 5.  In some cases I’ve had to use a negative bottom-margin to get it to nudge as near as I wanted. Tried that same method with a girl at the theatre, but that didn’t have positive results.

The two buttons have click-handlers which serve to launch the virtual keyboard, and to close the application.

I use a certain coding formatting standard in all our projects, which I’ve detailed here.

Let’s check out the code-behind for this MainWindow. Here’s the constructor..

  1. using System;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using Hurst.VirtualKeyboard;
  5. namespace Hurst.VirtualKeyboardDemoApp
  6. {
  7.     ///<summary>
  8.     /// The code-behind logic for our MainWindow.
  9.     ///</summary>
  10.     public partial class MainWindow : Window, IVirtualKeyboardInjectable
  11.     {
  12.         // The constructor
  13.         public MainWindow()
  14.         {
  15.             InitializeComponent();
  16.             _viewModel = new ViewModel();
  17.             // Remember which text field has the current focus.
  18.             _txtLastToHaveFocus = txtBox;
  19.             // Set up our event handlers.
  20.             this.ContentRendered += OnContentRendered;
  21.             this.LocationChanged += OnLocationChanged;
  22.             this.Closing += new System.ComponentModel.CancelEventHandler(OnClosing);
  23.             // Set the DataContext to our view-model.
  24.             DataContext = _viewModel;
  25.         }

You add a using pragma for the VirtualKeyboard namespace, and implement the IVirtualKeyboardInjectable interface as shown above. That interface is your contract with the virtual keyboard (VK) so they can interoperate.

Notice what we’re doing on line 20: we have an instance variable, _txtLastToHaveFocus, that serves to point to whichever text field has focus. We use this to tell the VK where to put it’s characters.

Notice also that we have three event handlers defined here. Let’s check these out.

The ContentRendered event handler:

void OnContentRendered(object sender, EventArgs e)
{
// If the Virtual Keyboard was up (being shown) when this application was last closed,
// show it now.
if (Properties.Settings.Default.IsVKUp)
{
ShowTheVirtualKeyboard();
}
// Put the initial focus on our first text field.
txtBox.Focus();
}

We have 3 things going on here.

1. As you can see on the first line within the method, it remembers whether the VK was up when we last ran this application. To achieve this, you simply add a boolean flag to your settings; in this case we named it IsVKUp.

2.  Invoke the VK using method ShowTheVirtualKeyboard. This is placed here, within the ContentRendered handler, because at this point your Window is already rendered and the VK can know where to position itself.

3. On the final line of code we set focus to the TextBox. Thus, you’ll still see the nice blinking caret in your text field, just as you would without the VK.

Here’s the ShowTheVirtualKeyboard method:

  1. public void ShowTheVirtualKeyboard()
  2. {
  3.     // (Optional) Enable it to remember which language it was set to last time, so that it can preset itself to that this time also.
  4.     VirtualKeyboard.SaveStateToMySettings(Properties.Settings.Default);
  5.     // Show the keyboard.
  6.     VirtualKeyboard.ShowOrAttachTo(this, ref _virtualKeyboard);
  7.     // (Optional) Call this for each text field for which you want the virtual keyboard to also remap your physical keyboard.
  8.     _virtualKeyboard.HandleKeysForControl(txtBox);
  9.     _virtualKeyboard.HandleKeysForControl(txtrichBox);
  10. }

This is where we fire up the VK.  You’re doing 2 things here.

1. By calling SaveStateToMySettings, you tell it how to save it’s state to your application settings. This is optional.

2. You call ShowOrAttachTo to launch the VK. You pass it the this pointer, so it knows who it’s owner Window is. You give it a reference to your local _virtualKeyboard instance variable, so you have a reference to it.

You need to implement the IVirtualKeyboardInjectable interface. Here’s how the demo app does this:

public System.Windows.Controls.Control ControlToInjectInto
{
get { return _txtLastToHaveFocus; }
}

By implementing the ControlToInjectInto property, you tell the VK where to send the characters that your user types into it.

If you have just one text field, you would simply return that (the instance-variable for the field). Here, we have two text fields. So we instead track which one has focus using this instance-variable, and return that in this property getter.

Let’s check out something else fun..

///<summary>
/// Handle the LocationChanged event, which is raised whenever the application window is moved.
///</summary>
void OnLocationChanged(object sender, EventArgs e)
{
// Do this if, when your user moves the application window around the screen,
// you want the Virtual Keyboard to move along with it.
if (_virtualKeyboard != null)
{
_virtualKeyboard.MoveAlongWith();
}
}

If you handle the LocationChanged event of your Window thus, then the VK will move around along with your Window, like it’s stuck to it. You can still position the VK itself relative to the application by manipulating it directly. Normally, I include a checkbox in my app’s Options dialog to give the user the ability to turn this on or off.  MoveAlongWith is a Window extension method that we’ll get to in a bit.

Oh yeah.. the click-handler that launches it.  Nothing remarkable here..

///<summary>
/// Handle the event that happens when the user clicks on the Show Virtual Keyboard button.
///</summary>
private void btnVK_Click(object sender, RoutedEventArgs e)
{
ShowTheVirtualKeyboard();
}

And here is the Closing event handler:

///<summary>
/// Handle the Closing event.
///</summary>
void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
bool isVirtualKeyboardUp = _virtualKeyboard != null && VirtualKeyboard.IsUp;
Properties.Settings.Default.IsVKUp = isVirtualKeyboardUp;
Properties.Settings.Default.Save();
}

All this does, is save the Up/NotUp state of your VK to your application’s settings.

Tracking which field has focus:

This demo-app has two text fields so that you can see how to use your VK to serve input into more than one control.

What you need to accomplish this, is pretty simple. We added that instance variable, _txtLastToHaveFocus. This variable has to always be pointing to whichever field is currently holding the focus within your Window. How do we do this?

Simple. We hook up handlers to the GotFocus events of all the text fields, as here..

private void txtBox_GotFocus(object sender, RoutedEventArgs e)
{
// Remember that the plain TextBox was the last to receive focus.
_txtLastToHaveFocus = txtBox;
}private void txtrichBox_GotFocus(object sender, RoutedEventArgs e)
{
// Remember that the RichTextBox was the last to receive focus.
_txtLastToHaveFocus = txtrichBox;
}

As a result, that variable is always pointing to the correct field.

Settings:

I mentioned you need to add something to your application’s settings:

Settings

Here you can see I put two settings. The bool setting, IsVKUp, can be whatever you want to name it. The one that specifies the keyboard layout, though, must be named “VKLayout” or else VK won’t see it.

That’s it as far as how to use this within your own app. Simple, I trust? If you’ve any questions please feel free.

Let’s talk about the design a bit.

The Design of the Virtual Keyboard

I’m quite fond of object-oriented design, especially where it saves time and yields a more elegant creation. Checkit..

Here, we have keyboard layouts. These can be pretty detailed bits of information. Fifty-plus keys that change according to the language/alphabet, tooltips, and double that for the shifted/unshifted states, and then you have to treat the capital letters versus small letters, differently than the distinction between shifted/unshifted symbols. And there’re potentially hundreds of possible keyboard layouts.

On the other hand, some of these have a lot in common. And, considering the central role of the common US-std English-language keyboard, I based the root class of the hierarchy of keyboard layouts upon the English US keyboard to supply the default properties.

Thus, we have a conceptual scheme that begs of an object-oriented class hierarchy. At the top, the root class is the US keyboard layout. Everything else either inherits their stuff from that, or overrides it. Below that, at the second level, are the main variations. Russian (perhaps that should’ve really been called Cyrillic), Spanish, etc. And below that, could be further variations of those.

The economy of data arises when you consider that, e.g. the Spanish keyboard changes only a few things, but wants to leave everything else in place just as with the English US keyboard. So if we can let the Spanish keyboard inherit all the English keyboard features, it only has to override just those keys (and their tooltips, etc.) that it wants to change. The ideal OOP application.

To forge this scheme into our WPF XAML-based application that has fifty data-bound buttons, check it ..

ClassDiagram

If you look at the KeyAssignmentSet class in Visual Studio (VS), you’ll see it has a big honkn glob of instance variables and properties. One for every key-button of the keyboard. I named them “VK_A”, “VK_OEM1”, etc. to match the Win32 definitions.

The class KeyAssignmentSet represents the US English keyboard layout.

The subclass SpanishKeyAssignmentSet, overrides only those properties it wants to change. In this, just seven does the trick. That’s a lot easier than providing for all 50-plus key definitions. Suweet (hugging myself..).

Now, to make this work with our XAML design, merits a bit of intricacy. WPF likes to have stable view-models, to thus be a view of. The VK itself has a main view-model class: KeyboardViewModel. All the key-buttons have view-model objects that are members of KeyboardViewModel. Thus, to apply the appropriate KeyAssignmentSet to that view-model, we have an array of the individual key view-models, and we iterate across those assigning the information from the KeyAssignmentSet to them.

For this check out the method AssignKeys, in VirtualKeyboard.xaml.cs

In response, the WPF view updates itself automatically to reflect the new layout.

In this code I use the term “CodePoint” to refer to a spot within the Unicode standard that’s represented by a specific number, and depending upon which font you happen to be using – maps to a resulting glyph. Unicode is a wonderful resource; a massive amount of work was invested to wrest order and manageability out of the World’s chaos of languages and alphabets.   Here, I use the term “shifted CodePoint” to refer to the character on the upper portion of the key button, such as the Asterisk that is often over top of the digit-8 key.

Here’s the layout with the key-names shown:

VKwKeynames100

A few observations from the XAML of the VK..

xmlns:baseLibWpf=“clr-namespace:Hurst.BaseLibWpf;assembly=Hurst.BaseLibWpf”
xmlns:vk=“clr-namespace:Hurst.VirtualKeyboard”
baseLibWpf:WindowSettings.SaveSize=“True”

I bring in the namespace for the external utility library and assign it to the XML namespace prefix “baseLibWpf”. Then I do the same for the VirtualKeyboard assembly and assign that to “vk”. Note how the syntax varies: one is an external assembly, and the other is a local assembly hence doesn’t require the “;assembly=” part. This is one of those things that if you don’t get it right, you’ll spin wheels trying to figure out why your XAML isn’t recognizing your junk in your trunk.

I set the WindowStyle property to ToolWindow, and the FontFamily to a bound property on our view-model that hopefully yields a font that renders our layout nicely. Arial Unicode MS is one common font that seems to have pretty decent coverage of the non-Latin codepoints. But it doesn’t hurt to have some fun seeking out lovely fonts for this.

Let’s look at one of the key-button definitions:

            <Button Name=“btnSectionMark”
Command=“vk:VirtualKeyboard.KeyPressedCommand”
CommandParameter=“§”
Grid.Column=“2”
Height=“24”
Margin=“6,0,2,1”
ToolTip=“Section sign, or signum sectionis”
Width=“25”>§</Button>

This one injects the section-mark (also called the “signum sectionis” if you want to sound uppity). All the key-buttons use this same KeyPressedCommand, with the command parameter carrying the character to inject. Most of the formatting is set in a Style, but this one overrides the Margin, Width and Height to fine-tune the appearance.

Right now, looking at this XAML in LiveWriter, the button Content shows up with the syntax for the hexadecimal 00A7 value, with the ampersand, pound, x prefix and the semicolon suffix. But at the same time, the published version I’m looking at online in FireFox, shows the actual signum sectionis instead. Hmm..

I use a style for the key-buttons so that I don’t have to type in a ton of markup..

<Style TargetType=”{x:Type Button}>
<Setter Property=“Width” Value=“Auto”/>
<Setter Property=“Height” Value=“Auto”/>
<Setter Property=“FontSize” Value=“18”/>
<Style.Triggers>
<Trigger Property=“IsPressed” Value=“False”>
<!– This is here because we’re setting it slightly differently when the button is being pressed. –>
<Setter Property=“Margin” Value=“0,0,2,1”/>
<Setter Property=“Effect”>
<Setter.Value>
<DropShadowEffect Direction=“315” Opacity=“0.7”/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property=“IsPressed” Value=“True”>
<Setter Property=“Foreground” Value=”{StaticResource brushBlue}/>
<!– Shift the button downward and to the right slightly, to give the affect of being pushed inward. –>
<Setter Property=“Margin” Value=“2,1,0,0”/>
<Setter Property=“Effect”>
<Setter.Value>
<DropShadowEffect Direction=“135” Opacity=“0.5” ShadowDepth=“2”/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

This Style targets all Buttons, thus it becomes the default for all Buttons within that container.

I had to tinker with and fine-tune the sizes, padding and margins to get it to look right.

In the first version I had set the FontFamily to “Bitstream Cyberbase, Roman”. I purchased that due to it’s codepoint-coverage. But I found that different fonts are merited for different languages, so I made that a bindable property within the view-model.

The most interesting thing (well, to me anyway) in this Style is making the key-buttons visually float off the surface a bit, and then seem to push downward (and to the right slightly) when you click on them, to yield that cute 3D affect. As you can see from reading the XAML, the trigger fires when the IsPressed property becomes true. It reacts by setting the margin property to shift it’s position down and to the right, and changes the DropShadowEffect to get that 3D affect.

Here’re how the main key-buttons are defined..

<Button Name=“btnVK_Oem3” Grid.Column=“0” ToolTip=”{Binding Path=VK_Oem3.ToolTip}>
<Button.Content>
<TextBlock Name=“txtblkVK_Oem3”>
<Run Text=”{Binding Path=VK_Oem3.Text, Mode=OneWay}/>
</TextBlock>
</Button.Content>
</Button>
<Button Name=“btnVK_1” Grid.Column=“1” ToolTip=”{Binding Path=VK_1.ToolTip}>
<Button.Content>
<TextBlock Name=“txtblkVK_1”>
<Run Text=”{Binding Path=VK_1.Text, Mode=OneWay}/>
</TextBlock>
</Button.Content>
</Button>
<Button Name=“btnVK_2” Grid.Column=“2” ToolTip=”{Binding Path=VK_2.ToolTip}>
<Button.Content>
<TextBlock Name=“txtblkVK_2”>
<Run Text=”{Binding Path=VK_2.TextShifted, Mode=OneWay}/>
<Run Text=”{Binding Path=VK_2.TextUnshiftedNL, Mode=OneWay}/>
<Run Text=”{Binding Path=VK_2.TextAltGr, Mode=OneWay} Foreground=”{Binding Path=ColorForAltGr}/>
</TextBlock>
</Button.Content>
</Button>

The DataContext of this Window is the KeyboardViewModel. As you can see, the Content of these Buttons is set to the Text property of the VK_1, VK_2, etc. members of KeyboardViewModel. Each of those keybuttons implement INotifyPropertyChanged to keep the GUI apprised of their values when they change. The base class ViewModel implements that for us.

The ToolTip property is also data-bound to the view-model. Each of those KeyViewModel objects (ie, VK_1, etc) also has a ToolTip property.

A slight complication for me was that that Text property, and the ToolTip, needed to yield different values depending upon whether the shift key was in effect.

Here is how that is implemented within the KeyViewModel class …

#region ToolTip
///<summary>
/// Get the ToolTip, whether it corresponds to the unshifted, shifted, or Alt codepoints.
///</summary>
public virtual string ToolTip
{
get
{
if ((s_domain.IsShiftLock
|| (_isLetter && s_domain.IsCapsLock)) && !String.IsNullOrEmpty(_shiftedToolTip))
{
return _shiftedToolTip;
}
else if (s_domain.IsInAltGrState && !String.IsNullOrEmpty(_altToolTip))
{
return _altToolTip;
}
else
{
return _toolTip;
}
}
}public string UnshiftedToolTip
{
get { return _toolTip; }
set
{
if (value != _toolTip)
{
_toolTip = value;
Notify(“ToolTip”);
}
}
}public string ShiftedToolTip
{
get { return _shiftedToolTip; }
set { _shiftedToolTip = value; }
}public string AltGrToolTip
{
get { return _altToolTip; }
set { _altToolTip = value; }
}
#endregion

Here, _domain is a static variable that refers to our KeyboardViewModel. This selects between the unshifted, and the shifted, ToolTip value.

The Text property acts similarly, except that it selects from the key’s Text property if that was explicitly set, otherwise it returns the unshifted or shifted codepoint that was assigned to that key.


Showing the VK

Stretching hard to get to where we want to be

This merited a bit of tinkering. Probably there’s a better way to do this, but it’s what I was able to get to work. If you know of a better way, please share.

The exception-handling is something that you’ll want to adapt to your specific application; what I use here is just one example of a system-wide method.

Here’s the code…


///<summary>
/// Either create and show, or else re-attach to (if it’s already up) the virtual keyboard.
/// To be called from the desired target-Window that wants to use it.
///</summary>
///<param name=“targetWindow”>The Window that wants to be the owner of the virtual-keyboard Window and the target of it’s output</param>
///<param name=“myPointerToIt”>The targetWindow’s own instance-variable that will point to the virtual keyboard object</param>
public static void ShowOrAttachTo(IVirtualKeyboardInjectable targetWindow, ref VirtualKeyboard myPointerToIt)
{
try
{
_desiredTargetWindow = targetWindow;
// Evidently, for modal Windows I can’t share user-focus with another Window unless I first close and then recreate it.
// A shame. Seems like a waste of time. But I don’t know of a work-around to it (yet).
if (IsUp)
{
Console.WriteLine(“VirtualKeyboard: re-attaching to a different Window.”);
VirtualKeyboard.The.Closed += new EventHandler(OnTheKeyboardClosed);
VirtualKeyboard.The.Close();
myPointerToIt = null;
}
else
{
myPointerToIt = ShowIt(targetWindow);
}
}
catch (Exception x)
{
Console.WriteLine(“in VirtualKeyboard.ShowOrAttachTo: “ + x.Message);
IInterlocution inter = Application.Current as IInterlocution;
if (inter != null)
{
inter.NotifyUserOfError(“Well, now this is embarrassing.”, “in VirtualKeyboard.ShowOrAttachTo.”, x);
}
}
}

Yeah, it’s not the trivial call to ShowDialog that we’d expect, is it?

The complication is: if it was already showing, but owned by some other window, and this window (the one you’re actually trying to get to use the VK now) was launched modally, it can’t just “take ownership” of the VK Window. The only thing I could get to work, was to shut the VK down and then re-launch it.

Thus, here we tell the VK to close itself, and hook into the Closed event so that another method gets called after the VK closes. That other method, in turn, re-launches the VK.

A bit of usability testing revealed that your users, in attempting to enter their stuff using the mouse, preferred a shift-key that would reset itself. So, clicking on either of the shift keys pushes the VK into the shifted state, and then clicking on any character pops it back into the un-shifted state. But if the user delays, it resets itself after ten seconds. Here’s what does that..

///<summary>
/// Flip the state of the SHIFT key-button.
///</summary>
private void PutIntoShiftState(bool bShiftLock)
{
ClearTimer();
// Set the shift-lock state.
_domain.IsShiftLock = bShiftLock;
UpdateTheKeyBindings();// If we’re turning Shiftlock on, give that a 10-second timeout before it resets by itself.
if (bShiftLock)
{
// If we’re going into shift-lock state,
// regard the AltGr state as mutually-exclusive and turn that off.
_domain.IsInAltGrState = false;
// Set the reset-timer.
_resetTimer = new DispatcherTimer(TimeSpan.FromSeconds(10),
DispatcherPriority.ApplicationIdle,
new EventHandler(OnResetTimerTick),
this.Dispatcher);
}
SetFocusOnTarget();
}

Note that every time your user clicks on anything within the VK, the VK’s Window gets focus. Which is not what we want! Thus we follow that with a call to SetFocusOnTarget, which tosses focus back to your text field.

Doing the actual key character injection

Here is the method that actually inserts the character into your target text-field..

#region Inject
///<summary>
/// Type the given string into whatever the target TextBox (or similar control) is.
///</summary>
///<param name=“sWhat”></param>
public void Inject(string sWhat)
{
if (TargetWindow != null)
{
((Window)TargetWindow).Focus();
TextBox txtTarget = TargetWindow.ControlToInjectInto as TextBox;
if (txtTarget != null)
{
if (txtTarget.IsEnabled && !txtTarget.IsReadOnly)
{
if (_domain.IsFlowDirectionLeftToRight
|| (!_domain.IsFlowDirectionLeftToRight && !_domain.IsForcingLeftToRight))
{
txtTarget.InsertText(sWhat);
}
else  // the FlowDirection is backwards, but the user wants to force it to insert LeftToRight.
{
txtTarget.InsertTextLeftToRight(sWhat);
}
MakeKeyPressSound();
}
else
{
if (!txtTarget.IsEnabled)
{
SetStatusTextTo(“Cannot type into disabled field”);
}
else
{
SetStatusTextTo(“Cannot type into readonly field”);
}
}
}
else
{
RichTextBox richTextBox = TargetWindow.ControlToInjectInto as RichTextBox;
if (richTextBox != null)
{
if (richTextBox.IsEnabled && !richTextBox.IsReadOnly)
{
richTextBox.InsertText(sWhat);
MakeKeyPressSound();
}
else
{
if (!txtTarget.IsEnabled)
{
SetStatusTextTo(“Cannot type into disabled field”);
}
else
{
SetStatusTextTo(“Cannot type into readonly field”);
}
}
}
else // let’s hope it’s an IInjectableControl
{
IInjectableControl targetControl = TargetWindow.ControlToInjectInto
as IInjectableControl;
if (targetControl != null)
{
targetControl.InsertText(sWhat);
MakeKeyPressSound();
}
}
//else   // if you have other text-entry controls such as a rich-text box, include them here.
//{
//    FsWpfControls.FsRichTextBox.FsRichTextBox txtrTarget
//     = TargetWindow.ControlToInjectInto as FsWpfControls.FsRichTextBox.FsRichTextBox;
//    if (txtrTarget != null)
//    {
//        txtrTarget.InsertThis(sWhat);
//    }
}
}
}///<summary>
/// Inject the character represented by the given “key” switch view-model, into whatever the target TextBox is.
///</summary>
///<param name=“vm”>The KeyViewModel that carries the information of what to inject</param>
public void Inject(KeyViewModel vm)
{
// The Tag would’ve been another way to associate the view-model with the button.
if (vm != null)
{
if (vm == _domain.EnterKey)
{
Inject(Environment.NewLine);
}
else
{
Inject(vm.CodePoint.ToString());
}
}
// If we were in Shift-mode, reset that now.
_domain.IsShiftLock = false;
ClearTimer();
}
#endregion

This part can merit a bit of thought. Out-of-the-box, I have provided for two possible controls: a TextBox, and a RichTextBox.

I make a call to your method ControlToInjectInto, to get a reference to what to put the character into. I try to find what it is by casting it to first one type and then another.

For either of these, I defined an extension method InsertText, to do the actual text insertion. Which was surprisingly non-trivial.

In an effort to accommodate you custom-text-box creators, I also defined an interface IInjectableControl. If you have a text field that is neither a TextBox nor a RichTextBox, if you can make your control implement this interface, it’ll still work. Otherwise, you’re going to have to modify this code to make it work for you. Well, that’s the great thing about getting a project complete with source-code, isn’t it? You’ll need to code for your control here, and also in the method DoBackSpace – which btw uses the built-in editing command EditingCommands.Backspace to actually do the BACKSPACE. It was actually simpler to just manipulate the text directly. But I wanted to play with the commanding approach. So I add a command-binding to this control at this point, use that to execute the Backspace operation, and leave that command-binding in place until the keyboard closes at which time we clear it.

The Extension Methods

Here’s the InsertText extension method for TextBox, which you’ll find in BaseLibWpf.WPFExtensions.cs

///<summary>
/// Insert the given text into this TextBox at the current CaretIndex, and replacing any already-selected text.
///</summary>
///<param name=“textbox”>The TextBox to insert the new text into</param>
///<param name=“sTextToInsert”>The text to insert into this TextBox</param>
public static void InsertText(this System.Windows.Controls.TextBox textbox, string sTextToInsert)
{
int iCaretIndex = textbox.CaretIndex;
int iOriginalSelectionLength = textbox.SelectionLength;
textbox.SelectedText = sTextToInsert;
if (iOriginalSelectionLength > 0)
{
textbox.SelectionLength = 0;
}
textbox.CaretIndex = iCaretIndex + 1;
}

Yeah, looks a bit verbose.

Here’s the InsertText extension method for RichTextBox:

///<summary>
/// Insert the given text into this RichTextBox at the current CaretPosition, replacing any already-selected text.
///</summary>
///<param name=“richTextBox”>The RichTextBox to insert the new text into</param>
///<param name=“sTextToInsert”>The text to insert into this RichTextBox</param>
public static void InsertText(this System.Windows.Controls.RichTextBox richTextBox, string sTextToInsert)
{
if (!String.IsNullOrEmpty(sTextToInsert))
{
richTextBox.BeginChange();
if (richTextBox.Selection.Text != string.Empty)
{
richTextBox.Selection.Text = string.Empty;
}
TextPointer tp = richTextBox.CaretPosition.GetPositionAtOffset(0, LogicalDirection.Forward);
richTextBox.CaretPosition.InsertTextInRun(sTextToInsert);
richTextBox.CaretPosition = tp;
richTextBox.EndChange();
Keyboard.Focus(richTextBox);
}
}

This took a bit of tinkering, just to get to insert a simple character. It’s not as simple as simply appending to the text: if the caret is not at the end, you have to insert at the caret and slide everything to the right (speaking in terms of array-indices).

Conclusion

So, there you have it – a working screen-based virtual keyboard created using C# and WPF. I hope this is useful for you, and that you’ll give me your thoughts and suggestions.   I find WPF fun to work with: it feels so natural now that I dislike using anything else for a desktop GUI application. But there’s always new bits to learn. Next up – a Mac and Linux implementation.

This project was introduced as an article on The Code Project.

This project is also published on CodePlex, which is also a convenient place for you to participate in discussion on this project.

James Witt Hurst

Posted in C#, CodeProject, silverlight, Software Design, The .NET Framework, WPF | Tagged , | 37 Comments