Jump to: navigation, search

Changes


HowTo:Convert Xamarin XAMLs to Maui

3,707 bytes added, 25 August
/* Highly Recommended */
|-
|}
 
{{UnderConstructionStart}}
 
=== DataTrigger permanently blocks manual changes (use DataChangedBehavior instead) ===
 
In .NET MAUI, a DataTrigger that sets a property the user can also change interactively will permanently block that manual change as long as the trigger's condition stays true. This did not happen in Xamarin - it is a MAUI-specific behavior change.
 
'''Symptom:''' A DataTrigger is used to set e.g. the selected tab based on the record's metaclass. The initial selection works correctly, but afterwards the user can never manually switch to a different tab - tapping another tab header highlights it, but the content never switches and SelectedIndex silently reverts.
 
'''Cause (short version):''' MAUI ranks a value applied by an active DataTrigger's Setter higher than a plain manual property write (e.g. a user's tap). Every manual write attempt is silently discarded while the trigger's condition remains true - no error, no exception, it just never takes effect.
 
'''Workaround:''' Do not use DataTrigger for a property that should be data-driven once and then freely user-editable afterwards. Use the existing DataChangedBehavior and SetPropertyAction pattern instead - it performs a single, plain, imperative write the moment the underlying data changes, and never competes with later manual changes.
 
{| class="wikitable" style="width:100%; table-layout:fixed;"
! style="width:50%;" | Xamarin
! style="width:50%;" | MAUI
|-
|
<syntaxhighlight lang="xml">
<controls:UBIKTabView.Triggers>
<DataTrigger TargetType="controls:UBIKTabView"
Binding="{Binding Content.MetaUID, Converter={StaticResource EqualityToBool}, ConverterParameter='b82accb3-7437-429d-aed9-08dfdd5a9e59'}"
Value="True">
<Setter Property="SelectedIndex" Value="1" />
</DataTrigger>
</controls:UBIKTabView.Triggers>
</syntaxhighlight>
||
<syntaxhighlight lang="xml">
xmlns:behaviors="clr-namespace:UBIK.MAUI.Behaviors;assembly=UBIK.MAUI"
...
<controls:UBIKTabView.Behaviors>
<behaviors:DataChangedBehavior
Binding="{Binding Content.MetaUID, Converter={StaticResource EqualityToBool}, ConverterParameter='b82accb3-7437-429d-aed9-08dfdd5a9e59'}"
ComparisonCondition="Equal"
Value="True">
<behaviors:SetPropertyAction
PropertyName="SelectedIndex"
TargetObject="{Binding Source={x:Reference ContentTabs}}"
Value="1" />
</behaviors:DataChangedBehavior>
</controls:UBIKTabView.Behaviors>
</syntaxhighlight>
|-
|}
Result: the tab still auto-selects correctly based on the data, and the user can freely switch tabs afterward.
 
{{Attention|This is not limited to tab selection. The same problem can occur wherever a DataTrigger, Trigger, MultiTrigger sets a property that a user (or code-behind) is also meant to change afterwards, e.g.:}}
* Selection controls: Picker.SelectedIndex/SelectedItem, CollectionView/ListView.SelectedItem, RadioButton.IsChecked, Shell.CurrentItem
* Toggle/input controls: Switch.IsToggled, CheckBox.IsChecked, Entry/Editor.Text
* Expand/collapse state on any control the user can also expand/collapse manually
* Implicit/global Style.Triggers - the riskiest case, since it silently affects every control of that type on a page
* Code-behind writes executed after the trigger has already applied a value (not just touch input)
 
'''Rule of thumb:''' when converting a Xamarin DataTrigger, if the property it sets should remain user-changeable afterwards, convert it into a DataChangedBehavior with SetPropertyAction. Keep DataTrigger/Style.Triggers only for properties that should stay continuously data-driven and don't conflict with user input.
 
{{UnderConstructionEnd}}
[[Category:How-To|Convert Xamarin XAMLs to Maui]]
791
edits