We have a list that uses a custom renderer containing a label, a checkbox and two icons (which have click events). This list needs to be made WCAG 2.0 compliant and in order to do that we need the list to be keyboard navigable.
The problem is with being able to move from one list item to the next and have the focus move to the label for the next/previous list item. Specifically, when the user enters the list using TAB button, the label for the first list item receives focus (highlighted box around text) and the entire row in the list is highlighted as the selected item.
However, when the user then presses the down arrow key to move to the next list item, the next row becomes highlighted (is now the selected item) but the focus remains on the label of the previous row (highlight still shown around label for row 1). The only way to get the focus to move to the newly selected row is to tab through the checkbox and two icons. This isn't a big deal if there are only a couple list items but would be a pain if there are 20+ rows in the list.
Is there a way to get the focus to move to the label of the newly selected row as soon as the user moves (using up/down cursor keys) to the new list item? I know a picture would help but I don't have anyway of posting a screenshot online. Any help would be greatly appreciated.
You're going to have to dig into how focus works in Flex. This is not a complete answer, but hopefully you can put together a solution that works for you. I did this about 4-5 years ago in Flex 3, but it should be similar in Flex 4.
How Focus Works in Flex
The main things to know are the FocusManager singleton class and the IFocusManagerComponent interface.
The FocusManager moves the focus around the UI based on user interactions (mouse clicks, keyboard navigation, etc.).
If a component implements the IFocusManagerComponent interface, then the FocusManager will include it in the "tab" loop and allow the component to be focused via keyboard navigation.
How Focus Works With Flex List Components
You've already stumbled onto the peculiarities of how focus works with the List component and item renderers. The Flex List components implement IFocusMangerComponent and so when you tab through the UI the FocusManager sends the focus to the list.
The List may or may not focus the item renderers. In Flex 3 you had to be using editable item renderers for this to happen, it may or may not be the same in Flex 4.
Some Ideas for Solutions to Your Problem
I think there are numerous ways to solve this. Use some combination of these techniques:
override the protected keyDownHandler() method of the List component. I don't have the code handy, but if you look at it's implementation in the List class you should be able to make your overridden version set the focus on the next renderer.
use methods of the FocusManager to find components in the tab loop: getNextFocusManagerComponent(), findFocusManagerComponent(). Check the docs there are others that will be useful. For example, when the user presses the down arrow, you can let the next item renderer get selected, then use findFocusManagerComponent() (passing in the newly selected renderer) and then tell the FocusManager to focus it with the setFocus() method. This is probably not exactly the right approach ;)
By the way, the FocusManger is a Flex singleton object, every UIComponent in Flex has a focusManager property you can use to get a reference to it.
consider disabling focus on objects that don't need to receive focus (like the Label in your item renderer). There are numerous properties to do this: focusEnabled, hasFocusableChildren, mouseFocusEnabled, tabEnabled, tabChildren etc.
consider disabling focus on the List component, but then making your item renderers implement the IFocusManagerComponent interface. Implementing the interface is simple, you just declare it in your class (there's no actual methods to implement). The tricky part will be now your item renderers need to have key down handlers (just override the protected keyDownHandler() method that all UIComponent objects have).
I think there are other techniques you can use, it's just been too long since I did this. I'd be happy to provide more help if you get stuck somehwere...
Related
I am using win32, c++.
I have a ListView & i want to disable (grey out) only some of the items from the list.
Is that possible or only whole ListView can be greyed out?
The ListView control does not have a concept of disabled items. You can simulate that appearance using custom drawing support. This Sample demonstrates how to change the text and background color of items within the list view.
You would need to go further and provide some means of determining when a disabled item is selected within the view (as the selection will continue to work).
The Windows List View Common Control does not have a disabled state for Items. If you want to do that, you will have to implement it yourself.
This is a not-trivial exercise. It's not hard to change the visible appearance using customer draw, but handling hit-testing and selection would be quite complex.
I have a map application and a submenu which has dynamically added objects (i.e. points on a map) added to the submenu, depending on the layer that is loaded. I have the ability to hide each individual objects (i.e. a point) by clicking on the corresponding submenu item. Is there any way to organize the submenu? When there are a lot of points (i.e. 100) the entire submenu takes up the screen. Can I add a scrollbar to a submenu? I looked in the documentation, but couldn't find anything that support this feature.
From this bug report I was able to find out that you could do the following:
submenu->setStyleSheet("QMenu { menu-scrollable: 1; }");
Works like a charm.
There is no such possibility as far as I know.
Maybe you shouldn't use a sub menu for this but prefer a menu entry that show a Point manager GUI of your own which would have a QListWidget displaying all your points items.
I'm aware that this solution will break a (big?) part of your code but I don't see anything else.
I think you may be able to get the effect you want by creating and using your own QStyle subclass (via QApplication::setStyle()), and overriding the styleHint virtual method to return 1 when the StyleHint parameter passed in is SH_Menu_Scrollable. At least, that works for me when I create large QMenu objects and show them as popup menus.... It may also work for QMenus attached to the menu bar, but I havent tried that.
Whilst it is possible by subclassing the QMenu class to create a custom widget and going from there you're better off looking at a better way to display that information. You'll save yourself time and it'll be much easier for your users to not have to scroll through a big list of items in a small area.
I have two CListCtrl objects in my form. I want selected list in both of them be same.
How I can do it.
I want duplicate the message that sent to a ClistCtrl and send to other one.
How I can do it?
if this is a good way?
thanks herzl
So, essentially what you're saying is that you want the lists to be synchronized.
You can easily achieve that by adding an event handler to catch the user's selection inside you list control, by adding: ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnItemChangedList1) to your dialog/window's message-map.
Inside OnItemChangedList1(), get the index of the currently selected item by calling GetFirstSelectedItemPosition(), and set that as the current index in your second list by calling SetSelectionMark().
This way, whenever the user will click on the 2nd item, for example, in List_A, the 2nd item in List_B will be selected as well.
There ought to be a function that brings that row into view, if it's not in view already, but I can't find it.
I hope that raps it up, ListView's have changed a lot since I've used them, but feel free to ask more if anything is unclear.
First what I want: The ability to display a grid with multiple columns, each cell having a custom render callback. So you might use such a control to display your inventory in a game, or something like the behaviour in Google Chrome where it shows a grid of popular pages you visit.
I've been playing with CListCtrl and while I can get custom rendering ability on each item, I can't get it work with columns - having say 3 items per row. The control has column-related methods but I think these are specifically for the built-in functionality where different attributes of an item are shown automatically in each column... not for providing a generic grid control.
So, does such functionality exist in MFC? If not then I wonder if the easiest approach is for me to actually insert each of the rows as an Item... and then the custom rendering draws the multiple cells in the row, I could also do custom UI to support clicking on the cells.
But what I really want is to be able to create a custom control, and add this as an item to a list - like in Flex for instance - so I/O etc is automatically handled.
Any advice/information welcome...
Dundas has thrown some of its (excellent) components in the public domain. Their Ultimate Grid is available on CodeProject.
I'm not aware of a built-in control, but I think you should take a look at this.
The article is describing in detail the functionality of a fully featured MFC grid control, derived from CWnd, for displaying tabular data.
YOUR_LIST_CONTROL.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES);
I think it will help you (SetExtendedStyle).
I suggest this one:
https://code.google.com/p/cgridlistctrlex/
very complete
I've got a MFC CTreeCtrl stuck in a dialog with the TVS_CHECKBOXES style turned on. I get checkboxes next to all my tree items fine. In OnInitDialog I set the checked state of some of the items using CTreeCtrl::SetCheck but none of the items in the tree are checked when the tree is displayed. SetCheck is returning TRUE. Checking items with the mouse works fine. Anyone encounter this before?
Figured out what the problems was. I was setting the TVS_CHECKBOXES style in the visual studio resource editor. Apparently this causes the problem I was having with the initial checks. Instead you have to do
m_nodeTree.ModifyStyle (TVS_CHECKBOXES, 0);
m_nodeTree.ModifyStyle (0, TVS_CHECKBOXES);
before filling the tree in OnInitDialog. Once I did this everything worked fine.
I created myTreeCtrl using this code:
myTreeCtrl.Create(WS_CHILD|TVS_HASBUTTONS|TVS_CHECKBOX|, CtrlRect, this, IDC_TREECTRL);
I tried to check some items in OnInitialDialog() and had the same problems.
I tried:
myTreeCtrl.ModifyStyle(TVS_CHECKBOXES, 0);
myTreeCtrl.ModifyStyle(0, TVS_CHECKBOXES);
And now it works fine.
More than that, it didn't check the item if it was not in the visible part of the window. I had to put a trigger on OnVScroll().
Check boxes in tree view controls are quirky. As documented:
If you want to use this style, you must set the TVS_CHECKBOXES style with SetWindowLong after you create the treeview control, and before you populate the tree. Otherwise, the checkboxes might appear unchecked, depending on timing issues.
In other words, you cannot set the TVS_CHECKBOXES tree view style at control creation time. Control styles set in Visual Studio's resource editor (which is just a graphical front-end for the .rc script) are used at control creation time.
The solution is fairly simple: Create the control without the TVS_CHECKBOXES style, and turn it on in code, before you populate the control:
::SetWindowLong( hwndTreeView, GWL_STYLE,
::GetWindowLong( hwndTreeView, GWL_STYLE ) | TVS_CHECKBOXES );
In MFC this can be done using
m_treeView.ModifyStyle( 0x0, TVS_CHECKBOXES );
where m_treeView is the tree view control instance variable.
Background information:
Check boxes weren't part of the initial tree view control implementation. They were added later on, following the scheme developers were using that needed check boxes before they were available: By using a state image list and setting state item indices on the tree view items.
One of the issues that needed to be addressed was determining the check box size. If the tree view control has an image list (the "normal image list") assigned, the check boxes should match the size of those images. Otherwise, the check boxes should use the system small icon size. A corollary of this is that if you are using a "normal image list", you need to enable the TVS_CHECKBOXES style after setting the image list.
Another quirk is, that the state image index 0 means "no state image" at all (1 refers to the "unchecked" state item image). If you add an item to a tree view control that has the TVS_CHECKBOXES style set, the control sets the state item index to 1 (even if you specify 0). That's why all items appear unchecked, when you set the TVS_CHECKBOXES style at creation time. This also implies, that if you want a tree view item without a state image, you have to add the tree view item, and then manually reset the state item index.
This should be enough information, to understand and solve the question as asked. There's a lot more to the tree view implementation, but I'll leave that to someone, that is better equipped to write about it. Refer to the references below.
References:
Raymond Chen (The Old New Thing) has published an extensive series covering the tree view control quirks. Not all of the entries are immediately relevant to this question, but each and every one is insightful and valuable, one way or another, so I'll just list them all:
The TVS_CHECKBOXES style is quirky, which is a polite way of saying that it is crazy
Beware of the leaked image list when using the TVS_CHECKBOXES style
Creating tree view check boxes manually: A simple state image list
Creating tree view check boxes manually: Responding to clicks
Creating tree view check boxes manually: Themed check boxes
Tree view check boxes: A sordid history
Tree view check boxes: The extended check box states