Converters
Written By Brian Faeran
Last updated 6 months ago
Converters
RatioConverter
Maintains a consistent aspect ratio across screen sizes.
Namespace:
xmlns:maui="clr-namespace:Unbroken.LaunchBox.MAUI" ResourceDictionary Example:
<ContentPage.Resources> <ResourceDictionary> <maui:RatioConverter x:Key="RatioConverter" Ratio="1.33333333333" /> </ResourceDictionary> </ContentPage.Resources> Usage Example:
<Grid x:Name="ImageGrid"> <Image Source="{Binding BannerImage}" WidthRequest="{Binding Source={x:Reference ImageGrid}, Path=Height, Converter={StaticResource RatioConverter}}" HeightRequest="{Binding Source={x:Reference ImageGrid}, Path=Height}" /> </Grid> TextSizeConverter
Adjusts font size consistently across screen sizes.
Namespace:
xmlns:maui="clr-namespace:Unbroken.LaunchBox.MAUI" ResourceDictionary Example:
<ContentPage.Resources> <ResourceDictionary> <maui:RatioConverter x:Key="TextTitleConverter" Ratio="2.5" /> <maui:RatioConverter x:Key="TextAttributesConverter" Ratio="1.5" /> </ResourceDictionary> </ContentPage.Resources> Usage Example:
<Label Text="{Binding GameTitle}" FontSize="{Binding Path=PhysicalScreenLength, Converter={StaticResource TextTitleConverter}}" /> <Label Text="{Binding ActiveGame.Game.GenresString}" FontSize="{Binding Path=PhysicalScreenLength, Converter={StaticResource TextAttributesConverter}}" /> DictionaryLookupConverter
Maps specific binding values to other values (e.g., colors by platform name).
Namespace:
xmlns:maui="clr-namespace:Unbroken.LaunchBox.MAUI" ResourceDictionary Example:
<ContentPage.Resources> <ResourceDictionary> <maui:DictionaryLookupConverter x:Key="ColorConverter" FallbackComparisonType="Contains"> <maui:DictionaryLookupConverter.DefaultValue> <Color>#444444</Color> </maui:DictionaryLookupConverter.DefaultValue> <maui:DictionaryLookupConverter.Dictionary> <ResourceDictionary> <Color x:Key="Nintendo 64">#1bb861</Color> <Color x:Key="Nintendo Entertainment System">#ba3141</Color> <Color x:Key="Sega Genesis">#c23b2c</Color> <Color x:Key="Sony PlayStation">#878c92</Color> </ResourceDictionary> </maui:DictionaryLookupConverter.Dictionary> </maui:DictionaryLookupConverter> </ResourceDictionary> </ContentPage.Resources> Usage Example:
<Label Text="{Binding GameTitle}" TextColor="{Binding Path=ActiveGame.Game.Platform, Converter={StaticResource ColorConverter}}" /> FallbackComparisonType Values:
ContainsStartsWithEndsWith
PlayTimeConverter
Parses PlayTime binding to output Hours, Minutes, or Seconds.
Namespace:
xmlns:converters="clr-namespace:Unbroken.LaunchBox.MAUI.Converters" ResourceDictionary Example:
<ContentPage.Resources>
<ResourceDictionary>
<converters:PlayTimeConverter x:Key="PlayTimeConverter" />
</ResourceDictionary>
</ContentPage.Resources> Usage Example:
<Label Text="{Binding ActiveGame.Game.PlayTime, Converter={StaticResource PlayTimeConverter}, ConverterParamter='Hours'}" /> MultiplyByConverter
Multiplies a value by a given parameter.
Namespace:
xmlns:converters="clr-namespace:Unbroken.LaunchBox.MAUI.Converters" ResourceDictionary Example:
<converters:MultiplyBy x:Key="Multiply"/> Usage Example:
<Label FontSize="{Binding FontSize, Converter={StaticResource Multiply}, ConverterParameter=1.25}" /> FileExistsToBoolConverter
Returns True if a file exists at the resolved path, otherwise False.
Namespace:
xmlns:converters="clr-namespace:Unbroken.LaunchBox.MAUI" ResourceDictionary Example:
<ContentPage.Resources>
<ResourceDictionary>
<converters:FileExistsToBoolConverter x:Key="FileExistsToBoolConverter" />
</ResourceDictionary>
</ContentPage.Resources> Usage Examples
1. Format a path using the bound value
Use ConverterParameter as a format string. The bound value will be injected into {0}. This is ideal when your binding is just a name or id and you need to compose the full path.
<!-- True if LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/<FilterValue>.jpg exists --> <Binding Path="FilterValue" Converter="{StaticResource FileExistsToBoolConverter}" ConverterParameter="LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/{0}.jpg" /> Common use with a MultiTrigger to swap sources:
<MultiTrigger TargetType="ffimageloading:CachedImage">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding FilterValue, Converter={StaticResource FileExistsToBoolConverter}, ConverterParameter='LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/{0}.jpg'}" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Source" Value="{Binding FilterValue, StringFormat='{}LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/{0}.jpg'}" />
</MultiTrigger>
<!-- Fallback when the file is missing -->
<MultiTrigger TargetType="ffimageloading:CachedImage">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding FilterValue, Converter={StaticResource FileExistsToBoolConverter}, ConverterParameter='LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/{0}.jpg'}" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Source" Value="LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/Default.jpg" />
</MultiTrigger> 2. Check a bound full path directly
If your binding already contains the full path including extension, omit ConverterParameter.
<!-- True if ClearLogoImage points to an existing file -->
<Binding Path="ClearLogoImage" Converter="{StaticResource FileExistsToBoolConverter}" /> Example with fallback if the platform specific Clear Logo is missing:
<!-- Prefer per filter Clear Logo -->
<MultiTrigger TargetType="ffimageloading:CachedImage">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding FilterValue, Converter={StaticResource FileExistsToBoolConverter}, ConverterParameter='LAUNCHBOX_THEME_FOLDER/Images/Clear Logos/{0}.png'}" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Source" Value="{Binding FilterValue, StringFormat='LAUNCHBOX_THEME_FOLDER/Images/Clear Logos/{0}.png'}" />
<Setter Property="IsVisible" Value="True" />
</MultiTrigger>
<!-- Fallback to a general Clear Logo path if present -->
<MultiTrigger TargetType="ffimageloading:CachedImage">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding FilterValue, Converter={StaticResource FileExistsToBoolConverter}, ConverterParameter='LAUNCHBOX_THEME_FOLDER/Images/Clear Logos/{0}.png'}" Value="False" />
<BindingCondition Binding="{Binding ClearLogoImage, Converter={StaticResource FileExistsToBoolConverter}}" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Source" Value="{Binding ClearLogoImage}" />
<Setter Property="IsVisible" Value="True" />
</MultiTrigger> Parameters
ConverterParameter
Optional format string that produces the file path to test. Use{0}to inject the bound value. You must include the file extension in the format.
Examples:LAUNCHBOX_THEME_FOLDER/Images/Backgrounds/{0}.jpgLAUNCHBOX_THEME_FOLDER/Images/Clear Logos/{0}.png
Return Values
True
The resolved file path exists on disk.False
The file path does not exist, or the binding value is null or empty.
Notes and Tips
The special token LAUNCHBOX_THEME_FOLDER resolves to the active theme folder, which makes theme assets portable across devices.
Always include the file extension in your format string. The converter does not try alternate extensions.
Use in
MultiTriggerblocks to switch between specific images and theme defaults without code behind.Works well with
ffimageloading:CachedImageto avoid expensive IO for images that are not shown.
Controls
Namespace:
xmlns:controls="clr-namespace:Unbroken.LaunchBox.MAUI.Controls" ImageControl
A custom image control that fixes alignment issues in the native <Image> control. Supports VerticalOptions and HorizontalOptions.
Example:
<controls:ImageControl Source="{Binding ClearLogoImage}" Aspect="AspectFit" VerticalOptions="Start" HorizontalOptions="End" />