Maui
Maui copied to clipboard
[Bug] EnumToIntConverter throws an unhandled exception when the picker tries to convert -1
Description
The EnumToIntConverter doesn't mix well sometimes with Pickers in MAUI. Sometimes the Picker seems to try to convert -1, and it of course fails since the enum doesn't have that value.
I have created a gif showing the issue in the app I am developing. If I find some time I'll try to create a repo project, but in short the issue seems related to MAUI reloading a hidden Picker. And the index for some reason is set to -1 at one point.
I have solved this for the mean time in my code by copying the source code from here: https://github.com/CommunityToolkit/Maui/blob/6d3ecd66810077bb102436cf2d264219d3cd7c04/src/CommunityToolkit.Maui/Converters/EnumToIntConverter.shared.cs#L41
And replacing that line with a return null
.
Link to Reproduction Sample
You can take a look at the code source of my project here: https://github.com/StockDrops/OpenStockApp/blob/a7cb138c8f8ef1acb6ba8cb196403b74e550ba0e/OpenStockApp/Views/ModelOptionsView.xaml#L120
I basically have a view with a picker and an enum, and when I load the items into the picker, navigate to another page with the another instance of the view inside, load items again, and then go back to the original view, the MAUI framework seems to set SelectedIndex to -1 and this of course breaks the converter since it throws that it doesn't find -1 in the enum, but I have 0 control over this since it's just the way MAUI seems to work.
Expected Behavior
Shoudn't throw that exception for -1 seems it seems like an important value for MAUI.
Actual Behavior
Throws an exception, causing an unhandled app exception crashing the app.
Basic Information
- Version with issue: RC1
- Last known good version: Preview 14
- IDE: VS 2022 Preview (latest)
- Platform Target Frameworks:
- UWP: This happens on Windows, I haven't tested in on other frameworks.
Workaround
Copy the source code, change the line 120 to return null
.
Reproduction imagery
Interesting! I wonder if the Picker
defaults a value to -1
?
@brminnick yes it does
From here: https://github.com/dotnet/maui/blob/8b56c0b1e703804631f280370fd34789ffa21b16/src/Controls/src/Core/Picker.cs#L32
I can't work out what the fix here would be. Obviously the Picker binding defaults to -1 but what should the converter return in this scenario?
An initial workaround would be to add a -1 value to the enum. It might even be the solution
I'd say it should depend if the Enum defines a value for -1.
If it doesn't returning null seems to work okay in my app.
If it does then that's tricky and I don't know what would be a good enough general approach if there's even one (at least for this use case of EnumToInt converter).
It maybe used not only with Picker. So I suggest to add some kind of DefaultValue:
int? DefaultValue = null;
…
if (DefaultValue.HasValue) return DefaultValue.Value;
else
throw new InvalidEnumArgumentExceptuin(..);
I would extend this question... If the default value is -1
, I believe that the control isn't fully initialized yet, so the MAUI framework shouldn't trigger the Converters, Triggers, etc. I'm curious in which scenarios this happens.
@emorell96 Could you attach a small repro?
I had similar issue with ListView, it happen when you unselect the row.
I would extend this question... If the default value is
-1
, I believe that the control isn't fully initialized yet, so the MAUI framework shouldn't trigger the Converters, Triggers, etc. I'm curious in which scenarios this happens.@emorell96
Could you attach a small repro?
There is a link to a repro in the original post
Perhaps we allow the user to return the default value of their specific enum if the incoming value is outside of the acceptable range of values for that enum. Similar to @VladislavAntonyuk s idea but instead of supplying the DefaultValue
could the user just state that they wish to ReturnDefaultValueWhenOutsideOfEnumBounds
(far better name required).
I don't like the idea of returning null
from the converter. That is because while it may work I suspect that is because the binding is failing to convert null
to the enum
and just not reporting the error and I don't think we should rely on such behaviour.
@bijington Do you suggest to return -1 if ReturnDefaultValueWhenOutsideOfEnumBounds is true?
The thing that worries me is that this happens only when MAUI is a weird state when the Picker has not loaded, I think. It happened when I switched between tabs on my app.
So what worries me is say that you have an initial value for the enum that you are trying to display in the picker, and then this weird state happens, the binding works and gives the default value to the view model value bound to this picker, and then when it loads, instead of showing the value the user actually had, the value is changed to the default value.
Is this possible?
That's a good point! It could be a bug in .NET MAUI that we've uncovered.
@emorell96
Yeah... The behavior that you describes, to me, looks like the SelectedItem
should be a CommandMapper
and it's implemented as a Mapper
... We can check with the team about it
@VladislavAntonyuk no I was actually wondering whether we could return the effective value of default
for the users enum definition, I am not sure if that is feasible/possible though.
I also then wondered if Binding.DoNothing
is something we could return to do as the name suggests. I have asked this in the community Discord to see if anyone has any knowledge of it's correct use https://discord.com/channels/732297728826277939/732297916680765551/968234717541437471
I believe it can be closed with 1.3.0 release. You can use SetShouldSuppressExceptionsInConverters