I’ve been using the DatePicker control (which can be found in WPF 4.0 as well as the WPF Toolkit) and have come across a situation where I would like to set keyboard focus on a DatePicker programmatically so that the user can immediately begin typing a date into the control. Well like many other people out there I attempted to do this by calling the controls Focus() method and when that didn’t have the desired results I tried Keyboard.Focus() and passed it the DatePicker. This also didn’t accomplish what I was looking for.
In the above cases the DatePicker would indeed gain focus, however you could not immediately begin typing in a date. If you pressed a navigational key on the keyboard such as Tab or any of the directional arrows it would then put the keyboard focus into the TextBox portion of the control and highlight any existing text.
Focus, but not on text…
Focus on text!
Since this is exactly the end result I was after I set about automating this in code and arrived at the following solution. Basically all I’m doing is simulating the Up Arrow being pressed on the DatePicker control, this causes the control to move focus to the internal TextBox. It’s very hacky but it’s the best thing I could come up with without inheriting from DatePicker which I’d like to avoid. I wrapped the code up in a nice extension method for ease of use, and that’s what you see below.
using System.Windows.Controls;
using System.Windows.Input;
namespace CGS
{
public static class DatePickerExtensions
{
public static void FocusOnText(this DatePicker datePicker)
{
Keyboard.Focus(datePicker);
var eventArgs = new KeyEventArgs(Keyboard.PrimaryDevice,
Keyboard.PrimaryDevice.ActiveSource,
0,
Key.Up);
eventArgs.RoutedEvent = DatePicker.KeyDownEvent;
datePicker.RaiseEvent(eventArgs);
}
}
}
If anyone knows of a cleaner, more legitimate way to accomplish this please let me know! As always questions and comments are welcome and appreciated.
I’ve spent a bit of time scouring the internet for a WPF Time Control that supports 12-hour format. There are several examples out there that are in 24-hour format, but I haven’t seen any for 12-hour format, so I wrote one. I began with some code located here and then modified it extensively to work for my situation. I didn’t need to display seconds, however it would be pretty easy to add them.
This control supports a wide range of keyboard input. You can enter the value for Hour, Minute, and Part of Day by either using the up/down arrow keys or by typing in numbers and letters. If you have any questions/suggestions/praise/opinions please feel free to leave a comment!
// Set the time of the control
this.timeControl.Value = DateTime.Now.TimeOfDay;
// Get the time from the control
TimeSpan time = this.timeControl.Value;
This is a followup post to the one I wrote on Enabling Controls with a CheckBox. In that post we created some XAML that would enable/disable controls in the GUI based on the IsChecked property of a checkbox.
Here’s an enhancement to that:
So what we’re doing is giving the controls on our dialog a nice visual grouping letting the user know that they’re associated. The GroupBox element has long existed to fulfill this need. However, with this little XAML change it also doubles as a sort of access control for the items it contains.
So all we’ve done here is add the CheckBox to the <GroupBox.Header>element of the GroupBox. Pretty slick!
This little technique is complete UI Candy and in my opinion illustrates one of the many powerful features of WPF: the ability to customize the GUI in any way you want, down to any level!
So I’ve been getting pretty fancy with my GUI development, and today I wanted to design a button that would appear as just flat text until you hovered over it with the mouse, at which point it would “pop up” and look like an actual button.
The following solution only works when run on a system with a Windows Vista/7 theme enabled, such as Aero or Basic. It will not work when run with the Windows Classic theme.
The ‘Flat’ Pop Up Button was achieved by simply setting the background and border to transparent. Here’s the XAML:
The next step was to make it so that when the mouse hovers over the button it “pops up” visually and looks like your standard button. At first I tried several methods for accomplishing this using triggers to set the style of the button which were all turning out to be pretty messy since I’m not the best graphical designer.
But silly me, I didn’t realize that in this case I didn’t have to do anything special at all! I could just leave the button as it is in the XAML above and the baked in triggers for the Button would still kick in and change the appearance when the mouse hovered over it.
Here’s what that looks like:
It looks pretty cool in spots where you want a nice, Aero style button, but if the user isn’t interacting with it you don’t want all those pixels distracting from the clean whiteness that is your polished application.
While XAML in WPF is probably the most powerful GUI development architecture I’ve ever used and by far my favorite, there’s still a few little tasks here and there that I just scratch my head trying to figure out.
This is probably due to my limited knowledge of XAML and how to use it properly, so until I get it all mastered I’m forced to use lines of DuctTape to get some of the results I want.
Here’s my most recent hack job. If you look at the XAML below you’ll notice that I’m making use of the Tag property of the button. This is just an example, but in real life there’s actually quite a few valuable uses for Tag.
<button content="Am I the right button?" tag="False" click="Button_Click"></button>
<button content="Am I the right button?" tag="True" click="Button_Click"></button>
<button content="Am I the right button?" tag="False" click="Button_Click"></button>
So in this example the user needs to click the right button. The right button is indicated by its tag property. In this case the second button is the one that works, right?
Not exactly.
The code to handle this situation would look something like this:
private void Button_Click(object sender, RoutedEventArgs e)
{
var sourceBtn = sender as Button;
bool isRight = (bool)sourceBtn.Tag;
}
Since Tag is defined as an object and I’m binding it to “False” in my XAML I thought this code would work out just fine, but it doesn’t.
The problem is Tag gets populated with a string instead of a boolean. That’s interesting, after all why shouldn’t it? How is XAML supposed to know that what I wanted to set to Tag is the boolean value False? It doesn’t.
So I had to write my XAML in such a way that it knew without a doubt that I was using a boolean value.
The first thing in accomplishing this was to include the System namespace in my XAML file, like so:
Then I could declare my Tag property full out giving it a system:Boolean for its value.
<button content="Am I the right button?" click="Button_Click">
<button.tag>
<system:boolean>False</system:boolean>
</button.tag>
</button>
<button content="Am I the right button?" click="Button_Click">
<button.tag>
<system:boolean>True</system:boolean>
</button.tag>
</button>
<button content="Am I the right button?" click="Button_Click">
<button.tag>
<system:boolean>False</system:boolean>
</button.tag>
</button>
And that’s it, it works! Yay!
But man, it really is ugly. Does anyone know of a cleaner, better way to accomplish the same thing? I would love to learn something new!