Matlab App Designer ListBox.Value changes when ItemsData is an array

Hi All,
I am having a problem with app designer LisxtBox. I have a ListBox and I define the names of my items in a cell array (for example; ch1, ch2, ch3, ch4). When I use the following commands, I can retrieve the selected item or its index
app.ListBox.Value
[~,index] = ismember(app.ListBox.Value,app.ListBox.Items)
However, when I attribute (match) the items with an array (for example; ch1 becomes Nx1, N being the number of data points. I use app.ListBox.ItemsData for defining each items data array), automatically 'app.ListBox.Value' becomes 'Nx1' cell array.
My intention is only be able to retrive the name of the item I selected (when I click on listbox item, I only want to see ch1, ch2 etc., not Nx1 array). Should I use something else rather than 'ListBox.Value'? Can you please help me with that?
Thank you.

 Accepted Answer

I think what you're looking for is,
[~,index] = ismember(app.ListBox.Value, app.ListBox.ItemsData); % Note: ItemsData
% This returns a character vector; it won't work with >1 selection
value = app.ListBox.Items{index};
% This returns a cell containing char-vectors
value = app.ListBox.Items(index);

7 Comments

Thanks for your answer Adam. However, since 'app.ListBox.ItemsData' is not empty (meaning it has 4 'Nx1' cell arrays), I get the following error:
"Error using cell/ismember (line 34)
Input A of class cell and input B of class cell must be cell arrays of character
vectors, unless one is a character vector."
If I use 'app.ListBox.Value', then returns '1×1 cell array'. I just want to see the name of my selected item (I am going to add my item in another listbox and that's why I am trying to see the item name).
I'm having trouble building a mental image of your listbox. Could you add this line to your app which should print the listbox content to the command window? Then copy-paste it in a comment so I can see what's going on.
disp(app.ListBox)
The results should appear in this format,
>> disp(app.ListBox)
ListBox (Apples) with properties:
Value: 'Apples2'
Items: {'Apples' 'Apples' 'Pears' 'Bananas'}
ItemsData: {'Apples1' 'Apples2' 'Pears1' 'Bananas1'}
Multiselect: off
ValueChangedFcn: ''
Position: [100 100 100 74]
K>> disp(app.DataListBox)
ListBox (Ch2) with properties:
Value: {{1×1 cell}}
Items: {'Ch1' 'Ch2' 'Ch3' 'Ch4'}
ItemsData: {{1×1 cell} {1×1 cell} {1×1 cell} {1×1 cell}}
Multiselect: 'on'
ValueChangedFcn: ''
Position: [10 158 96 146]
Basically, I would like to print 'Ch2' or its index, which is '2'.
What is in each cell of ItemsData?
If the cell-of-cells contain a char-vector such as,
items: {{'A'} {'B'} {'C'} {'D'}}
then the solution is as easy as,
[~,index] = ismember(app.ListBox.Value{1}, [app.ListBox.ItemsData{:}]);
If the content of each cell is more complex, you can use a loop or an array function.
index = cellfun(@(c)isequal(app.ListBox.Value,c), app.ListBox.ItemsData);
Note, if there's a way to assign the ItemsData without using nested cells, do that.
Each cell inside ItemsData contains 'Nx1' array (N=4095).
Function you provided gives 1x4 array with zeros inside.
The following for loop worked, thanks to you:
for i = 1:numel(app.ListBox.Items)
index(i) = isequal(app.ListBox.Value{1}, [app.ListBox.ItemsData{i}]);
end
and also the following function:
index = cellfun(@(c)isequal(app.ListBox.Value{1},c), [app.ListBox.ItemsData]);
Then, I can retrive the name as
idx = find(index); % Find indice of nonzero element
ItemName = app.ListBox.Items{idx}
Thank you very much for your help Adam.
"Function you provided gives 1x4 array with zeros inside."
The function returns a logical vector. If the vector is all 0s (all False), that means there are no matches. That could occur for one of three reasons.
  1. No items are selected within the listbox
  2. There's items in ItemData aren't merely Nx1 arrays as described
  3. There are rounding issues with floating point precision.
Here's a demo that my solution should work.
fig = uifigure();
lbx = uilistbox(fig,'Items',{'Apples','Pears','Bananas'}, ...
'ItemsData',{rand(1,4095)',rand(1,4095)',rand(1,4095)'})
index = cellfun(@(c)isequal(lbx.Value,c), lbx.ItemsData)
% RESULT:
% index =
% 1×3 logical array
% 1 0 0
find(index) % = 1 (1st row of list box)
If this approach doesn't work, I can't trouble shoot it without a minimal working example (ie, you can share a simple listbox that reproduces the problem).
But first, let's take a step back. It would be nice if listbox returned an index number of the user's selection. Matlab should implement this!. But in the mean time, you can reorganize and simplify your workflow so that you can use the listbox selection to get the values in ItemsData after the selection is made.
Here's an example adapted from my example above.
% Create a cell array of ListBox options and your data.
% This could also be organized within a table if your arrays are
% all the same lenght.
data = {
'Ch1', rand(1,4095)';
'Ch2', rand(1,4095)';
'Ch3', rand(1,4095)'};
fig = uifigure();
lbx = uilistbox(fig,'Items', data(:,1));
% Get user's selection
[~,index] = ismember(lbx.Value, lbx.Items);
% Get associated data
chosenData = data{index,2};

Sign in to comment.

More Answers (0)

Asked:

on 15 May 2020

Commented:

on 15 May 2020

Community Treasure Hunt

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

Start Hunting!