xamarin image button svg with text (size svg) - xaml

I want to make a button, image button svg with text.
In xaml:
<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"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
mc:Ignorable="d"
x:Class="loginUI.L202">
<StackLayout VerticalOptions="Center" Spacing="50">
<StackLayout.Resources>
<ResourceDictionary>
<Style TargetType="Button">
<Setter Property="HorizontalOptions" Value="FillAndExpand"/>
</Style>
<Style TargetType="Image">
<Setter Property="WidthRequest" Value="50"/>
</Style>
</ResourceDictionary>
</StackLayout.Resources>
<Button Text=" test" BackgroundColor="Wheat" BorderRadius="20" TextColor="red">
<Button.Image>
<OnPlatform x:TypeArguments="FileImageSource" Android="home.svg" iOS="home.svg"/>
</Button.Image>
</Button>
</StackLayout>
How to set the size (WidthRequest | HeightRequest) for home.svg? TargetType="Image" does not work.
Or
There is a way to insert into the button like ?
<Button> <Path Data="M185.255 512c-76.201 ....." /> </Button>

Why use Button if you can use ImageButton?
<ImageButton Source="img.xml" WidthRequest="100" HeightRequest="100" />
But, if you want to use Button, then:
<Button ImageSource="img.xml" WidthRequest="100" HeightRequest="100" />
Why .xml?
Because you need to convert your .svg file in a Vector to use as ImageSource of your Button. Use this link to convert, then, add it on your drawable folder.

Related

Dynamic resource not updating ImageButton style in .NET MAUI

I defined two ContentPage level styles to be bound dynamically to an ImageButton. When the ImageButton click event is called, it is supposed to switch the ImageButton style, but this is not happening.
Below is the ContentPage content with the styles and the ImageButton definition:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SampleMobile.SamplePage"
Title="">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="defaultStyle" TargetType="ImageButton">
<Setter Property="BorderColor" Value="Grey"/>
<Setter Property="BorderWidth" Value="2" />
</Style>
<Style x:Key="selectedStyle" TargetType="ImageButton">
<Setter Property="BorderColor" Value="Blue"/>
<Setter Property="BorderWidth" Value="5" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Grid RowDefinitions="50, 100, 5, 100, 5, 50, 100, 100, 100" ColumnDefinitions="*, *, *, *"
Padding="25, 35, 25, 35" ColumnSpacing="5" RadioButtonGroup.GroupName="mobileNetworks">
<Label Grid.Row="0" Grid.ColumnSpan="4"
Text="Select Network"
VerticalOptions="Center"
HorizontalOptions="Center" />
<ImageButton Source="first.png" Grid.Row="1" Grid.Column="0" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{DynamicResource imageButtonStyle}"/>
<ImageButton Source="second.png" Grid.Row="1" Grid.Column="1" BorderWidth="2" HeightRequest="50" WidthRequest="50" BorderColor="Grey" CornerRadius="10"/>
<ImageButton Source="third.png" Grid.Row="1" Grid.Column="2" BorderWidth="2" HeightRequest="50" WidthRequest="50" BorderColor="Grey" CornerRadius="10"/>
<ImageButton Source="fourth.png" Grid.Row="1" Grid.Column="3" BorderWidth="2" HeightRequest="50" WidthRequest="50" BorderColor="Grey" CornerRadius="10"/>
</Grid>
</ContentPage>
Below is the code behind file where the first style is set, and the second style is set inside the click event handler:
public partial class SamplePage : ContentPage
{
public SamplePage()
{
InitializeComponent();
Resources["imageButtonStyle"] = Resources["defaultStyle"];
}
private void SelectImage(object sender, EventArgs e)
{
Resources["imageButtonStyle"] = Resources["selectedStyle"];
}
}
I'm still trying to find what is wrong, and why it is not working as expected.
You can use this.
First give the ImageButton a name like this x:Name="Image1"
I added 2 Buttons to change it and go back.
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="defaultStyle" TargetType="ImageButton">
<Setter Property="BorderColor" Value="Gray"/>
<Setter Property="BorderWidth" Value="2" />
</Style>
<Style x:Key="selectedStyle" TargetType="ImageButton">
<Setter Property="BorderColor" Value="Blue"/>
<Setter Property="BorderWidth" Value="5" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
</Frame>
<ImageButton x:Name="Image1" Source="balzwart.png" Style="{DynamicResource defaultStyle}" />
<Button Text="Change" Clicked="Button_Clicked" />
<Button Text="Back" Clicked="Button_Clicked_1" />
</StackLayout>
and for the Button Click
private void Button_Clicked(object sender, EventArgs e)
{
Image1.Style = (Style)Resources["selectedStyle"];
}
private void Button_Clicked_1(object sender, EventArgs e)
{
Image1.Style = (Style)Resources["defaultStyle"];
}
Find it here https://github.com/borisoprit/DynamicSO
Instead of manipulating the styles at runtime, which is only a semi-good idea and should be done differently anyway, I recommend you do something like below instead using Visual States and only one Style for the ImageButton:
<?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="SelectedImageSample.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="ImageButtonStyle" TargetType="ImageButton">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BorderColor" Value="Blue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Grid RowDefinitions="50, 100, 5, 100, 5, 50, 100, 100, 100" ColumnDefinitions="*, *, *, *"
Padding="25, 35, 25, 35" ColumnSpacing="5" RadioButtonGroup.GroupName="mobileNetworks">
<Label Grid.Row="0" Grid.ColumnSpan="4"
Text="Select Network"
VerticalOptions="Center"
HorizontalOptions="Center" />
<ImageButton Source="first.png" Grid.Row="1" Grid.Column="0" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
<ImageButton Source="second.png" Grid.Row="1" Grid.Column="1" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
<ImageButton Source="third.png" Grid.Row="1" Grid.Column="2" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
<ImageButton Source="fourth.png" Grid.Row="1" Grid.Column="3" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
</Grid>
</ContentPage>
In your Code Behind, you then can use the event handler to set the Visual State as follows:
private void SelectImage(object sender, EventArgs e)
{
if (sender is ImageButton imageButton)
{
VisualStateManager.GoToState(imageButton, "Selected");
}
}
This is just the minimal demonstration of how it can be done without manipulating a style in the resources. If you want to unselect the ImageButton again, you'll need to implement some logic and an Unselected Visual State.
Update 1
It might be useful to store some kind of state on the button by adding an IsSelected property (e.g. via inheritance). Then the Visual State can be updated accordingly.
Update 2
If you don't want to extend ImageButton, you could also use an Attached Property to store the state for the button.

