Changes

XAML Tips

16,410 bytes added, 8 May
/* Device and Platform Responsiveness */
=== Attachable behaviors ===
It's quite often that you need to attach behaviors to certain XAML elements. For example, on a Grid, you want to attach a behavior which executes a command upon a Tapped event, or you want to execute a command when a certain property on a UBIK object changes.
</DataTemplate>
</source>
<br>
==== Event Triggered ====
With an EventTriggerBehavior, you can react on changes/events of UI Elements:
</Grid>
</source>
<br>
==== Data Triggered ====
If you want to react on changes of the underlying data (ViewModel), you can use DataTriggerBehavior instead. The following example, when used in the ''UBIKSplashArea'' template, automatically navigates to the root objects once the login process is finished and the user was successfully authenticated:
</Grid>
</source>
<br>
<br>
       == Content creation ===== Content Child item creation ===
{{Version/WinXSince|3.5.5}}
To directly create an object on a child of the current object, you can define a Button as follows. The method "Item.IsTypeCreationAllowed" used in the expression gets the uid of the type that should be created below a child, if a child does not allow the creation of that type underneath it, the child will be hidden in the selection dialog. To actually create the object, the "CreateChildItemCommand" needs to be passed a KeyValueList with two parameters: The Parent-key is the UID or the ContentViewModel of the child underneath the object should be created, the Type-key is the type of object which should be created--this should match the uid passed to the "Item.IsTypeCreationAllowed" method.
* AutoNavigate (optional, defaults to true): When set to false, the client will not automatically navigate to the created content;
* AutoCommit (optional, defaults to false): When set to true, the change(s) will be saved to the local cache and the database, and then committed to the server.
<br>
=== Creating multiple documents ===
</tabs>-->
<br>  <br>
=== Disable FilloutCriteria ===
</Grid>
</source>
<br>
<br>
     === Hotspotting ===
{{Attention|To use a binding in the KeyValueParameter, it has to be applied like in the example provided here: [[KeyValueList]]}}
The hotspotting command is used for hotspotting as well as for annotating, to configure the button for hotspotting, the commandparameter "Mode" should be set to "HotSpotting", for annotating the "Mode" should be "Annotate". The parameter commit is optional, if set to true, the changes get automatically persisted when leaving the editing mode.
</AppBarToggleButton>
</source>
<br>
<br>
== Remember scroll positions of list views ==
  === Remember scroll positions of list views === ==== Version 3.7 & later {{Version/WinXSince|3.7}} ====
Starting from this version,
* The precision of scroll position remembering is improved(by pixel offsets instead of by items);
* The SelectionBoundListView's <code>RememberScrollPosition</code> property is not set to "false"; (It's "true" by default.)
* The SelectionBoundListView's <code>x:Name</code> property value is unique.
<br>
   ==== Version 3.6 {{Version/WinXSince|3.6}} ====
The UBIK-Client does include a function to remember the position in a list (ListView) when navigating away from it. This function is only available when the list (ListView) has a unique name as a property (x:Name). When browsing back to the previously visited list UBIK scrolls back to the last position. The function does not save scroll positions over different sessions.
Implementing the function to remember the scroll position in a ListView one has to consider that the list elements (Children) could depend on a other UI-element. If the list elements do depend on a other UI-elemente, this element has to be created above the ListView in the XAML.
</DataTemplate>
</source>
<br>
<br>
  === MultiBinding {{Version/WinXSince|3.6}} ===
