Validating menu items - c#

Something that I wanted to know for a long time already:
In a WinForms application you often have an edit menu with entries like Undo and Redo. These menu entries must be enabled or disabled depending on what control has the focus and what it's undo stack state is. For this validation you have to know when the focus changes. Unfortunately, there seems to be no way to accomplish that in a standard C# WinForms application. What I did so far was to add an OnEnter event handler for each control, however this is nasty and doesn't work for controls added by backend code (e.g. in a C++/CLI layer). Another approach is to use a message filter, but WM_FOCUS is not sent through such a filter. Overwriting ActiveControl does not work either, since it is not virtual. So, what else can be done to validate menu items on each focus change?
Note: I have read the article at http://msdn.microsoft.com/en-us/magazine/cc188928.aspx but this approach is way to complicated for such a simple task. I have all my validation code in place already. I only have to trigger it when focus goes to a new control.

Related

Is there a way to execute Undo and Redo processes in a WPF window for every containing controls (not just focused control)

I have a report part in my WPF application which contains some different WPF Pages. I need my report pages to be edittable by user. Each report page contains different Textbox and RichTextBox controls.
Whenever some control's value is changed, if I press ctrl+z and ctrl+y on my keyboard, Undo and Redo will happen only if the control is focused.
Is there any way to extend the functionality of these key combinations to execute Undo and Redo process on all of existing controls in the page without needing to focus on them?
If you lock your effects under a command pattern you can handle the undo/redo events yourself. As long as the wpf controls involved are bound to the data that is done/undone/redone. That makes it possible.
see Undo/Redo Implementation For Multiple Variables
You could use the brute force approach.
Assuming you're using MVVM ( if you're not then you should learn and use it ).
Handle propertchanged in the viewmodel(s) and persist before and after by serialising the entire viewmodel to a collection of viewmodels. One for each state. You then iterate backwards through that collection to go back and forwards to re-apply.
This is relatively easy to implement but the downside is the potential to lose changes between redo.
You could improve on that by adding a bit more sophistication. Retaining a property name, old and new value per propertychange.

Switching controls based on Combo Box Value

I am looking into developing a GUI that will switch the controls based on the value of the selected combo box item.
I have tried adding a different canvas or grid to the gui designer in visual studio but it comes hard to manage as everything overlaps each other in the designer and is hard to know what's what.
Is there an easy way that I can do this, is there a particular control that makes this easy to achieve. I don't really want code the gui in c# and not use xaml.
What I was hoping to do is that all the controls are in there own panel and when the combo box value is changed one panel is removed or hidden and the other is shown.
How can something like this be achieved.
Thanks for any help you can provide
You could implement each different "mode" as a separate UserControl.
Then have a shell with the combobox, where the combobox OnChange will swap out what UserControl is plugged into the shell.
Any other totally common components such as OK/cancel buttons could be part of the shell.
A completely alternative implementation to consider is a tabbed approach, but that probably only flies if it makes sense for the user to act on several of them.
What will you do if the user selects A in the combo, makes changes in UserControlForA, and then selects B in the combo? Could be an annoying corner case, and if this is production code the sort of thing that you'll get future user requests to change how it works.
If you're sure of the design go for it. If not, I'd play around with a few apps and try to find a nice example of the same sort of thing, and consider how they approached it.
But techwise I think a UserControl is what you're describing.
(Edit: crud just saw the xaml/wpf in the question, not sure this is correct in that context, clueless there)
You can use DataTemplate for each different mode.See Different item template for each item in a WPF List for more information.

WPF UI Automation - Control Tree not poluated till region is clicked for a TabControl

I am doing a UI automation for a WPF application using the Microsoft UI Automation library and it works well.
However my app has four screens in a TabControl. Even when I click the tab item through code its child control tree isnt populated. The only control I can see is the "thumb" Control. Same happens when I see the control tree with UISpy.
However if the window is clicked then all the controls appear. As a Workaround I am simulating a mouseclick through code and it works. I wanted to know if there is some better way of doing it.
I ran into a problem similar to this. What was happening was some data was being retrieved on threads and the controls were not generated at the point automation peers were generated. I would suggest if you have access to the code base for the application you are attempting to automate looking into whether threading is being used. In my specific case it was because BeginInvokes were used to retrieve the data, I switched them to Invokes and it worked fine.
Also from what I could tell the reason the controls were being show on mouse over was because the tool tip generated a popup and caused the automation peers to be updated.
Why don't you click the control using mouse events if that is what works.
(Now, if you still are having that problem..)
How to simulate Mouse Click in C#?

How to build a Windows Forms email-aware text box?