Expander arrow image not updating with AppThemeBinding in Xamarin.Forms

If I try to make the arrow image for an expander change with system theme change, it doesn't change. The code below works perfectly, but the arrow image will be impossible to see if the app is in dark mode.
<xct:Expander>
<xct:Expander.Header>
<Grid>
<Label
FontAttributes="Bold"
FontSize="15"
Style="{StaticResource Label}"
Text="More Details" />
<Image
HeightRequest="25"
HorizontalOptions="End"
Source="DownArrow.png"
VerticalOptions="Start">
<Image.Triggers>
<DataTrigger
Binding="{Binding Source={RelativeSource AncestorType={x:Type xct:Expander}}, Path=IsExpanded}"
TargetType="Image"
Value="True">
<Setter Property="Source" Value="UpArrow.png" />
</DataTrigger>
</Image.Triggers>
</Image>
</Grid>
</xct:Expander.Header>
<Label
Text="Some content"
TextColor="{AppThemeBinding Light={StaticResource TextColor},
Dark=LightGray}" />
</xct:Expander>
If I try to make the make the arrow for the expander change with the system theme by doing {AppThemeBinding Light=DownArrow.png,Dark=DownArrowDark.png} and {AppThemeBinding Light=UpArrow.png,Dark=UpArrowDark.png} for image source, the image only changes from a down arrow to an up arrow on the first click then stays as an up arrow and doesn't update.
Rotate the image 180 degrees instead of replacing the source:
<Setter Property="Rotation" Value="180" />

Xamarin Forms Material Design Icons Webfont

I am still pretty new to Xamarin Forms and I am having issues with displaying Material Design Icons for my app. I keep getting the box with question mark and I do not understand why. I am using a control template to create a header and footer for my page.
Heres the output on the screen:
View Display
Heres my App.xaml code:
<?xml version="1.0" encoding="utf-8"?>
<Application 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="DueMore.App">
<Application.Resources>
<ResourceDictionary>
<Color x:Key="fgColor">#66169C</Color>
<Color x:Key="bgColor">#FFFFFF</Color>
<Color x:Key="OverDueItem">#FF1C07</Color>
<OnPlatform x:Key="Material" x:TypeArguments="x:String">
<On Platform="iOS" Value="Material Design Icons" />
<On Platform="Android" Value="materialdesignicons-webfont.ttf#Material Design Icons" />
</OnPlatform>
<Style TargetType="{x:Type Button}" x:Key="MaterialIcons">
<Setter Property="FontFamily" Value="{DynamicResource Material}"/>
<Setter Property="FontSize" Value="100"/>
<Setter Property="HorizontalOptions" Value="Center"/>
<Setter Property="VerticalOptions" Value="Center"/>
<Setter Property="TextColor" Value="{DynamicResource fgColor}"/>
<Setter Property="FontSize" Value="Large"/>
</Style>
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="{DynamicResource bgColor}" />
<Setter Property="BarTextColor" Value="{DynamicResource fgColor}" />
</Style>
<ControlTemplate x:Key="MainPageTemplate">
<StackLayout>
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="1"
Grid.RowSpan="10"
Grid.Column="0"
Grid.ColumnSpan="5"/>
<Entry Placeholder="Enter an Inbox Item"
HeightRequest="50"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="9"
BackgroundColor="{DynamicResource bgColor}"
TextColor="{DynamicResource fgColor}"
HorizontalOptions="Fill"/>
<Button Text=""
Style="{StaticResource MaterialIcons}"
Clicked="Save_Clicked"
Grid.Row="9"
Grid.Column="3"/>
<Button Text=""
Style="{StaticResource MaterialIcons}"
Clicked="Button_Clicked"
Grid.Row="9"
Grid.Column="4"/>
</Grid>
</StackLayout>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
Any help would be appreciated! Thank you in advance!
On Android, you need to add the font icons to your Assets folder in your android platform specific project. On iOS, you need to add the font icons to the Resources folder in the iOS project.
ControlTemplate usage:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="App2.MainPage"
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"
ControlTemplate="{StaticResource MainPageTemplate}"
mc:Ignorable="d">
<StackLayout>
<!-- Place new controls here -->
</StackLayout>
Screenshot:
For the source file with Material Design Icons, you could download from the GitHub.
https://github.com/WendyZang/Test/tree/master/MaterialDesignIcons/App2

