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

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.

Related

Stretch BindableLayout.ItemTemplate in Maui horizontally

I have a HorizontalStackLayout with elements in it added via the BindableLayout.Itemsource.
This is an example of what I mean:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutStretchTest.MainPage">
<VerticalStackLayout>
<HorizontalStackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Green">
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</BindableLayout.ItemsSource>
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
TextColor="White"
BackgroundColor="DarkBlue"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
<VerticalStackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Label Text="Text"
HorizontalTextAlignment="Center"
TextColor="Black"
BackgroundColor="White"/>
</VerticalStackLayout>
</VerticalStackLayout>
</ContentPage>
How can I make the Labels(Blue) FillAndExpand into the free space(Green)?
The Maui learn page says:
A HorizontalStackLayout only respects the alignment preferences on
child views that are in the opposite direction to the orientation of
the layout.
Is there a way to stretch the children, or what is the appropriate "container" for this use case?
Please be noted that it's a known issue that being tracked in [Bug] LayoutOptions Expand not work in HorizontalStackLayout and VerticalStackLayout . To be clear, the AndExpand options are deprecated, and are not supported in the new HorizontalStackLayout and VerticalStackLayout. As an alternative solution, you can achieve the same layout with a Grid. Or you can continue to use StackLayout for another choice.

XAML, Binding, Source and Path

I am learning to understand, how the binding mechanism works in XAML for .NET MAUI. I am assuming this is the same for all XAML projects, WPF, MAUI etc.
At the end is the whole XAML.
This XAML works fine:
<Button WidthRequest="150" Text="Add Activity"
Command="{Binding AddActivityEntityCommand}"
IsEnabled="{Binding IsNotBusy}"
Grid.Row="2"
Margin="8"/>
Is the reason why this works because the Button is part of the ContentPage, which has it's x:DataType set to MainPageViewModel, which is where the command lives?
The Binding is set to AddActivityEntityCommand, while the actual method signature is
async Task AddActivityEntityAsync(). How is this resolved? Since it obviously doesn't match the name, but it works. And what are the method signature requirements for this to work/being recognized?
This on the other hand, doesn't just work as easy out of the box:
<Label HorizontalOptions="End" TextColor="Red" Padding="0,0,10,0" Text="🗑"
IsVisible="{Binding IsSynchronized}">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={x:Type viewmodel:MainPageViewModel},
Path=DeleteActivityCommand}" />
</Label.GestureRecognizers>
</Label>
In this context, adding Command="{Binding DeleteActivityCommand} doesn't work, because it derives its Path from <DataTemplate x:DataType="model:ActivityEntity">, I am assuming, which is the data object and not the ViewModel, where the command actually is.
The problem here is, that as soon as I enter this XAML Command="{Binding Source={x:Type viewmodel:MainPageViewModel}, Path=DeleteActivityCommand}", the CollectionView shows empty and there is an unhandled exception thrown when the view is loaded:
System.Reflection.TargetException: Object does not match target type.
The method signature for this command is this async Task DeleteActivityAsync()
What am I missing?
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="OnesieMobile.View.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:model="clr-namespace:OnesieMobile.Model"
xmlns:viewmodel="clr-namespace:OnesieMobile.ViewModel"
x:DataType="viewmodel:MainPageViewModel"
Title="{Binding Title}">
<Grid
ColumnDefinitions="*"
RowDefinitions="20,50,50,*"
RowSpacing="0">
<Label HorizontalOptions="End" Margin="10,0,10,0" Text="{Binding CurrentDateTime}" Grid.Row="0"/>
<Entry Margin="10,0,10,0"
Grid.Row="1" x:Name="entryNewActivity"
Placeholder="New Activityssss" HeightRequest="30" Text="{Binding NewActivityTitle}" />
<Button WidthRequest="150" Text="Add Activity"
Command="{Binding AddActivityEntityCommand}"
IsEnabled="{Binding IsNotBusy}"
Grid.Row="2"
Margin="8"/>
<CollectionView
Grid.Row="3"
ItemsSource="{Binding ActivityEntities}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:ActivityEntity">
<Grid Padding="10,0,10,0">
<Frame Style="{StaticResource CardView}">
<Grid ColumnDefinitions="*,30,50">
<StackLayout Padding="10,5,0,0" Grid.Column="0">
<Label Text="{Binding Title}" />
</StackLayout>
<StackLayout Padding="10,5,0,0" Grid.Column="1">
<Label HorizontalOptions="End" TextColor="Red"
Padding="0,0,10,0" Text="🗑" IsVisible="{Binding IsSynchronized}" >
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={x:Type viewmodel:MainPageViewModel},
Path=DeleteActivityCommand}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
<StackLayout Padding="10,5,0,0" Grid.Column="2">
<Label HorizontalOptions="End"
Padding="0,0,10,0" Text="✔" IsVisible="{Binding IsSynchronized}" />
</StackLayout>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ActivityIndicator IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
Grid.RowSpan="3"
Grid.ColumnSpan="2"/>
</Grid>
</ContentPage>
Update:
MainPageViewModel.cs contains these Commands
[ICommand]
async Task DeleteActivityAsync()
{
}
[ICommand]
async Task AddActivityEntityAsync()
{
}
Inside an item template, there are several ways to refer to the original BindingContext. I like to do it by getting it from the collection itself:
<CollectionView x:Name="myCollection" ...>
...
<CollectionView.ItemTemplate>
...
Command="{Binding Source={x:Reference myCollection},
Path=BindingContext.DeleteActivityCommand}" />
FUTURE TBD:
I don't like the command name not existing anywhere in the implementing code. Hopefully there will eventually be a way to specify the command name in the ICommand attribute, to make it obvious:
// This won't work today.
[ICommand Name="DeleteActivityCommand"]
...
For now, we have to learn [ICommand]'s magic naming rules, which seem to be "Remove Async from end (if present); Add Command to end".