I'm building a C# client app that allows a user to communicate with one or more existing users in a system via an email-like metaphor. I'd like to present the user with a text entry box that auto-completes on known email addresses, and allows multiple delimiter-separated addresses to be entered. Ideally, I'd also like the email addresses to turn into structured controls once they've been entered and recognized. Basically, I'm modeling the UI interaction for adding users after Facebook's model.
Are there any Windows Forms controls out there with the ability to do something like this? Is there any well-established terminology for a hybrid textbox / control list box (no, not a ComboBox) or something that I should be searching for?
Thanks,
-Patrick
I have had good luck in the past creating composite user-controls to provide specific functionality using native .NET Winforms controls. It works pretty good as long as there aren't too many of them, in which case things start to slow down.
In you case, and this is just off the top of my head, but, perhaps you could take a FlowLayoutPanel, a Button, and a Textbox which supports auto-complete and put these together to create a control that would provide the functionality you are looking for.
If there are no addresses selected in the control (e.g. in a List<string>), then the container (FlowLayoutPanel) would only display the TextBox. Once the user selected an entry, the control would automatically create a Button with the appropriate caption and insert it to the left in the FlowLayoutPanel. If the user removes an address he/she has already selected, simply remove its representation (the button) from the FlowLayoutPanel, and the TextBox can resize accordingly. There may be issues with getting the TextBox to fill up the remaining space (I can't remember how to do that), but you get the idea. The container does not have to be FlowLayoutPanel - you could use a Panel with Docked controls, or even a TableLayoutPanel for this.
A design as I described would allow the user to delete the address by clicking on the button. However, without some other visual cues, that isn't very intuitive or user-friendly, so I would consider making the "Button" be another composite control which contains a "prettied-up" label along with an tiny delete Button (X) to the right. For this you could use a Panel control and dock the X button to the right, and fill the Label on the left. You would provide public properties here as needed to control the text and provide an event handler or callback for the delete functionality.
Once the visual stuff is working, all that is left is to provide the appropriate Properties and Methods on the main control to allow it to interact as needed with outside code.
As a simple, "poor man's", implementation you could take a look at the AutoComplete* properties of the TextBox control. You could dynamically populate the AutoCompleteSource with your known addresses and when an entry matches, add to a separate, list-style control of your choice.
See this SO article for some interesting code snippets related to your question, and my suggested workaround.
Beyond the built-in AUtoComplete properties you're probably looking at having to purchase a 3rd party control from a tools vendor.
I've not seen anything like that before in WinForms. In WPF it would be another matter - if you can use that, maybe consider hosting a WPF control within your WinForms application instead?
I think you're trying to do something similar to this codeproject article: AutoComplete TextBox
And since you mention WPF in a comment, you also have this article: WPF AutoComplete Folder TextBox (should be easy enough to cut out the folder bit of the article I'd thought).
Well, there isn't such a control. If I were you, I'd create 2 textboxes to do the job. See, a normal textbox can easily be configured for autocomplete from a list, even dynamically; however, it accepts only one entry at a time.
So, I suggest you dedicate one textbox for autocomplete, and one for the addresses. So, whenever there is a qualified email address in the first textbox, and you click enter, the address gets added to the address textbox, and automatically add delimitation.
Then you need to handle the addresses in the address textbox as objects instead of characters. Code it in a way that when a user tries to delete a character in an address, the whole address is deleted.
This is the workaround I can think of. I'll help with the code if you give it a try.

Updating UI objects in windows forms

Pre .net I was using MFC, ON_UPDATE_COMMAND_UI, and the CCmdUI class to update the state of my windows UI.
From the older MFC/Win32 reference:
Typically, menu items and toolbar buttons have more than one state. For
example, a menu item is grayed
(dimmed) if it is unavailable in the
present context. Menu items can also
be checked or unchecked. A toolbar
button can also be disabled if
unavailable, or it can be checked.
Who updates the state of these items
as program conditions change?
Logically, if a menu item generates a
command that is handled by, say, a
document, it makes sense to have the
document update the menu item. The
document probably contains the
information on which the update is
based.
If a command has multiple
user-interface objects (perhaps a menu
item and a toolbar button), both are
routed to the same handler function.
This encapsulates your user-interface
update code for all of the equivalent
user-interface objects in a single
place.
The framework provides a convenient
interface for automatically updating
user-interface objects. You can choose
to do the updating in some other way,
but the interface provided is
efficient and easy to use.
What is the guidance for .net Windows Forms? I am using an Application.Idle handler in the main form but am not sure this is the best way to do this. About the time I put all my UI updates in the Idle event handler my app started to show some performance problems, and I don't have the metrics to track this down yet. Not sure if it's related.
I've found it easiest to have the menu item event handler spawn a background thread that disables the menu item, does the work, and then re-enables the menu item. That way, the UI is available to handle other UI requests, and I don't need to poll for when the operation is complete.
I usually include logic that prevents more than one operation that uses the same resources to happen simultaneously. This means creating a function to disable/enable all similar resources at once. e.g. I might only allow 1 file operation to happen at a time, so I would create a function to disable/enable all the menu items associated with file operations and call it from every one of those menu items.
Just change their property, e.g.
obj.Enabled = true;
or
obj.Enabled = false;
The property of that object will automatically call .Invalidate() or .Refresh() for you, so the control should be repainted automatically.
If you want to do a BIG task which would block the UI for multiple seconds, it's worth using Threads + Delegates.
AFAIK, in the standard .NET System.Windows.Forms world, this functionality is not available out the box.
This problem can be answered in a few ways. The links below are useful resources:
•OnUpdate equivalent
•ActionLists for Windows forms
•Command UI Updating Windows Forms in C#

Categories