Problem with value property of uidropdown

Hi,
I'm using a uidropdown control with the Items and ItemsData properties set within the method startupFcn of my app. I'm using the following simple code to specify the items of the dropdown control along with numeric IDs:
app.MethodDropDown.Items = Methods.TYPES(:, 1);
app.MethodDropDown.ItemsData = [Methods.TYPES{:, 2}];
Methods.TYPES is a cell-array in class Methods with the first column containing character arrays (i.e. the names for the method types) and the second column contains numeric ID values for the method types.
When retrieving the value of the selected item I observe a different behavior between different MATLAB versions. Up to 2022b the Value property returns the numeric value of the selected item as specified in ItemsData. However, starting with 2023a, a string (i.e. in my case a character array) is returned.
Am I doing something wrong? I suspect that something changed between 2022b and 2023a but I can't find anything about such a change in the changelog of MATLAB. Moreover, the documentation of 2023a still states that my code seems to be correct.
Best,
Michael

Answers (1)

Hello Michael,
It appears that you're encountering an issue with the 'uidropdown' control in MATLAB R2023a,
I use the same version and attempted to reproduce the problem using a simplified example. Here are the steps I followed and the code that worked correctly for me, returning the numerical ID as expected:
1.Added the startupFcn:
  • In the Component Browser, click on the app node.
  • In the right-hand pane, scroll down to the "Callbacks" section and click on "Add StartupFcn". This will create a new function called startupFcn.
function startupFcn(app)
% Define the Methods.TYPES cell array
Methods.TYPES = {
'Method1', 1;
'Method2', 2;
'Method3', 3;
};
% Set the items and items data for the dropdown
app.MethodDropDown.Items = Methods.TYPES(:, 1);
app.MethodDropDown.ItemsData = [Methods.TYPES{:, 2}];
end
2. I inserted a button to retrive the value and added a callback to it.
% Button pushed function: RetrieveValueButton
function RetrieveValueButtonPushed(app, event)
selectedValue = app.MethodDropDown.Value;
% Display the selected value
disp(selectedValue);
end
you can refer to this MathWorks documentation to know more : uidropdown

5 Comments

Hi,
thank you for the quick reply. I should have come up with the idea to try it with a simple example first, before creating a question here. Sorry about that.
I now also created a simplified example and it works in R2022b as well as in R2023a. So this does not seem to be the problematic piece of code.
Unfortunately, my code is quite complex as it's parts of a really big project. So I can't post the full code. It would be too complex to go through anyways.
But this is what I'm basically doing:
  • I have one app which is used to show a settings dialog. This dialog basically contains an empty panel with a GridLayout in it, which is populated dynamically, depending on the settings category chosen.
  • I have several apps, each implementing the settings page for a certain category. Each of these apps contains a panel which contains all the relevant controls for the settings of the respective category.
  • After choosing a settings category, the respective app is loaded by using its constructor. Once the instance has been created, I copy over the controls from the content panel of the loaded app to the panel of the settings app using
copyobj(panelInstance.ContentPanel, app.SettingsPageGridLayout, 'legacy');
  • Once all controls have been copied over, the loaded app instance is deleted.
Maybe that's an overly compex way of implementing a settings dialog. But in my opinion it's an elegant way to allow to add new settings categories by just implementing another app for that category. And it also keeps code for different categories separated. Maybe it makes more sense if I mention that a category in our program is usually associated with a specific module which can be licensed separately.
I'm not sure if the way of doing it poses problems with more recent versions of MATLAB. But as said, this method worked fine up to 2022b.
But I guess that I'll have to dig deeper into the code to see where things start going wrong.
Best,
Michael
Just as an update: in the meanwhile I managed to condense the code down to a minimum (see attachment). And when I run the app SettingsDialog.mlapp and hit the button "TEST", I get a message box with a numeric output in R2022b. In 2023a, however, I get the text of the item selected in the dropdown "Smoothing method".
And: in the meanwhile I also contacted the MATLAB support. Just because I'm not sure whether this is a bug in more recent MATLAB versions. Who knows.
Best,
Michael
Another update: Mathworks support was able to reproduce the problem and it indeed seems to be a problem with copyobj. It seems like they observed such a behavior already in the past but they are not sure whether this is a real bug. The developers are now looking into this.
Good to know ,
yeah the issue is reproducible with the code provided.
I also noticed that in MATLAB R2023b, there's an update that allows us to access the index of the component value in the list of items using the ValueIndex property.
I believe this might be helpful in the meantime
Yes, the ValueIndex could be a solution to not run into the problem. But for that I would have to rewrite a lot of my code which I simply do not want.
I also have a final update from Mathworks: they confirmed that the problem is caused by a bug in copyobj. An enhancement request has already been filed and it should get fixed in upcoming updates. A workaround from Mathworks is to set the ItemsData property to empty after using copyobj and then set the ItemsData property again to the values needed:
h = uidropdown(uifigure,'Items',{'A' 'B' 'C'}, 'ItemsData', [1:3], 'Value', 3)
% copy into new uifigure -> Value is set to Item instead of ItemData element
hc = copyobj(h,uifigure,'legacy')
% workaround: set ItemsData to empty and back to default
hc.ItemsData = [];
hc.ItemsData = [1, 2, 3]
But this is not possible in my case since the apps with the different settings pages are loaded dynamically. And the class, loading the settings pages on demand, does not know anything about the ItemsData properties needed.
So, I guess that I will simply store the ItemsData values to the UserData property. And then I will use a wrapper function for copyobj, which searches through all children of the destination panel with the copied objects to find uidropdown controls and set the UserData values to ItemsData, if set.
Seems a bit cleaner to me.
Best,
Michae

Sign in to comment.

Categories

Find more on MATLAB in Help Center and File Exchange

Products

Release

R2023a

Community Treasure Hunt

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

Start Hunting!