A friend of mine who is learning WPF recently asked me how to load forms dynamically into the panes of a tab control. Being the helpful sort I am, I wrote up a quick app that demonstrates this.
Essentially, the idea is to create the forms as UserControls, and then load these at runtime into the host control (either a TabItem or some other Content or Item control such as a Grid). Remember that for a Content Control, you would set mycontrol.Content to the new form, while an Items control can contain multiple children, so to replace the content with a form you would call mycontrol.Children.Clear(), followed by mycontrol.Children.Add(newform).
The demo app is available here.
Posted in Coding
Tagged .NET, Tutorial, WPF
I am writing a WPF application which runs as a tool-style dialog on the desktop, and needs to be able to be minimized but not maximised. It seems that this is somthing the WPF designers didn’t quite anticipate, despite it having been pretty easy to achieve under Windows Forms.
After searching around the ‘net, I finally found some code that disabled both the minimize & maximize buttons, but took a couple shortcuts that I didn’t like (and besides, it was in VB…).
A bit of searching and a quick cleanup left me with a working result. Catch the Loaded event of your window, and put the following code into the handler:
// Import some references
// Place these inside the class definition...
private extern static Int32 SetWindowLong(IntPtr hWnd, Int32 nIndex, Int32 dwNewLong);
private extern static Int32 GetWindowLong(IntPtr hWnd, Int32 nIndex);
private const Int32 GWL_STYLE = -16;
private const Int32 WS_MAXIMIZEBOX = 0x10000;
private const Int32 WS_MINIMIZEBOX = 0x20000;
// And finally the event handler...
private void Window_Loaded(object sender, RoutedEventArgs e)
IntPtr hWnd = new WindowInteropHelper(this).Handle;
Int32 windowLong = GetWindowLong(hWnd, GWL_STYLE);
windowLong = windowLong & ~WS_MAXIMIZEBOX;
SetWindowLong(hWnd, GWL_STYLE, windowLong);
I have included the value for WS_MINIMIZEBOX in case you need it.
Posted in Coding
Tagged C#, Interop, WPF
I just posted this up on the MSDN forums, and then worked out the answer myself (so posted my own answer – is that allowed?). Thought it would be good to keep track of for future reference, so here goes…
I’ve got an application where I need to validate a text field as the control loses focus (i.e. as the user thinks (s)he is finished with it), pop up a Message Box informing the user of their error, and then re-focus the TextBox.
My WPF includes (simplified)
|<TextBox x:Name=“txText” LostFocus=“txText_LostFocus” />
which calls the following
|private void txText_LostFocus(object sender, EventArgs e)
| /* Check for valid input */
| if (/* not valid */)
| MessageBox.Show(“You have entered an incorrect value”);
Problem is, the txText.Focus() line triggers the LostFocus event again, so I end up with a never-ending Message Box loop!
I am aware that I could get around this by using validators and adorners on the TextBox, but I would like the Message Box, and for the TextBox to keep focus if bad data is entered.
There doesn’t seem to be a PreviewLostFocus event – is this correct?
The light came on soon after…
And the answer is… I’m a dope.
Just minutes after posting this question I noticed that there is in fact a PreviewLostKeyboardFocus event. Capturing this event and setting e.Handled = true on an invalid input condition does exactly what I was after. Further, using a KeyboardFocusChangedEventArgs argument in the event handler allows me to check the NewFocus control, and if is equal to (eg) the Cancel button on my dialog, validation can be bypassed.