how to add checkbox in listview using xamarin forms

i want to create a checkbox in listview using xaml, after selecting the multiple checkbox click button to get all selected value.My code is :
<ContentPage.Content>
<ListView x:Name="ProductsListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Spacing="0">
<Label Text="{Binding retail_modified_item_id}"
TextColor="Blue" FontSize="13" />
<Label Text="{Binding name, StringFormat='Name :
{0:N}'}" TextColor="black" FontSize="10" />
<Label Text="{Binding retail_price,
StringFormat='Price : {0:N}'}"
TextColor="black" FontSize="10" />
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
my output is;
output without checkbox
i tried some sample code from https://www.ignatiuz.com/blog/xamarin/button-check-box-with-list-item-in-xamarin-forms-listview/
but i'm getting input:checkbox not found
i am new to xamarin please give some sample code or link to do this
You can use Plugin.InputKit from Nuget.
Usage
<?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:local="clr-namespace:xxx"
xmlns:input="clr-namespace:Plugin.InputKit.Shared.Controls;assembly=Plugin.InputKit"
x:Class="xxx.MainPage">
<ContentPage.Content>
<ListView x:Name="ProductsListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Spacing="0">
<Label Text="{Binding retail_modified_item_id}"
TextColor="Blue" FontSize="13" />
<Label Text="{Binding name, StringFormat='Name :
{0:N}'}" TextColor="black" FontSize="10" />
<Label Text="{Binding retail_price,
StringFormat='Price : {0:N}'}"
TextColor="black" FontSize="10" />
<input:CheckBox Text="xxx" Type="Check"/>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
I have written a content on implementing the multiselect listview in xamarin forms. Please check this : https://androidwithashray.blogspot.com/2018/03/multiselect-list-view-using-xamarin.html
Hope this helps.
Add/remove value to local collection using OnCheckChanged method.
I used this way:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="Some item" />
<CheckBox
IsChecked="true"
CheckedChanged="OnCheckedChanged"
HorizontalOptions="EndAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
If you need to have checkboxes inside a listview, you can use Xamarin.Forms.InputKi (https://github.com/enisn/Xamarin.Forms.InputKit)
Then I would define it like this inside a DataTemplate's ViewCell:
<input:CheckBox Text="Hello World I'm Option 2" Type="Check"/>
There are also Bindable properties and events which you can use depending on your scenario:
CheckChanged: (Event) Invokes when check changed.
CheckChangedCommand: (Command) Bindable Command, executed when check
changed.
Key: (int) A key you can set to define checkboxes as ID.
Text: (string) Text to display description
IsChecked: (bool) Checkbox checked situation. Works TwoWay Binding as
default.
Color: (Color) Color of selected check.
TextColor: (Color) Color of description text.
Type: (CheckType) Type of checkbox checked style.
(Check,Cross,Star,Box etc.)

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.

Xamarin.Forms can't display image in list

I have a ListView with several items in it. I am running the app as a UWP app on my local machine, but for some reason, displaying an image via a url doesn't work?
The tag I'm using is
<Image Source="https://en.bitcoin.it/w/images/en/2/29/BC_Logo_.png" HeightRequest="20" WidthRequest="20" />
I have tried using several different images from different domains as I thought it could be an authorisation issue? But no images that I've tried seem to be working.
As I define the space for the image, there is a gap in the list where it should be.
For reference, here is the whole list code:
<ContentPage Title="Coins">
<ContentPage.Content>
<ListView x:Name="coins" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Spacing="5" Orientation="Horizontal" Padding="10,10,10,10">
<Label Text="{Binding Path=Rank}" FontSize="10" VerticalTextAlignment="Center"/>
<Image Source="https://en.bitcoin.it/w/images/en/2/29/BC_Logo_.png" HeightRequest="20" WidthRequest="20" />
<Label Text="{Binding Path=Name}" TextColor="Black" FontSize="19" VerticalTextAlignment="Center"/>
<Label Text="{Binding Path=PercentChange24h, StringFormat='{0}%'}" VerticalTextAlignment="Center" TextColor="{Binding PercentTextColour}"/>
<Label Text="{Binding Path=LivePrice, StringFormat='${0}'}" VerticalTextAlignment="Center" HorizontalTextAlignment="End" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
This issue was down to UWP not being able to display images, this works on Android and iOS.