== Information ==
=== Frame to Border ===
'''Use [https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/border?view=net-maui-9.0 Border] instead of Frame.'''
Frame is deprecated in MAUI. Attributes;
* Stroke (previously BorderColor)
* Use StrokeShape (previously CornerRadius) to define the corners. Eg. <nowiki>StrokeShape="RoundRectangle 8,8,8,8"</nowiki> where the corner curve can be written as 1 value (all the same), 2 values (horizontal and vertical), or 4 values (each corner defined seperately). The default StrokeShape is 'Rectangle', which effectively equals a CornerRadius of 0.
* StrokeThickness can be used to define the thickness of the border.
* Other properties documented in the link above can be used to define the look of the border.
{| class="wikitable"
! Xamarin
! MAUI
|-
| <Frame ... />
| <Border ... />
|}
[[Category:How-To|Convert Xamarin XAMLs to Maui]]
[[Category:Mobile|Convert Xamarin XAMLs to Maui]]
[[Category:XAML|Convert Xamarin XAMLs to Maui]]
=== LayoutOptions with "...AndExpand" ===
'''Replace "...AndExpand" with Grid layout.'''
Horizontal/VerticalOptions ending in "...AndExpand" are deprecated. Use Grid with `ColumnDefinition Width="*"` for expansion.
=== GlyphLabel and Styles ===
'''Use Label with new styles.'''
Custom controls like `GlyphLabel` are no longer needed. Use `Label` with styles like `UBIKSymbolText`.
{| class="wikitable"
! Xamarin
! MAUI
|-
| controls:GlyphLabel
| Label with UBIKSymbolText style
|}
=== SfTabView Virtualization ===
'''Enable virtualization.'''
Add `EnableVirtualization="True"` to all SfTabView instances or styles.
=== Swipe Menu Icons on Android ===
'''Refactor swipe templates and label styles.'''
Icons in swipe menus were truncated on Android. Fixed via refactoring.
=== Color Style Changes ===
'''Dark theme adjustments.'''
Changes to color styles may affect appearance. Review usage of `UBIKDarkThemeColor`, `UBIKDarkTextColor`, etc.
=== Strikethrough Converter ===
'''Use `TextDecorations="Strikethrough"` instead of converter.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| Text="{Binding ..., Converter={StaticResource StrikethroughConverter}}"
| Text="{Binding ...}" TextDecorations="Strikethrough"
|}
=== Button Disabled Trigger ===
'''Add trigger for disabled buttons.'''
Maui buttons don’t visually change when disabled. Add trigger to style.
=== TapGestureRecognizer Replacement ===
'''Use TappedBehavior instead.'''
TapGestureRecognizer now intercepts taps. Use `TappedBehavior` to avoid conflicts.
{| class="wikitable"
! Xamarin
! MAUI
|-
| <... .GestureRecognizers><TapGestureRecognizer Command="{Binding ...}" /></... .GestureRecognizers>
| <... .Behaviors><behaviors:TappedBehavior><behaviors:InvokeCommandAction Command="{Binding ...}" /></behaviors:TappedBehavior></... .Behaviors>
|}
=== TapGestureRecognizer and Swipe Conflict ===
'''Remove TapGestureRecognizer from root Grid.'''
TapGestureRecognizer blocks swipe behavior. Remove it and adapt parent list to trigger navigation. An example of such behaviors can be seen in UBIKChildArea.
=== Navigation in UBIKChildItem ===
'''Use EventHandlerBehavior for navigation.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| [none]
| <controls:SfListViewExt.Behaviors><behaviors:EventHandlerBehavior EventName="ItemTapped"><behaviors:InvokeCommandAction Command="{Binding AppStatus.RootList.Items[0].NavigateToChildrenCommand}" /></behaviors:EventHandlerBehavior></controls:SfListViewExt.Behaviors>
|}
== Recommended ==
=== Extract DataTemplates from UBIKThemes ===
'''Create separate .xamlx files for the following DataTemplates.'''
It's not so easy about the namespaces:
* In our default templates, it's enough to add the following ones to every new separate .xamlx files at the beginning;
* xmlns:ctrls="clr-namespace:UBIK.MAUI.Controls;assembly=UBIK.MAUI";
* xmlns:platform="clr-namespace:UBIK.MAUI.Platform.Renderers;assembly=UBIK.MAUI";
* xmlns:resources="clr-namespace:UBIK.MAUI.Resources;assembly=UBIK.MAUI";
* xmlns:services="clr-namespace:UBIK.MAUI.Services;assembly=UBIK.MAUI";
* xmlns:uiservices="clr-namespace:UBIK.UI.Services;assembly=UBIK.UI".
* But we don't know if other namespaces might be used in the custom templates. So it might be necessary to really analyze the namespaces used and find/copy them from the UBIKThemes file.
{| class="wikitable"
! !! Templates !!
|-
| UBIKMainItem || UBIKChildItem || UBIKTaskItem
|-
| UBIKTaskProperty || UBIKTaskPropertyString || UBIKTaskPropertyDouble
|-
| UBIKTaskPropertyInt || UBIKTaskPropertyNumeric || UBIKTaskPropertyDateTime
|-
| UBIKTaskPropertyGeoData || UBIKTaskPropertyBool || UBIKTaskPropertyPopup
|-
| UBIKTaskPropertyList || UBIKTaskPropertyGuid || UBIKPropertyItem
|-
| UBIKPropertyTextLengthHint || UBIKPropertyDirectEditButtons || UBIKTaskPropertyEditButtons
|-
| UBIKPropertyDirectItemString || UBIKPropertyDirectItemDouble || UBIKPropertyDirectItemInt
|-
| UBIKPropertyDirectItemMinMax || UBIKPropertyDirectItemNumeric || UBIKPropertyDirectItemDateTime
|-
| UBIKPropertyDirectItemGeoData || UBIKPropertyDirectItemBool || UBIKPropertyDirectItemPopup
|-
| UBIKPropertyDirectItemList || UBIKPropertyDirectItemGuid || UBIKDocumentItem
|-
| UBIKSearchResultItem || UBIKDefaultHotSpot || UBIKAngularLinkHotSpot
|-
| UBIKRoundLinkHotSpot || UBIKInputHotSpot || UBIKSignatureHotSpot
|-
| UBIKObjectHotSpot || UBIKMediaHotSpot ||
|}
=== VideoPlayer Adjustments ===
'''This property is repsonsible for the video player regarding how or if it should get scaled up depending on the value of the
Aspect property'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">VideoPlayer...</syntaxhighlight>
| <syntaxhighlight lang="xml">VideoPlayer Aspect="AspectFit"</syntaxhighlight>
|}
'''The UriToVideoSourceConverter is no longer needed because the conversion of the
VideoSource gets done by the MediaElement itself. It is marked as obsolete and should therefore no longer be used.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml"><controls:VideoPlayer... Source="{Binding DocumentViewModel.LocalURI, Converter={StaticResource UriToVideoSource}}"/></syntaxhighlight>
| <syntaxhighlight lang="xml"><controls:VideoPlayer... Source="{Binding DocumentViewModel.LocalURI}"/></syntaxhighlight>
|}
'''The StopTimer property is obsolete and no longer needed because the MediaElement behind does the Stop of the VideoPlayer
by itself.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml"><controls:VideoPlayer... StopTimer="{Binding Unloaded}" /></syntaxhighlight>
| <syntaxhighlight lang="xml"><controls:VideoPlayer... /></syntaxhighlight>
|}
=== SearchBar Style Fix on iOS ===
'''On iOS, defining a transparent background for the SearchBar control results in a black text on black background appearance.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">[issue on iOS only] UBIKThemes: SearchBar style: <Setter Property="BackgroundColor" Value="Transparent" /></syntaxhighlight>
| <syntaxhighlight lang="xml">Delete this setter</syntaxhighlight>
|}
=== Remove TapGestureRecognizer from Main Item ===
'''Swiping on the Main items was broken by Maui (Documented in Information). The workaround is to remove the TapGestureRecognizer from UBIKMainItem, and add ListView-based navigation similar to that found in UBIKChildArea (with an extended binding path for technical reasons).'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">(In UBIKMainItem)
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding NavigateToChildrenCommand}" />
</Grid.GestureRecognizers></syntaxhighlight>
| <syntaxhighlight lang="xml">[nothing]</syntaxhighlight>
|}
=== Add Navigation Behavior in Child Area ===
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">(In UBIKChildArea)
[nothing]</syntaxhighlight>
| <syntaxhighlight lang="xml"><controls:SfListViewExt.Behaviors>
<behaviors:EventHandlerBehavior EventName="ItemTapped">
<behaviors:InvokeCommandAction Command="{Binding AppStatus.RootList.Items[0].NavigateToChildrenCommand}" />
</behaviors:EventHandlerBehavior>
</controls:SfListViewExt.Behaviors></syntaxhighlight>
|}
== Highly Recommended ==
=== New name for Root item templates ===
The template formerly called UBIKMainItem has been renamed to UBIKRootItem for consistency.
The renaming is not mandatory in customizing, however, ensure that the ItemTemplate requested in UBIKRootArea matches the file intended to be used for visualizing root items.
=== CircularImage to AvatarView ===
'''Use AvatarView instead of CircularImage.'''
CircularImage and its wrapping Frame are no longer needed. Use AvatarView from the MAUI Community Toolkit. Add the namespace:
<syntaxhighlight lang="xml">
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
</syntaxhighlight>
{| class="wikitable"
! Xamarin
! MAUI
|-
| <Frame><CircularImage Source="..." /></Frame>
| <toolkit:AvatarView ImageSource="..." BorderWidth="..." BackgroundColor="..." />
|}
=== GlyphSize to FontSize and Alignment ===
'''Use FontSize and alignment properties instead of GlyphSize.'''
The GlyphSize property is obsolete. Use FontSize and add alignment properties for better layout.
{| class="wikitable"
! Xamarin
! MAUI
|-
| <Setter Property="GlyphSize" Value="13.0" />
| <Setter Property="FontSize" Value="16" /><br/><Setter Property="VerticalOptions" Value="Center" /><br/><Setter Property="HorizontalOptions" Value="Center" /><br/><Setter Property="VerticalTextAlignment" Value="Center" /><br/><Setter Property="HorizontalTextAlignment" Value="Center" />
|}
=== StaticResource to DynamicResource ===
'''Use DynamicResource and BaseResourceKey.'''
For dynamic theming, use DynamicResource instead of StaticResource. When inheriting styles, use BaseResourceKey.
{| class="wikitable"
! Xamarin
! MAUI
|-
| BasedOn="{StaticResource SomeStyle}"
| BaseResourceKey="SomeStyle"
|-
| Style="{StaticResource SomeStyle}"
| Style="{DynamicResource SomeStyle}"
|}
=== UBIKPropertyDirectEditListPopup and Guid link direct editing ===
We have changed the way the content item template is defined and used in UBIKPropertyDirectEditListPopup, which is used in the direct editing of Guid link properties. This change aims to simplify the template and is also due to the fact that the old approach has a poor performance in the new MAUI app.
{| class="wikitable"
! Xamarin
! MAUI
|-
|
<syntaxhighlight lang="xml">
<DataTemplate x:Key="PopupFilterQueryItemTemplate">
...
</DataTemplate>
</syntaxhighlight>
||
The DataTemplate "PopupFilterQueryItemTemplate" is no longer needed and should be removed.
|-
|
<syntaxhighlight lang="xml">
<controls:SfListViewExt
x:Name="FilterQueryResultList"
...
ItemTemplate="{StaticResource PopupFilterQueryItemTemplate}" />
</syntaxhighlight>
||
<syntaxhighlight lang="xml">
<controls:SfListViewExt
x:Name="FilterQueryResultList"
...
ItemTemplate="{Binding [UBIKChildItem], Source={x:Static services:TemplateService.Instance}}">
<controls:SfListViewExt.Behaviors>
<behaviors:EventHandlerBehavior EventName="ItemTapped">
<behaviors:InvokeCommandAction Command="{Binding SetPropertyValueCommand}" Converter="{StaticResource ItemTappedEventArgsToViewModelConverter}" />
<behaviors:InvokeCommandAction Command="{Binding ConfirmEditCommand}" />
</behaviors:EventHandlerBehavior>
</controls:SfListViewExt.Behaviors>
</controls:SfListViewExt>
</syntaxhighlight>
|}
In comparison, the old solution defines a "PopupFilterQueryItemTemplate" DataTemplate which simply wraps the needed selection related behaviors to the existing "UBIKChildItem" template. The new solution reuses the "UBIKChildItem" template directly and add the same but adapted behaviors to the list view instead.
=== UBIKTabView ===
UBIKTabView has been adapted so that it now supports lazy loading when used in combination with a UBIKContentView or ContentControl. This results in a performance boost because the contents of non-selected tabs are no longer rendered in the UI automatically unless the tab is explicitly selected by the user. Therefore, the LazyLoading property should be set to true for tabs that are not the “default” tabs—i.e., tabs that are not initially selected when a page is opened (Property or Document tabs).
For more customizing options refer to the [https://help.syncfusion.com/maui-toolkit/tabview/tab-item-customization Syncfusion Documentation].
Add the following namespace to use the UBIKTabView:
<syntaxhighlight lang="xml">
xmlns:controls="clr-namespace:UBIK.MAUI.Controls;assembly=UBIK.MAUI"
</syntaxhighlight>
'''From a performance perspective, our UBIKTabView should be used instead of the SfTabView going forward, as it supports lazy loading.'''{{Version/MobileSince|5.1}}
{| class="wikitable" style="width:100%; table-layout:fixed;"
! style="width:60%;" | Xamarin
! style="width:40%;" | MAUI
|-
|
<syntaxhighlight lang="xml">
<tabView:SfTabView>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView x:Name="ChildContainer" Converter="{StaticResource ChildAreaTemplateConverter}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<ContentView Content="{Binding [UBIKPropertyArea], Source={x:Static services:TemplateService.Instance}}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<ContentView Content="{Binding [UBIKDocumentArea], Source={x:Static services:TemplateService.Instance}}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
</tabView:SfTabView>
</syntaxhighlight>
||
<syntaxhighlight lang="xml">
<controls:UBIKTabView
x:Name="ContentTabs"
Style="{DynamicResource TabViewBaseStyle}"
TabHeaderPadding="0">
<controls:UBIKTabView.Items>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView x:Name="ChildContainer"
Converter="{StaticResource ChildAreaTemplateConverter}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView
Converter="{StaticResource TemplateConverter}"
ConverterParameter="UBIKPropertyArea"
LazyLoading="True" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView
Converter="{StaticResource TemplateConverter}"
ConverterParameter="UBIKDocumentArea"
LazyLoading="True" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
</controls:UBIKTabView.Items>
</controls:UBIKTabView>
</syntaxhighlight>
|-
|}
[[Category:How-To|Convert Xamarin XAMLs to Maui]]
[[Category:Mobile|Convert Xamarin XAMLs to Maui]]
[[Category:XAML|Convert Xamarin XAMLs to Maui]]
== Mandatory ==
|}
[[Category:How-To|Convert Xamarin XAMLs to Maui]][[Category:Mobile|Convert Xamarin XAMLs to Maui]][[Category:XAML|Convert Xamarin XAMLs to Maui]]
== SfTabView ==
</Grid>
</syntaxhighlight>
|}
== Highly Recommended ==
=== New name for Root item templates ===
The template formerly called UBIKMainItem has been renamed to UBIKRootItem for consistency.
The renaming is not mandatory in customizing, however, ensure that the ItemTemplate requested in UBIKRootArea matches the file intended to be used for visualizing root items.
=== CircularImage to AvatarView ===
'''Use AvatarView instead of CircularImage.'''
CircularImage and its wrapping Frame are no longer needed. Use AvatarView from the MAUI Community Toolkit. Add the namespace:
<syntaxhighlight lang="xml">
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
</syntaxhighlight>
{| class="wikitable"
! Xamarin
! MAUI
|-
| <Frame><CircularImage Source="..." /></Frame>
| <toolkit:AvatarView ImageSource="..." BorderWidth="..." BackgroundColor="..." />
|}
=== GlyphSize to FontSize and Alignment ===
'''Use FontSize and alignment properties instead of GlyphSize.'''
The GlyphSize property is obsolete. Use FontSize and add alignment properties for better layout.
{| class="wikitable"
! Xamarin
! MAUI
|-
| <Setter Property="GlyphSize" Value="13.0" />
| <Setter Property="FontSize" Value="16" /><br/><Setter Property="VerticalOptions" Value="Center" /><br/><Setter Property="HorizontalOptions" Value="Center" /><br/><Setter Property="VerticalTextAlignment" Value="Center" /><br/><Setter Property="HorizontalTextAlignment" Value="Center" />
|}
=== StaticResource to DynamicResource ===
'''Use DynamicResource and BaseResourceKey.'''
For dynamic theming, use DynamicResource instead of StaticResource. When inheriting styles, use BaseResourceKey.
{| class="wikitable"
! Xamarin
! MAUI
|-
| BasedOn="{StaticResource SomeStyle}"
| BaseResourceKey="SomeStyle"
|-
| Style="{StaticResource SomeStyle}"
| Style="{DynamicResource SomeStyle}"
|}
=== UBIKPropertyDirectEditListPopup and Guid link direct editing ===
We have changed the way the content item template is defined and used in UBIKPropertyDirectEditListPopup, which is used in the direct editing of Guid link properties. This change aims to simplify the template and is also due to the fact that the old approach has a poor performance in the new MAUI app.
{| class="wikitable"
! Xamarin
! MAUI
|-
|
<syntaxhighlight lang="xml">
<DataTemplate x:Key="PopupFilterQueryItemTemplate">
...
</DataTemplate>
</syntaxhighlight>
||
The DataTemplate "PopupFilterQueryItemTemplate" is no longer needed and should be removed.
|-
|
<syntaxhighlight lang="xml">
<controls:SfListViewExt
x:Name="FilterQueryResultList"
...
ItemTemplate="{StaticResource PopupFilterQueryItemTemplate}" />
</syntaxhighlight>
||
<syntaxhighlight lang="xml">
<controls:SfListViewExt
x:Name="FilterQueryResultList"
...
ItemTemplate="{Binding [UBIKChildItem], Source={x:Static services:TemplateService.Instance}}">
<controls:SfListViewExt.Behaviors>
<behaviors:EventHandlerBehavior EventName="ItemTapped">
<behaviors:InvokeCommandAction Command="{Binding SetPropertyValueCommand}" Converter="{StaticResource ItemTappedEventArgsToViewModelConverter}" />
<behaviors:InvokeCommandAction Command="{Binding ConfirmEditCommand}" />
</behaviors:EventHandlerBehavior>
</controls:SfListViewExt.Behaviors>
</controls:SfListViewExt>
</syntaxhighlight>
|}
In comparison, the old solution defines a "PopupFilterQueryItemTemplate" DataTemplate which simply wraps the needed selection related behaviors to the existing "UBIKChildItem" template. The new solution reuses the "UBIKChildItem" template directly and add the same but adapted behaviors to the list view instead.
=== UBIKTabView ===
UBIKTabView has been adapted so that it now supports lazy loading when used in combination with a UBIKContentView or ContentControl. This results in a performance boost because the contents of non-selected tabs are no longer rendered in the UI automatically unless the tab is explicitly selected by the user. Therefore, the LazyLoading property should be set to true for tabs that are not the “default” tabs—i.e., tabs that are not initially selected when a page is opened (Property or Document tabs).
For more customizing options refer to the [https://help.syncfusion.com/maui-toolkit/tabview/tab-item-customization Syncfusion Documentation].
Add the following namespace to use the UBIKTabView:
<syntaxhighlight lang="xml">
xmlns:controls="clr-namespace:UBIK.MAUI.Controls;assembly=UBIK.MAUI"
</syntaxhighlight>
'''From a performance perspective, our UBIKTabView should be used instead of the SfTabView going forward, as it supports lazy loading.'''{{Version/MobileSince|5.1}}
{| class="wikitable" style="width:100%; table-layout:fixed;"
! style="width:60%;" | Xamarin
! style="width:40%;" | MAUI
|-
|
<syntaxhighlight lang="xml">
<tabView:SfTabView>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView x:Name="ChildContainer" Converter="{StaticResource ChildAreaTemplateConverter}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<ContentView Content="{Binding [UBIKPropertyArea], Source={x:Static services:TemplateService.Instance}}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<ContentView Content="{Binding [UBIKDocumentArea], Source={x:Static services:TemplateService.Instance}}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
</tabView:SfTabView>
</syntaxhighlight>
||
<syntaxhighlight lang="xml">
<controls:UBIKTabView
x:Name="ContentTabs"
Style="{DynamicResource TabViewBaseStyle}"
TabHeaderPadding="0">
<controls:UBIKTabView.Items>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView x:Name="ChildContainer"
Converter="{StaticResource ChildAreaTemplateConverter}" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView
Converter="{StaticResource TemplateConverter}"
ConverterParameter="UBIKPropertyArea"
LazyLoading="True" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
<tabView:SfTabItem>
<tabView:SfTabItem.Content>
<controls:UBIKContentView
Converter="{StaticResource TemplateConverter}"
ConverterParameter="UBIKDocumentArea"
LazyLoading="True" />
</tabView:SfTabItem.Content>
</tabView:SfTabItem>
</controls:UBIKTabView.Items>
</controls:UBIKTabView>
</syntaxhighlight>
|-
|}
== Recommended ==
=== Extract DataTemplates from UBIKThemes ===
'''Create separate .xamlx files for the following DataTemplates.'''
It's not so easy about the namespaces:
* In our default templates, it's enough to add the following ones to every new separate .xamlx files at the beginning;
* xmlns:ctrls="clr-namespace:UBIK.MAUI.Controls;assembly=UBIK.MAUI";
* xmlns:platform="clr-namespace:UBIK.MAUI.Platform.Renderers;assembly=UBIK.MAUI";
* xmlns:resources="clr-namespace:UBIK.MAUI.Resources;assembly=UBIK.MAUI";
* xmlns:services="clr-namespace:UBIK.MAUI.Services;assembly=UBIK.MAUI";
* xmlns:uiservices="clr-namespace:UBIK.UI.Services;assembly=UBIK.UI".
* But we don't know if other namespaces might be used in the custom templates. So it might be necessary to really analyze the namespaces used and find/copy them from the UBIKThemes file.
{| class="wikitable"
! !! Templates !!
|-
| UBIKMainItem || UBIKChildItem || UBIKTaskItem
|-
| UBIKTaskProperty || UBIKTaskPropertyString || UBIKTaskPropertyDouble
|-
| UBIKTaskPropertyInt || UBIKTaskPropertyNumeric || UBIKTaskPropertyDateTime
|-
| UBIKTaskPropertyGeoData || UBIKTaskPropertyBool || UBIKTaskPropertyPopup
|-
| UBIKTaskPropertyList || UBIKTaskPropertyGuid || UBIKPropertyItem
|-
| UBIKPropertyTextLengthHint || UBIKPropertyDirectEditButtons || UBIKTaskPropertyEditButtons
|-
| UBIKPropertyDirectItemString || UBIKPropertyDirectItemDouble || UBIKPropertyDirectItemInt
|-
| UBIKPropertyDirectItemMinMax || UBIKPropertyDirectItemNumeric || UBIKPropertyDirectItemDateTime
|-
| UBIKPropertyDirectItemGeoData || UBIKPropertyDirectItemBool || UBIKPropertyDirectItemPopup
|-
| UBIKPropertyDirectItemList || UBIKPropertyDirectItemGuid || UBIKDocumentItem
|-
| UBIKSearchResultItem || UBIKDefaultHotSpot || UBIKAngularLinkHotSpot
|-
| UBIKRoundLinkHotSpot || UBIKInputHotSpot || UBIKSignatureHotSpot
|-
| UBIKObjectHotSpot || UBIKMediaHotSpot ||
|}
=== VideoPlayer Adjustments ===
'''This property is repsonsible for the video player regarding how or if it should get scaled up depending on the value of the
Aspect property'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">VideoPlayer...</syntaxhighlight>
| <syntaxhighlight lang="xml">VideoPlayer Aspect="AspectFit"</syntaxhighlight>
|}
'''The UriToVideoSourceConverter is no longer needed because the conversion of the
VideoSource gets done by the MediaElement itself. It is marked as obsolete and should therefore no longer be used.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml"><controls:VideoPlayer... Source="{Binding DocumentViewModel.LocalURI, Converter={StaticResource UriToVideoSource}}"/></syntaxhighlight>
| <syntaxhighlight lang="xml"><controls:VideoPlayer... Source="{Binding DocumentViewModel.LocalURI}"/></syntaxhighlight>
|}
'''The StopTimer property is obsolete and no longer needed because the MediaElement behind does the Stop of the VideoPlayer
by itself.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml"><controls:VideoPlayer... StopTimer="{Binding Unloaded}" /></syntaxhighlight>
| <syntaxhighlight lang="xml"><controls:VideoPlayer... /></syntaxhighlight>
|}
=== SearchBar Style Fix on iOS ===
'''On iOS, defining a transparent background for the SearchBar control results in a black text on black background appearance.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">[issue on iOS only] UBIKThemes: SearchBar style: <Setter Property="BackgroundColor" Value="Transparent" /></syntaxhighlight>
| <syntaxhighlight lang="xml">Delete this setter</syntaxhighlight>
|}
=== Remove TapGestureRecognizer from Main Item ===
'''Swiping on the Main items was broken by Maui (Documented in Information). The workaround is to remove the TapGestureRecognizer from UBIKMainItem, and add ListView-based navigation similar to that found in UBIKChildArea (with an extended binding path for technical reasons).'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">(In UBIKMainItem)
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding NavigateToChildrenCommand}" />
</Grid.GestureRecognizers></syntaxhighlight>
| <syntaxhighlight lang="xml">[nothing]</syntaxhighlight>
|}
=== Add Navigation Behavior in Child Area ===
{| class="wikitable"
! Xamarin
! MAUI
|-
| <syntaxhighlight lang="xml">(In UBIKChildArea)
[nothing]</syntaxhighlight>
| <syntaxhighlight lang="xml"><controls:SfListViewExt.Behaviors>
<behaviors:EventHandlerBehavior EventName="ItemTapped">
<behaviors:InvokeCommandAction Command="{Binding AppStatus.RootList.Items[0].NavigateToChildrenCommand}" />
</behaviors:EventHandlerBehavior>
</controls:SfListViewExt.Behaviors></syntaxhighlight>
|}
== Information Only ==
=== Frame to Border ===
'''Use [https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/border?view=net-maui-9.0 Border] instead of Frame.'''
Frame is deprecated in MAUI. Attributes;
* Stroke (previously BorderColor)
* Use StrokeShape (previously CornerRadius) to define the corners. Eg. <nowiki>StrokeShape="RoundRectangle 8,8,8,8"</nowiki> where the corner curve can be written as 1 value (all the same), 2 values (horizontal and vertical), or 4 values (each corner defined seperately). The default StrokeShape is 'Rectangle', which effectively equals a CornerRadius of 0.
* StrokeThickness can be used to define the thickness of the border.
* Other properties documented in the link above can be used to define the look of the border.
{| class="wikitable"
! Xamarin
! MAUI
|-
| <Frame ... />
| <Border ... />
|}
=== LayoutOptions with "...AndExpand" ===
'''Replace "...AndExpand" with Grid layout.'''
Horizontal/VerticalOptions ending in "...AndExpand" are deprecated. Use Grid with `ColumnDefinition Width="*"` for expansion.
=== GlyphLabel and Styles ===
'''Use Label with new styles.'''
Custom controls like `GlyphLabel` are no longer needed. Use `Label` with styles like `UBIKSymbolText`.
{| class="wikitable"
! Xamarin
! MAUI
|-
| controls:GlyphLabel
| Label with UBIKSymbolText style
|}
=== SfTabView Virtualization ===
'''Enable virtualization.'''
Add `EnableVirtualization="True"` to all SfTabView instances or styles.
=== Swipe Menu Icons on Android ===
'''Refactor swipe templates and label styles.'''
Icons in swipe menus were truncated on Android. Fixed via refactoring.
=== Color Style Changes ===
'''Dark theme adjustments.'''
Changes to color styles may affect appearance. Review usage of `UBIKDarkThemeColor`, `UBIKDarkTextColor`, etc.
=== Strikethrough Converter ===
'''Use `TextDecorations="Strikethrough"` instead of converter.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| Text="{Binding ..., Converter={StaticResource StrikethroughConverter}}"
| Text="{Binding ...}" TextDecorations="Strikethrough"
|}
=== Button Disabled Trigger ===
'''Add trigger for disabled buttons.'''
Maui buttons don’t visually change when disabled. Add trigger to style.
=== TapGestureRecognizer Replacement ===
'''Use TappedBehavior instead.'''
TapGestureRecognizer now intercepts taps. Use `TappedBehavior` to avoid conflicts.
{| class="wikitable"
! Xamarin
! MAUI
|-
| <... .GestureRecognizers><TapGestureRecognizer Command="{Binding ...}" /></... .GestureRecognizers>
| <... .Behaviors><behaviors:TappedBehavior><behaviors:InvokeCommandAction Command="{Binding ...}" /></behaviors:TappedBehavior></... .Behaviors>
|}
=== TapGestureRecognizer and Swipe Conflict ===
'''Remove TapGestureRecognizer from root Grid.'''
TapGestureRecognizer blocks swipe behavior. Remove it and adapt parent list to trigger navigation. An example of such behaviors can be seen in UBIKChildArea.
=== Navigation in UBIKChildItem ===
'''Use EventHandlerBehavior for navigation.'''
{| class="wikitable"
! Xamarin
! MAUI
|-
| [none]
| <controls:SfListViewExt.Behaviors><behaviors:EventHandlerBehavior EventName="ItemTapped"><behaviors:InvokeCommandAction Command="{Binding AppStatus.RootList.Items[0].NavigateToChildrenCommand}" /></behaviors:EventHandlerBehavior></controls:SfListViewExt.Behaviors>
|}