ResourceDictionary: System.InvalidCastException

I get an Exception throw and I cant figure out why. My guess is that Im overlooking something simple. The Exception gets thrown in ResourceSharingPage.xaml.g.cs
this is my xaml:
<?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="BookCodedotNet2.ResourceSharingPage">
<ContentPage.Resources>
<ResourceDictionary>
<x:String x:Key="fontSize">Large</x:String>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text=" Carpe diem ">
<Button.FontSize>
<StaticResourceExtension Key="fontSize"/>
</Button.FontSize>
</Button>
</StackLayout>
</ContentPage>
If I remove
<Button.FontSize>
<StaticResourceExtension Key="fontSize"/>
</Button.FontSize>
I can build the app.
In the resources, try something like below. Use double value instead of string as FontSize is a double.
<ResourceDictionary>
<x:Double x:Key="fontSize">35</x:Double>
</ResourceDictionary>
You've defined the resource of type x:String. FontSize doesn't accept values of type String. It only accepts values of type Double or NamedSize. As you mentioned in the comment to Abdul Gani's answer, you should be defining NamedSize.
You are better off using the Style tag and setting the style of your Label that way. Follow SushiHangover's answer over here if you want to use Style instead.
You can use NamedSize in resource dictionary in this way:
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="fontSize" TargetType="Button">
<Setter Property="FontSize" Value="Large" />
</Style>
<Color x:Key="NormalTextColor">Blue</Color>
<Style x:Key="MediumBoldText" TargetType="Button">
<Setter Property="FontSize" Value="Large" />
<Setter Property="FontAttributes" Value="Bold" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text=" Carpe diem " Style="{StaticResource fontSize}"> </Button>
<Button Text="Test"
TextColor="{StaticResource NormalTextColor}"
Style="{StaticResource MediumBoldText}" />
</StackLayout>

How to define ResourceDictionary by adding Style in Xamarin xaml {GroupStyle}

I'm trying to make something like set atribute to all labels inside a grid
I Know how to make it, just doing this:
<Grid RowSpacing="2" Padding="2,0,2,0">
<Grid.Resources>
<ResourceDictionary>
<Style BasedOn="{StaticResource Font-Awesome}" TargetType="Label"/>
</ResourceDictionary>
</Grid.Resources>
<Label Text="31 " Grid.Column="0" TextColor="#2764B5" XAlign="Start"/>
<Label Text="91 " Grid.Column="1" TextColor="#A0A1A2" XAlign="Center"/>
<Label Text="12 " Grid.Column="2" TextColor="#A0A1A2" XAlign="End"/>
</Grid>
But Its Ugly and redundant
I want to do smetthing like
<Grid RowSpacing="2" Padding="2,0,2,0" Style="{StaticResource grd-actions}">
<Label Text="31 " Grid.Column="0" TextColor="#2764B5" XAlign="Start"/>
<Label Text="91 " Grid.Column="1" TextColor="#A0A1A2" XAlign="Center"/>
<Label Text="Compartilhar " Grid.Column="2" TextColor="#A0A1A2" XAlign="End"/>
</Grid>
And On App Static Resources include the ResourceDictionary for the grid, something like:
<Style x:Key="gd-actions" TargetType="Grid">
<Setter Property="Resources">
<Setter.Value>
<ResourceDictionary>
<Style BasedOn="{StaticResource Font-Awesome}" TargetType="Label"/>
</ResourceDictionary>
</Setter.Value>
</Setter>
</Style>
I've being trying with a lot of ways but it's aways throw some kind of exception!
Can someone help-me Here?
I guess the most clean way to do this is by using Explicit Styles with Global Resources. Declare the style for that Labels in Application Resources and then in you label just add the Style Property:
Application:
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="xforms_test.App">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="labelAquaStyle" TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="TextColor" Value="Aqua" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
And in your page:
<Grid RowSpacing="2" Padding="2,0,2,0">
<Label Grid.Column="0" Text="These labels" Style="{StaticResource labelAquaStyle}" />
<Label Grid.Column="1" Text="are demonstrating" Style="{StaticResource labelAquaStyle}" />
<Label Grid.Column="2" Text="explicit styles" Style="{StaticResource labelAquaStyle}" />
</Grid>