MATLAB Answers

Listbox is ignoring command to reset ListboxTop

23 views (last 30 days)
AstroGuy1984
AstroGuy1984 on 24 Apr 2017
Commented: Corey on 18 Sep 2020 at 14:34
I am writing a GUI (WITHOUT GUIDE) using 2016A. One element in this GUI is a uicontrol listbox in which the user can select multiple elements. This listbox is created within a panel like so:
uicontrol('Parent', selSeries, 'Style', 'listbox', 'Min', 0, 'Max', 1e3,...
'FontSize', 8, 'units', 'normalized', 'Position', [0.02, 0.02, 0.94, 0.94],...
'Tag', 'selectSeriesChoiceBox', 'Callback', @selectSeries_Callback)
Where selSeries is a panel within a uitab object within a uitabgroup which resides in the figure.
The first thing I do within the callback is to invoke the "old" data selection and using some logic, reference it with the "new" selections. The purpose of this is to allow the user to just click down the list like a checklist, without having to use CTRL or SHIFT to make multiple selections. I use get/setappdata to accomplish this, and the behavior is as I desire.
When I set the new values, however, MATLAB will (as designed) automatically change the position of the scrollbar. I wish to retain the user's scrollbar position. So I try to update the property 'ListboxTop' after I set the new listbox values. This processes without error, but it is ignored.
function selectSeries_Callback(hObject, event)
% LOGIC TO DETERMINE NEW VALUES VECTOR - newValue
userTop = hObject.ListboxTop;
hObject.Value = newValue;
hObject.ListboxTop = userTop;
% OTHER CODE
end
I have also tried the method of setting the properties using set(hObject, 'ListboxTop', userTop).
Adding to the mystery is the behavior in debug. If I again try to set the property within the shell, the listbox again ignores me without error. HOWEVER, if I were to pull all properties in the shell, (e.g. get(hObject) or clicking "all properties") and THEN setting the property, it worked.
This gave me the idea for a quick workaround to try doing that in the code as such:
function selectSeries_Callback(hObject, event)
% LOGIC TO DETERMINE NEW VALUES
userTop = hObject.ListboxTop;
hObject.Value = newValue;
tmp = get(hObject);
hObject.ListboxTop = userTop;
% OTHER CODE
end
This did not solve my issue. The listbox again remains at the bottom position and doesn't reset to where I am asking it to. However, if I set a breakpoint at tmp, and then F10 through those two lines, it works!
This implies to me that there's something subtle I'm missing with the activity of the object. Maybe something is getting loaded (or some such) when the breakpoint is hit? I've also tried putting in a pause to see if maybe something needed to be caught up.
Any insights that could be provided to fix this would be greatly appreciated. Thanks!

  4 Comments

Show 1 older comment
Bernard
Bernard on 24 Oct 2017
Looks like I followed you down the same rabbit hole. I have a data import tool that lists channel names in a listbox and allows the user to select them for importing channel data from files. Some users didn't like having to hold control, because if you forget once, you start over. Now, when you select a new channel, it scrolls down to show the channel with the highest index in the listbox. So I set the ListboxTop property, and it doesn't work in the function or in the command window until you get the hObject first.
I'm running 2017a, so it's still not fixed.
Melvin
Melvin on 25 Oct 2018
I have the same problem in 2017a. It's not scrolling down by setting ListboxTop to the last element. Hope this will get fixed soon.
Corey
Corey on 9 Apr 2020
i have the same issue still with matlab r2019b. i am keeping track of what the user has already selected without them having to hold down control and if i set the listboxtop before leaving the callback function it does not work unless i step through the program.

Sign in to comment.

Answers (2)

Prashant Arora
Prashant Arora on 27 Apr 2017
Hi,
This seems to work for me. I created a uicontrol Listbox, but inside a figure.
h = uicontrol('Parent', gcf, 'Style', 'listbox', 'Min', 0, 'Max', 1e3,...
'FontSize', 8, 'units', 'normalized', 'Position', [0.02, 0.02, 0.94, 0.94],...
'Tag', 'selectSeriesChoiceBox')
%Add some Strings
h.String = repmat({'Hello';'How';'Are';'You'},5);
Then I added the callback as follows
function selectSeriesChoiceBox(object,event)
newValue = object.Value + 1;
userTop = object.ListboxTop;
object.Value = newValue;
object.ListboxTop = userTop+1;
end
One thing which you can possibly try is using a "drawnow" command. This will update the MATLAB figure and maybe that's what's missing.

  0 Comments

Sign in to comment.


Michael Daenen
Michael Daenen on 18 Sep 2020 at 12:25
Edited: Michael Daenen on 18 Sep 2020 at 12:52
I found a workaround for this by adding two extra commands.
h = uicontrol('Style','list',...);
pause(0.1);
get(h,'ListboxTop');
set(h,'ListboxTop',1);

  1 Comment

Corey
Corey on 18 Sep 2020 at 14:34
I think the key to this workaround is requesting the top (and throwing the data away) using get immediately before setting it.
Also consider using drawnow instead of pause for slightly quicker execution.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!