How can I add custom buttons to the existing MessageBox in WPF? Apart from the usual Ok and Cancel buttons, I need to add 3 more buttons and also handle their events.
Short answer: No it is not possible, you need to write a new window.
Long answer: the MessageBox class uses the Win32 MessageBox (or maybe MessageBoxEx) function, this function does not support extending the message box.
It is possible to modify the message box after it is opened, but:
It is a lot of work
It isn't supported
you have to do it using Win32 directly, the message box window is not WPF or even WinForms.
All in all, it's less work to write a window with one TextBlock, one Image and 5 buttons than to mess around with internal implementation details of the MessageBox code.
Related
Is there a way to make an entire WPF Window inert after a button click?
The window is invoked via Window.ShowDialog() and after use, the window is no longer needed for interaction but I leave it open to remind the user of the inputs in TextBox's, ListBox's, and give visual feedback via OxyPlot and so on. I leave it to the user to close the window manually.
One solution is to disable all buttons but that's tedious and it still leaves TextBox's functioning. That's not optimal because for anything to be functioning creates the wrong impression that the Window remains for anything other than looking at. It would be better for every control to be non-functioning by a single setting.
I did it by putting a name on the WPF window code behind and then setting .IsEnabled false upon the appropriate button click. All buttons, combo boxes, text boxes, and even OxyPlot became inert at that point and most parts were greyed out.
Consider creating a dedicated boolean dependency property in your code-behind or viewmodel and binding IsEnabled of every TextBox to the property.
Just out of curiosity,
The Win32 Group Box control is actually a Button control with the style BS_GROUPBOX applied. As the control is static, being simply text with a special border, why is it one of the Button styles, when the rest are all for actual buttons or button-like UI elements which receive user input?
Thanks in advance for any insights.
This goes way back to the 1980s. Everybody that worked on it is drinking pina coladas in Hawai today so we'll have to make-do with a guess. The likely one is that, since it was so very important to minimize the foot-print of Windows back then, that the existing plumbing for the BUTTON control was re-usable to implement a group box as well.
I have some simple code for popping up a "dialog"-like thing over part of my application window. The idea is, the user must dismiss the dialog before continuing to work with that part of the page.
This works by hovering a large semi-transparent rectangle over the part of the page that is supposed to be disabled - which does a nice enough job of blocking clicks to the region. You see this sort of thing a lot in WPF and Web apps, I think.
The problem I have is, the user can still reach all those juicy blocked controls by tabbing to them using the keyboard. "No problem", I hear you say, "just set the IsEnabled on the panel to false, thereby blocking keyboard access".
Unfortunately, disabling the controls:
Doesn't look very nice
Tends to have unintended consequences with custom styles and bindings further down the tree
So, is there a better way to disable a part of the page, without setting the "IsEnabled" property, such that it doesn't change the visual appearance of any of the controls?
Thanks,
Mark
Can you put your "dialog" XAML in a popup window? Then, call ShowDialog() on the window to make it a modal window? If you don't want your popup to look like a standard window, you could always syle it to remove borders, etc.
I solved this by subscribing to the PreviewGotKeyboardFocus event, from the parent element in the tree, and then handling the event such that focus never gets passed to the children.
Also, I had to explicitly remove focus from the "disabled" controls as well, of course.
Alright so first im coding in C using the win32 api, no mfc, no .net, no wxwidgets.
I've created a window with the WC_TABCONTROL class, and have added tabs to it, everything works fine except... I need to have content in each tab, I got the impression from msdn that I needed to create a dialog for each page, and then load the dialog when the user selects a tab. Only problem with this is my main window isnt a dialog, so making the dialog box for the tab fit perfectly is not working too good.
So I'm wondering if there's a better way to do this? I thought about just hiding and showing different controls per tab but that doesn't seem like a good idea.
What I'd like is when my application starts it will resize the window and the tab control to the minimal size needed to fit all the tabs (3-4 tabs), and the window isn't going to be resizable which I guess simplifies things a little bit. I did this by following the example on msdn (Loading each dialog box into memory, looping thru each one and setting a RECT to the minimal size needed then resizing everything), problem is that the size is in dialog box units and I can't convert it to pixels because I don't have a HWND to the dialog box yet.
Basically my question is what is the best way to manage controls on a window with a tab control. So if I have a tab control and the user changes from tab1 to tab2, I want different controls to be displayed to the user.
The basic idea that MSDN is getting at is to have the controls for each tab within their own HWND. The benefit of this is that you can hide/show all the controls within a HWND by hiding/showing that parent HWND. This means that going from one tab to another is just a case of hiding one container HWND, and showing another, which is simpler and more elegant than having to hide/show groups of controls. (It also keeps the dialog handler code for each pane separate, which is usually what you want.) Both approaches are allowed, though: it's often more convenient to create a dialog, but you are not required to.
These container HWNDs don't have to be dialogs, but using a dialog means that windows will populate the contents from a .rc file for you and handle keyboard tabbing automatically. If you create your own HWND, you'll have to do this yourself. You could take a hybrid approach: start off with a dialog, but add your own controls in the WM_INITDIALOG handler if you need to, and even handle WM_SIZE to do custom layout so that the controls fit better.
If you go the create-your-own-HWND route, look up IsDialogMessage() for a simple way to add keyboard tabbing support to your own HWND; and also check out the WS_EX_CONTROLPARENT style so that tabbing between the tabs themselves and the controls in the container HWND work.
Re: "problem is that the size is in dialog box units and i cant convert it to pixels because i dont have a HWND to the dialog box yet." - you may be able to use CreateDialog to create the dialog as invisible - omit WS_VISIBLE from the .rc file - then you can measure/resize as appropriate before you show it.
I have a model dialog consisting of a datagrid, and OK button, and a Cancel button. It probably should be resizable.
What settings for WindowStyle, etc., would you recommend?
If you are asking what technically is involved in displaying a modal window, then it just has to be shown with the ShowDialog() method call. The call will block until the user closes the window.
By default, a window will be shown with a WindowStyle of SingleBorderWindow and the user should be able to resize it.
You may also want to look at the property ShowInTaskbar if you don't want the dialog to appear in the taskbar.
Here's a link to the MSDN docs on the Window class for reference.
This question is nearly impossible to answer with the details given (what does the dialog do? what is the design of your application?), so the only answer I feel can be given is: be consistent.
Make your dialog look as much like the rest of your application as possible, although depending on that design, you may want to draw attention to it a little bit more than your "regular" windows to make sure that it is acknowledged.
You probably want to set the owner of the dialog to the calling window, and you probably want to WindowStartupLocation to be CenterOwner.