Referencing static objects created in XAML - xaml

I am trying to create some design-time data using XAML. I am afraid I can't find guidance on the Web on how to create an array by referencing other XAML-created objects. Something similar to this...
<MyClass x:Key="Obj1" Prop1="..." Prop2="..." />
<MyClass x:Key="Obj2" Prop1="..." Prop2="..." />
<x:Array Type={x:Type my:MyClass} x:Key="MyObjects">
<StaticResource Key="Obj1" />
<StaticResource Key="Obj2" />
</x:Array>
Unfortunately, the above doesn't work. Is there something that would work?
I reproduced the error by creating an empty Xamarin Forms app with the latest VS Studio for the Mac. I added this to ContentPage.Resources...
<ContentPage.Resources>
<ResourceDictionary>
<n:String x:Key="myString">Hello World</n:String>
<x:Array x:Key="myArray" Type="{x:Type n:String}">
<StaticResource Key="myString" />
</x:Array>
</ResourceDictionary>
</ContentPage.Resources>
I get the following error at the start of the application:
Xamarin.Forms.Xaml.XamlParseException
... StaticResource not found for key myString
I am building a Xamarin.Forms application using the latest version of Visual Studio for Mac.
Also, I am aware I can create the objects as direct children of the array. I am trying to create them separately so that I can include them in different collections.
Update (after the suggestion from #junior-jiang-msft)
I tried Junior Jiang's proposal but I get the following build error...
/Users/savasp/Projects/test/test/MainPage.xaml: Error: The given key 'Xamarin.Forms.Xaml.XmlName' was not present in the dictionary.
Here's the sample XAML Form in a new, vanilla Xamarin.Forms project...
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="test.MainPage">
<ContentPage.Resources>
<x:String x:Key="m1">hello</x:String>
<x:String x:Key="m2">world</x:String>
<x:Array x:Key="array" Type="{x:Type x:String}">
<Setter Value="{StaticResource m1}" />
<Setter Value="{StaticResource m2}" />
</x:Array>
</ContentPage.Resources>
<StackLayout>
<!-- Place new controls here -->
<ListView ItemsSource="{StaticResource array}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>

Maybe you misunderstand something about ResourceDictionary.For the value and assignment of StaticResource.
<ContentPage...>
<ContentPage.Resources>
<x:String x:Key="myStringOne">Hello String One</x:String>
<x:String x:Key="myStringTwo">Hello String Two</x:String>
<x:Array x:Key="myArray" Type="{x:Type x:String}">
<x:String>mono</x:String>
<x:String>monodroid</x:String>
<x:String>monotouch</x:String>
<x:String>monorail</x:String>
<x:String>monodevelop</x:String>
<x:String>monotone</x:String>
<x:String>monopoly</x:String>
<x:String>monomodal</x:String>
<x:String>mononucleosis</x:String>
</x:Array>
</ContentPage.Resources>
<StackLayout>
<ListView ItemSource="{StaticResource myArray}"/>
</StackLayout>
</ContentPage>
You can refer to this document Creating and Consuming a ResourceDictionary.

You should declare like this:
<x:Array Type="{x:Type x:String}">
<x:String>Hello</x:String>
<x:String>World</x:String>
</x:Array>
Or, another example using Color Object:
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<Color>Aqua</Color>
<Color>Black</Color>
<Color>Blue</Color>
<Color>Fuchsia</Color>
<Color>Gray</Color>
<Color>Green</Color>
<Color>Lime</Color>
<Color>Maroon</Color>
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
You can check the XAML Markup docs here

Related

UWP ListView selected item highlight disappears if ItemContainerStyle is set

I am using a ListView to display a list of items. But when I set the font of the items using ItemContainerStyle and now an item is selected, the ListView highlight (blue line on the left) is no longer visible. On this screenshot here is a comparison. The problem has come with the installation of the Microsoft.UI.Xaml package, because here the design of ListView has been changed. Is there any way to fix this without having to remove ItemContainerStyle or the Microsoft.UI.Xaml package?
MainPage.xaml
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<ListView HorizontalAlignment="Left">
<ListViewItem Content="ABCD"/>
<ListViewItem Content="abcd"/>
<ListViewItem Content="1234"/>
</ListView>
<ListView HorizontalAlignment="Right">
<ListViewItem Content="ABCD"/>
<ListViewItem Content="abcd"/>
<ListViewItem Content="1234"/>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="FontSize" Value="16"></Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
</Page>
App.xaml
<Application
x:Class="App1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1">
<Application.Resources>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</Application.Resources>
</Application>
The reason for this behavior is that when you set a new ItemContainerStyle for the listview, it overrides the default item style that is used from the WinUI library.
The solution to this is that you need to give the item a style based on the style that the item is currently using. I find the default style of the ListViewItem in WinUI GitHub: ListViewItem_themeresources. So you just need to create a style that is based on the DefaultListViewItemStyle.
You will need to change a little bit of your code like this:
<ListView>
<ListViewItem Content="ABCD"/>
<ListViewItem Content="abcd"/>
<ListViewItem Content="1234" />
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource DefaultListViewItemStyle}">
<Setter Property="FontSize" Value="25"></Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>