Very often we want to display some UI elements (e.g. a Grid) depending on whether multiple criteria are met. It's much easier to achieve this by using a MultiBindingBehavior like the following.
<source lang = "xml">
</source>
The behavior makes sure the container Grid is set to Visibile only if the mass editing mode is not turned on (MassEditViewModel is null) and the context object has child document(s) (Documents.Items.Count is greater than 0. You can combine any number of binding results (MultiBindingItem) using the VisLogicAndConverter (the name should be self explanatory).
<br>
<br>
== Other Commands ==
=== InvokeOnItemsCommand {{Version/WinXSince|3.6}} ===
Available on all ListViewModels, this command allows executing a specified command on a collection of list items. It can be used in combination with features such as [[Mass_Edit_(UBIK_WinX)|mass editing]] and [[XAML_Changes_in_UBIK_WinX_3.5#After_3.5|expression based collection filtering]]. Examples for both combinations are provided below.
{{Hint|Parameter "Command" and "SelectedItemsOnly" are specific to the InvokeOnItemsCommand. What other parameters to define or whether to define them at all depends on the type of command to be executed on the items.}}
<br>
==== Invoke on selected items ====
</tab>
</tabs>
<br>
<br>
==== Invoke on filtered results ====
 
{{Attention|To use a binding in the KeyValueParameter, it has to be applied like in the example provided here: [[KeyValueList]]}}
{{Attention|The binding <code>ListViewModel.InvokeOnItemsCommand</code> should be updated to <code>BulkOperation.InvokeOnItemsCommand</code> starting from version 4.3.}}
    <br>
==== Support for old styled commands ====
<source lang = "xml"><example:KeyValueParameter Key="CommandParameter" Value="some string value for example" /></source>.
This single value is then passed as the command parameter instead of the entire KeyValueList.
<br>   <br>
=== SetPropertyValueCommand {{Version/WinXSince|3.6}} ===
{{Hint|There's no way to commit changes without saving them locally first. Therefore, the "AutoSave" parameter will be ignored when "AutoCommit" is set to true.}}
 
Here's an example of the command usage. It tries to set the property called "VALUE" to a double value 50 regardless of its current state and then automatically save and commit the change.
<br />
<source lang = "xml">
<AppBarButton xmlns:example="using:UBIK.WinX.Controls" ...<Button Command="{Binding SetPropertyValueCommand}" Icon Style="Edit{StaticResource UBIKButtonStyle}" Label Content="Set to 50%Property"> <AppBarButtonButton.CommandParameter> <examplecontrols:KeyValueList> <examplecontrols:KeyValueParameter Key="PropertyName" Value="VALUEMP_PROPERTY" /> <examplecontrols:KeyValueParameter Key="PropertyValue"> <example:KeyValueParameter.Value> <x:Double>50</x:Double> </example:KeyValueParameter.="My Value> <" /example:KeyValueParameter> <examplecontrols:KeyValueParameter Key="OnlyForUnvalidated" Value="false" /> <examplecontrols:KeyValueParameter Key="AutoSave" Value="true" /> <examplecontrols:KeyValueParameter Key="AutoCommit" Value="true" /> </examplecontrols:KeyValueList> </AppBarButtonButton.CommandParameter> </AppBarButtonButton>
</source>
{{Hint|It is advised to provide typed values like <nowiki><x:Double>50</x:Double></nowiki>. But for For simple types, you can try writing them in the text format like <nowiki><examplecontrols:KeyValueParameter Key="PropertyValue" Value="50" /></nowiki> and {{UBIK}} will try to find the right type. For advanced property types, it is advised to provide typed values like <nowiki><x:Boolean>true</x:Boolean></nowiki>.}}<br>
==== Set a Binding as PropertyValue ====
There is a known issue in XAML where Behaviors and KeyValueLists do not inherit the binding context of the control they are attached to. Simply put, trying to use a binding directly in the PropertyValue part of the command; '''<nowiki><controls:KeyValueParameter Key="PropertyValue" Value="{Binding BindingPath}" /></nowiki>''', would lead to the client setting the value of MP_PROPERTY to null.
Luckily, there is a simple way to link this Binding to a context. Using the above example as a foundation, adapt the button as shown below:<source lang ="xml"><Button x:Name="SetDynamicPropertyButton" Tag= SaveAndCommitCommand "{Binding}" ... > <Button.CommandParameter> <controls:KeyValueList> ... <controls:KeyValueParameter Key="PropertyValue" Value="{Binding Tag.BindingPath, ElementName=SetDynamicPropertyButton}" />[[File ... </controls:Under_Construction_NoteKeyValueList> </Button.PNG|1000px]]CommandParameter></Button></source>
The above code uses the x:Name of the button to specify the viewmodel from which we wish to begin our binding path.<br>
You do not need to follow this exact syntax, all that is necessary is to provide a connection to the BindingContext of an observable control.
 
 
==== Set Current DateTime ====
The current DateTime stamp can be retrieved from '''AppStatus.LiveDateTime'''.<br>
Since the known issue described in the section above prevents direct binding to this, below are examples for how to implement it.
 
<tabs>
<tab name="UWP">
<source lang = "xml">
xmlns:example="using:UBIK.WinX.Controls"
...
<Button
x:Name="SetCurrentDateTimeButton"
Tag="{Binding}"
Command="{Binding SetPropertyValueCommand}"
Style="{StaticResource UBIKButtonStyle}"
Content="Set Property">
<Button.CommandParameter>
<controls:KeyValueList>
<controls:KeyValueParameter Key="PropertyName" Value="MP_PROPERTY" />
<controls:KeyValueParameter Key="PropertyValue" Value="{Binding Tag.AppStatus.LiveDateTime, ElementName=SetCurrentDateTimeButton}" />
<controls:KeyValueParameter Key="OnlyForUnvalidated" Value="false" />
<controls:KeyValueParameter Key="AutoSave" Value="true" />
<controls:KeyValueParameter Key="AutoCommit" Value="true" />
</controls:KeyValueList>
</Button.CommandParameter>
</Button>
</source>
{{Hint|The DateTime can be set to the desired format by adding a StringFormatConverter to the LiveDateTime binding:<br><nowiki>"{Binding Tag.AppStatus.LiveDateTime, ElementName=SetCurrentDateTimeButton, </nowiki>'''<nowiki>Converter={StaticResource StringFormatConverter}, ConverterParameter={0:yyyy-MM-dd HH:mm}</nowiki>'''<nowiki>}" </nowiki>.}}
</tab>
<tab name="Xamarin">
<Button
x:Name="SetCurrentDateTimeButton"
Command="{Binding SetPropertyValueCommand}"
Text="Set Property">
<Button.CommandParameter>
<classes:KeyValueList>
<classes:KeyValueParameter Key="PropertyName" Value="MP_PROPERTY" />
<classes:KeyValueParameter Key="PropertyValue" Value="{Binding BindingContext.AppStatus.LiveDateTime, Source={x:Reference SetCurrentDateTimeButton}}" />
<classes:KeyValueParameter Key="OnlyForUnvalidated" Value="false" />
<classes:KeyValueParameter Key="AutoSave" Value="true" />
<classes:KeyValueParameter Key="AutoCommit" Value="true" />
</classes:KeyValueList>
</Button.CommandParameter>
</Button>
</tab>
</tabs>
 
<br>
 
 
 
 
 
 
=== SaveAndCommitCommand ===
With the ''SaveAndCommitCommand'' it is possible to save and commit unsaved changes on a ContentViewModel.
* ForceCommit CommandParamerterCommandParameter (optional, defaults to false): Normally when the App is in Online mode, changes are automatically committed when saved. This is not the case when the App is in Manual mode. Setting the ''ForceCommit'' parameter to true makes it possible to commit the changes when saved in Manual mode.* {{Version/WinXSince|4.7}} {{Version/XamarinSince|4.7}} PropertyNameToSave CommandParameter(optional, defaults to null): Delivers the Property Name as String of a specific Property that should be saved. E.g. when called via PropertyViewModel.ResetCommand or PropertyViewModel.DeleteCommand, the ''PropertyNameToSave'' parameter is used to only apply the SaveAndCommitCommand on the related PropertyViewModel called from, and not on other unsaved changes on this ContentViewModel.
<br/>
<tabs>
</tab>
</tabs>
[[File:Under_Construction_End.PNG]]<br>
=== DisplayViewCommand ===
This command can be used to [[Custom_View_(Client)|display cutom views]].
<br>
=== TeachInCommand ===
** True: The change is saved.
<br/> {{hint| Make sure you use the correct binding path for your command depending on your current context view model. E.g., if the context view model is already the ContentViewModel then your binding path should simply be TeachInCommand. You can use the [[Developer_Mode|developer mode]] to find out the current view model in a view.}}
<br>
===UpdateArbitraryObjectCommand {{Version/WinXSince|4.7}}===
</tab>
</tabs>
    <br>
=== Access to an arbitrary object {{Version/WinXSince|4.6}} {{Version/XamarinSince|4.6}} ===
</tab>
</tabs>
<br>
<br>
==== Localizing UI Texts ====
The most efficient practice is to use pre-localized texts from the standard client, however, this is not always possible, especially in custom UIs. The ObjectByUID indexer was therefore initially developed as a technique to allow localization of custom UI label texts.
The concept is to create an infrastructure object that carries metaproperties for localized texts, then bind to this infrastructure object using ObjectByUID, and bind to a specific metaproperty to receive it's localized Description text as follows:
<source lang = "xml">
"{Binding ObjectByUID[paste-your-uid].Properties.VisibleItems[add-your-property-name].Description}"
</source>
From here there are two approaches; the database-leaning one is to add one metaproperty per UI label, and simply bind to the Description of it. However, this shifts maintenance effort to the UBIK Studio after the initial adding of the label in XAML. Another approach would be to use the metaproperty to provide a "tag" that the xaml customizer can then use to differentiate between hardcoded labels.
A third approach would be to create one infrastructure object per label, however, this can lead to many objects being loaded upon startup.
{| class="wikitable"
|-
! Approach !! Implementation !! Maintenance Effort !! Recommendation
|-
| One metaproperty per UI Label || Bind the label text to the metaproperty Description || Database / UBIK Studio || Recommended for UWP, customizings with fewer UI texts, finalized customizings.
|-
| One metaproperty delivering a localization "tag" (such as: "EN" / "DE") || Use something like DataTrigger (Xamarin) to hardcode a different localized text per tag (such as: "eg." / "zb.") || XAML || Recommended for Xamarin, highly customized UIs with many texts, customizings that tend to change often.
|}
<br>
<br>
=== FlipView ===
    ==Showing Images and Icons == In UBIK, there are two types of image;* The thumbnail image assigned to a UBIK object, delivered using the <nowiki>{Binding Icon...}</nowiki> binding, in combination with a ByteToImageConverter. Examples can commonly be found on UBIKChildItem templates.* Custom image shown with a specific purpose, such as a company logo or icon on a button/UI virtualization element.<br> ==== Paths as string resources ====When using custom images in your UI, it is a good idea not to hardcode path data into your Image control but instead to create a string resource in UBIKThemes that holds the image path, and use this string resource in your Image control. The benefit of the indirect connection between image file and usage is that the "file is in use" issue (sometimes experienced when either manual, or auto-deployment of xamls, tries to change image files when UBIK is running) is avoided this way. Sample:<tabs><tab name="UWP">'''UBIKThemes:'''<source lang = "xml"><x:String x:Key="MainLogo">ms-appdata:///local/xaml/Images/MainLogo.png</x:String></source><br>'''Usage:'''<source lang = "xml"><Image x:Name="LogoImage" Height="32" Stretch="Uniform" Source="{Binding Source={StaticResource MainLogo}, Converter={StaticResource PathToImageConverter}}" /></source></tab> <tab name="Xamarin"> '''UBIKThemes:'''<source lang = "xml"><x:String x:Key="Logo_Image">IMG_Logo.png</x:String></source><br>'''Usage:'''<source lang = "xml">xmlns:customimage="clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL"...<customimage:FileImage HeightRequest="140" Aspect="AspectFit" FileName="{StaticResource BorealisLogo_Image}" FolderName="xaml" /></source></tab></tabs><br> === Icons ===UBIK comes equipped with a collection of icons that can be easily used in your customizing. [[Icon_Font|Here is an indepth explanation on usage]]. In the case that you require an icon that is not included in our icon font file, there is the possibility to use SVG path data to render your required icon in the UI.<br> ==== Custom Icons ====Here referring to icons which are not included as standard icons un UBIK. '''Path data''' is a collection of points, which combined together form a vector image. Vector images, compared to raster images like a PNG or JPG, are scalable, because they are always rendered from path data, and not from a bitmap, which has to be stretched or squished to fit your defined size. Described below two approaches. The UWP approach involves adding an SVG icon file to your xaml project and render it using an Image control. The Xamarin approach shows how to use svg data directly using a Path control.<br> <tabs><tab name="UWP"><source lang = "xml"> <Image Width="14" Height="14" Margin="0,0,0,1"> <Image.Source > <SvgImageSource UriSource="{StaticResource PP_Issued}" /> </Image.Source></Image></tab> <tab name="Xamarin">The first step is to generate path data for your icon. The easiest way is to download the [https://apps.microsoft.com/detail/9wzdncrdxf41?hl=en-US&gl=US| Character Map] tool from Microsoft. This can be used to browse all installed icon files for your icon of choice. Once selected, use Tools > Xaml / Xamarin Forms to show various useful aspects of the icon. In this case, the Path Icon option can be used to generate a Path control that can be pasted directly in your xaml as follows:<br><source lang = "xml"><Path Fill="{StaticResource UBIKAccentColor}" Data="F1 M 8.75 1.25 L 18.75 1.25 L 18.75 18.75 L 1.25 18.75 L 1.25 8.75 L 5 8.75 L 5 6.25 L 1.25 6.25 L 1.25 1.25 L 6.25 1.25 L 6.25 5 L 8.75 5 Z M 10 2.5 L 10 5 L 12.5 5 L 12.5 2.5 Z M 2.5 5 L 5 5 L 5 2.5 L 2.5 2.5 Z M 6.25 6.25 L 6.25 8.75 L 8.75 8.75 L 8.75 6.25 Z M 2.5 10 L 2.5 12.5 L 5 12.5 L 5 10 Z M 17.5 17.5 L 17.5 2.5 L 13.75 2.5 L 13.75 6.25 L 10 6.25 L 10 10 L 6.25 10 L 6.25 13.75 L 2.5 13.75 L 2.5 17.5 Z " /> </source><br> Once you have your Path control, you can customize it as [https://learn.microsoft.com/en-us/previous-versions/xamarin/xamarin-forms/user-interface/shapes/path| documented by Microsoft]. Path data generated using the above method will most likely need a Fill attribute, for example <nowiki>Fill="{StaticResource UBIKAccentColor}"</nowiki>. {{Hint|More complicated icons will have longer and more complicated paths.}}</tab></tabs><br><br> == Default Tab Selection ==The tab selection in UBIKContentView defaults to the first tab, which is Children objects. However, for cases where it makes more sense to display Properties or Documents by default, it is possible to change the tab selection using the following classifications:* [[SYSCLS_SHOWDOCUMENTS]]* [[SYSCLS_SHOWPROPERTIES]] {{Attention| Adding the classification to a metaclass is enough for UWP. However, Xamarin currently requires additional customizing to make use of the TabSelector property.}}  ==== Implementation in Xamarin ====One approach is to add a DataTrigger to the SfTabView found in UBIKContentArea that is triggered by the value of the TabSelector property, as shown below;<source lang = "xml"><tabView:SfTabView VisibleHeaderCount="3" > <!-- tabView:SfTabItems ... --> <tabView:SfTabView.Triggers> <DataTrigger TargetType="tabView:SfTabView" Binding="{Binding TabSelector}" Value="PropertiesTab"> <Setter Property="SelectedIndex" Value="1"/> </DataTrigger> <DataTrigger TargetType="tabView:SfTabView" Binding="{Binding TabSelector}" Value="DocumentsTab"> <Setter Property="SelectedIndex" Value="2"/> </DataTrigger> </tabView:SfTabView.Triggers></tabView:SfTabView></source><br><br> == FlipView == === UI virtualization ===
When using the FlipView control in your XAML code, it's better to enable [https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview#ui-virtualization UI virtualization]. The difference in performance gets more obvious as the number of items in the FlipView increases. Here's how to enable it.
</source>
VirtualizingStackPanel.VirtualizationMode offers two possibilities: Standard & Recycling. In case you are interested, here are their [https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.virtualizationmode?view=netframework-4.7.2 differences]. === Auto saving ={{Version/WinXSince|4.6}} ===
Unsaved changes on the document (e.g. Annotations) are gonna be saved and committed automatically when flipping the page in the FlipView.
{{Attention|Changes are lost when leaving the page without flipping the document first.}}
{{Version/WinXSince|4.7}} {{Version/XamarinSince|4.7}} If you want to keep the changes when leaving the page by e.g. navigating away without flipping the document first, there is a boolean property called ''AutoSaveDocumentsOnPageClose'' (default value: false) which enables this behavior. It can be activated by adding the property to (or editing it in) the custom UBIKThemes as follows:
<tabs>
<tab name="UWP">
<source lang = "xml">
<x:String x:Key="AutoSaveDocumentsOnPageClose">true</x:String>
</source>
</tab>
<tab name="Xamarin">
<source lang = "xml">
<x:String x:Key="AutoSaveDocumentsOnPageClose">true</x:String>
</source>
</tab>
</tabs>
VirtualizingStackPanel== Device and Platform Responsiveness =={{UnderConstructionStart}}<br>Although '''OnPlatform''' and '''OnIdiom''' are used in Xamarin, the following wiki article is valid from MAUI 5.VirtualizationMode offers two possibilities: Standard & Recycling0 (add version flag), as the syntax changed. In case you  '''OnPlatform''' can be used to define different property values based on the platform. Valid Platform names are interested, here are their :* iOS* Android* WinUI (for MAUI Windows)* further ones see [https://docslearn.microsoft.com/en-us/dotnet/apimaui/systemplatform-integration/customize-ui-appearance?view=net-maui-9.windows0#customize-ui-appearance-with-a-markup-extension-based-on-the-platform here]<br>'''OnIdom''' can be used to define different property values based on the device type (e.controlsg.virtualizationmodePhone, Tablet, Desktop). When it comes to the proper syntax, we should stick with the approaches mentioned in the [https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/customize-ui-appearance?view=netframeworknet-4maui-9.70 official documentation].Means, we should '''avoid''' using the single-tag syntax like ''<OnPlatform Android="..." iOS="..." />'' or ''<OnIdiom Phone="..." Desktop="..." />''. Instead, we should either use the '''multi-tag syntax''' or the '''inline syntax''' for OnPlatform / OnIdiom. ==== Multi-tag syntax ====Here it is mandatory to add '''x:TypeArguments="TheType"''' with the proper type to OnPlatfrom/OnIdiom. ''Default="..."'' is optional.<tabs><tab name="OnPlatform"><source lang = "XML"><OnPlatform x:TypeArguments="Thickness" Default="20"> <On Platform="iOS, WinUI" Value="0,20,0,0" /> <On Platform="Android" Value="10,20,20,10" /></OnPlatform></source></tab><tab name="OnIdiom"><source lang = "XML"><OnIdiom x:TypeArguments="Thickness" Default="20"> <OnIdiom.Desktop>0,60,0,0</OnIdiom.Desktop></OnIdiom></source></tab></tabs> If OnPlatform Values contain multiple subtags, the following syntax can be used:<source lang = "XML"><ControlTemplate x:Key="ExampleControlTemplate"> <Grid> <OnPlatform x:TypeArguments="View"> <On Platform="Android"> <Button ... Text="Button A" /> ... </On> <On Platform="iOS"> <Button ... Text="Button B" /> ... </On> <On Platform="WinUI"> <Grid> <Button ... Text="Button C" /> <Label Text="Example" /> ... </Grid> </On> </OnPlatform> </Grid></ControlTemplate></source> {{Attention|When using ''GridLength'' as a type in OnPlatform/OnIdiom, it should only be used in combination with the inline syntax.}} ==== Inline syntax ====When using the inline syntax, the type should not be specified. ''Default='' is optional.<tabs><tab name="OnPlatform"><source lang = "XML"><BoxView Color="{OnPlatform Default=Yellow, iOS=Red, Android=Green}" /></source></tab><tab name="OnIdiom"><source lang = "XML"><BoxView Color="{OnIdiom Default=Yellow, Phone=Red, Tablet=Green}" /></source></tab></tabs> If the value contains any special characters like '''"''' or ''',''' or a '''string''' when using the OnIdiom or OnPlatform inline variant, it needs to be wrapped between ' '. But be careful with using apostrophes - when using them around curly brackets {} it can lead to an error.<tabs><tab name="Don't"><source lang = "XML">Margin="{OnIdiom 10,2 differences], Phone=2,0}"</source></tab><tab name="Instead do"><source lang = "XML">Margin="{OnIdiom '10,2', Phone='2,0'}"</source></tab></tabs> === Complex values ===If the OnPlatform/OnIdiom value contains a '''Binding''', '''StaticResource''' or any other complex value in curly brackets, it is recommended to use the '''inline syntax'''. Although there is no official documentation, it seems to work according to our experience. However, the multi-tag syntax doesn't seem to work always for such cases. DynamicResource values seem not to be supported in OnIdiom / OnPlatform. <tabs><tab name="Don't"><source lang = "XML"><OnIdiom x:TypeArguments="..." Default="{Binding ...}"> <OnIdiom.Phone>{Binding ...}</OnIdiom.Phone></OnIdiom></source></tab><tab name="Instead do"><source lang = "XML">Header="{OnIdiom Default={Binding ...}, Phone={Binding ...}}"</source></tab></tabs> {{Attention|Unreliable Support: Behavior may vary when using bindings or complex resources. Although it seems to work with the inline syntax according to our experiences, it is recommended to test these edge cases thoroughly.}} {{UnderConstructionEnd}}
[[Category:Client|XAML Tips]]
364
edits

Help improve this page!