xamarin.forms hamburger icon

I have a problem with master page and hamburger button, when the menu is hidden the height of the button doesn't fill the height (first image), othervise yes (second image). I really don't understand.
Somebody can help me?
Thanks a lot in advance.
here the page to show
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DMInfoOrganizer"
x:Class="DMInfoOrganizer.Impostazioni" Title="{local:Translate TxtImpostazioni}" >
<ContentPage.Content>
<StackLayout>
<Label x:Name="Lbl" Text="{local:Translate TxtImpostazioni}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
here the masterpage
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DMInfoOrganizer"
x:Class="DMInfoOrganizer.MasterPage">
<StackLayout>
<ListView x:Name="lstMenu" x:FieldModifier="public">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:MasterPageItem}">
<local:MasterPageItem Title="{local:Translate TxtHome}" TargetType="{x:Type local:Home}" />
<local:MasterPageItem Title="{local:Translate TxtNuovaLibreria}" TargetType="{x:Type local:NuovaLibreria}" />
<local:MasterPageItem Title="{local:Translate TxtImpostazioni}" TargetType="{x:Type local:Impostazioni}" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1" Text="{Binding Title}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
As far as I can tell Microsoft has changed the toolbar items height in 1809 and your app doesn't seem to handle that well. So you shouldn't use SDK for 1809 to compile the app (but some older) and everything will be fine.
thanks a lot!
The problem is that I can't compile app with older sdk version because I have this error
This version of Win2D requires Windows SDK >= 10.0.17134.0, but TargetPlatformVersion is 10.0.16299.0.
edit: I Installed the 10.0.17134.0 version and now all works.

Can not Add() elements to page (IOS) xaml, gif image

Hello I'm trying to use FFImageloader package in XAML. I've added the custom renders in appdelegate and mainacticivy on the devices. When it renderes my page it throws an error.
I've tried to remove properties from the new namespace and it still throws this error. I have added the namespaces and installed the following packages from the guide on their github page.
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ODEON.Pages.news"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
Title="MainWindow">
<ContentPage.Content>
<ffimageloading:CachedImage HorizontalOptions="Center" VerticalOptions="Center"
WidthRequest="300" HeightRequest="300"
DownsampleToViewSize="true"
Source = "http://loremflickr.com/600/600/nature?filename=simple.jpg">
</ffimageloading:CachedImage>
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding title.rendered}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
this is the error :
ODEON/Pages/news.xaml(10,10): Error: Position 9:10. Can not Add() elements to ODEON.Pages.news.Content (ODEON.iOS)

Xamarin.Forms - x:Reference 2nd level

I'm currently working in a new ContentPage for my application and I have some controls with DataTemplates.
I would like to use a Command in my ContentPage's ViewModel in one of the DataTemplates, however I'm not sure how to do the right reference for this to work properly. Here's my XAML code:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MaverickMobileOnline.ImagesListingPage"
--MANY NAMESPACE REFERENCES--
>
<ContentPage.Resources>
<ResourceDictionary>
<c:ItemTappedEventArgsConverter x:Key="ItemTappedConverter" />
<c:ItemAppearingEventArgsConverter x:Key="ItemAppearingConverter" />
<c:BooleanNegationConverter x:Key="not" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Spacing="0">
<commonViews:MainCustomNavBar MinimumHeightRequest="120" />
<controls:PullToRefreshLayout
x:Name = "layout"
RefreshCommand="{Binding btn_reload_businesses_images_click}"
IsEnabled = "True"
IsRefreshing="{Binding Path=is_businesses_loading}" >
<ScrollView
x:Name = "scrollView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<templates:ItemsStack
Padding="0"
Margin="0,10,0,10"
x:Name="itmStack"
BackgroundColor="White"
ItemsSource="{Binding Path=photos_list}">
<templates:ItemsStack.ItemTemplate>
<DataTemplate>
<artina:GridOptionsView
Padding="10,0"
ColumnSpacing="10"
RowSpacing="10"
VerticalOptions="Fill"
HeightRequest="120"
ColumnCount="3"
RowCount="1"
ItemsSource="{Binding Path=.}">
<artina:GridOptionsView.ItemTemplate>
<DataTemplate>
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MaverickMobileOnline.GalleryImageItemTemplate"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations">
<ContentView.Content>
<ffimageloading:CachedImage
FadeAnimationEnabled="true"
Aspect="AspectFill"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
LoadingPlaceholder="advertising_photo_placeholder.png"
Source="{Binding Path=image_medium}" />
</ContentView.Content>
<ContentView.GestureRecognizers>
<TapGestureRecognizer
-- HERE! --
Command="{Binding Source={x:Reference X}, Path=BindingContext.command_name}"
CommandParameter="{Binding image_medium}"
/>
</ContentView.GestureRecognizers>
</ContentView>
</DataTemplate>
</artina:GridOptionsView.ItemTemplate>
</artina:GridOptionsView>
</DataTemplate>
</templates:ItemsStack.ItemTemplate>
</templates:ItemsStack>
</ScrollView>
</controls:PullToRefreshLayout>
</StackLayout>
</ContentPage>
Please take a look at the code after the mark "-- HERE! --".
PS: I'm just refining this layout on order to improve performance.
Any help will be appreciated.
UPDATE:
ViewModel:
public RelayCommand<string> btn_image_tap_preview
{
get
{
return new RelayCommand<string>(
OpenImagePreview
);
}
}
//* Image tap
private async void OpenImagePreview(string url)
{
//* Some code
}
Updated XAML:
<StackLayout x:Name="mainStack" Spacing="0">
<commonViews:MainCustomNavBar MinimumHeightRequest="120" />
....
<ContentView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference mainStack}, Path=BindingContext.btn_image_tap_preview}"
CommandParameter="{Binding image_medium}" />
</ContentView.GestureRecognizers>
I'm debugging but I can't reach the ViewModel's command.
You can use x:Reference and take the binding context of any layout or element from your content page like StackLayout. Since its binding context is the ViewModel of the page it would have the command you are looking for at the first level itself. You can directly use it.
<StackLayout x:Name="myStackLayout" Spacing="0">
<commonViews:MainCustomNavBar MinimumHeightRequest="120" />
....
<ContentView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference myStackLayout}, Path=BindingContext.command_name}"
CommandParameter="image_medium" />
</ContentView.GestureRecognizers>
Or you can set the binding context for TapGesture
<TapGestureRecognizer BindingContext="{Binding Source={x:Reference myStackLayout.BindingContext}}" Command="{Binding command_name}"
DataTemplates does not seem to work well with x:Reference prior to v1.4.4, you can read more about in the forum post - x:Reference not working?.
The implementation in the newer version can be seen in the answer here.
If you are interested the Bugzilla issue that was fixed is here.

How to change icon color in Xamarin.Forms xaml page?

Currently, I am developing a Xamarin.Forms PCL application for Android and iOS. In one of my pages I define a ListView. The template for the ListView.ItemTemplate displays an icon using <Image Source="some_Icon.png" />. The icon displays as expected (black) but I have not found a way to set the color.
I would like to colorize this icon based on logic in my ViewModel.
I have searched for answers both through the Documentation and StackOverlflow to no avail.
Is there a better way to display and style icons from a Xamarin.Forms PCL project?
Does Xamarin.Forms require a set of resource/image files for every possible color I might use?
I solved my problem with Iconize for Xamarin.Forms. I implemented my solution based off the Iconize sample code below.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:iconize="clr-namespace:FormsPlugin.Iconize;assembly=FormsPlugin.Iconize"
x:Class="Iconize.FormsSample.Page1"
Title="{Binding FontFamily}">
<ContentPage.ToolbarItems>
<iconize:IconToolbarItem Command="{Binding ModalTestCommand}" Icon="fa-500px" />
<iconize:IconToolbarItem Command="{Binding VisibleTestCommand}" Icon="fa-500px" IconColor="Red" />
<iconize:IconToolbarItem Command="{Binding VisibleTestCommand}" Icon="fa-500px" IsVisible="{Binding VisibleTest}" />
</ContentPage.ToolbarItems>
<ListView CachingStrategy="RecycleElement" ItemsSource="{Binding Characters}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<iconize:IconImage HeightRequest="20" Icon="{Binding Key}" IconColor="Blue" WidthRequest="20" />
<iconize:IconImage HeightRequest="20" Icon="{Binding Key}" BackgroundColor="Blue" IconColor="Yellow" WidthRequest="20" IconSize="10" />
<iconize:IconButton FontSize="20" Text="{Binding Key}" TextColor="Red" WidthRequest="48" />
<iconize:IconLabel FontSize="20" Text="{Binding Key}" TextColor="Green" VerticalTextAlignment="Center" />
<Label Text="{Binding Key}" VerticalTextAlignment="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
In my case, I simply had to replace my original <Image .../> element and replace it with
<iconize:IconImage HeightRequest="20" Icon="fa-circle" IconColor="{Binding CircleColor}" WidthRequest="20" />.
In my ViewModel, I added the CircleColor property to set the icon color as needed based on my logic.