I am creating a MAUI project that uses graphic components (buttons) defined in an external DLL.
The images of these buttons are resources embedded in the external DLL that I load in this way:
ImageSource.FromResource (Instance.LOCAL_ASSEMBLY_IMAGEPATH + filename, Instance.LOCAL_ASSEMBLY);
When I run on windows the images are correct, when I run on android the images are randomly placed ...
This is only a display issue because the button instance is right.
Windows example
Android example
XAML top bar
<Shell.TitleView>
<Grid x:Name="ShellViewObject" HorizontalOptions="FillAndExpand" Margin="0" Padding="0" ColumnSpacing="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
<ColumnDefinition Width="48" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
</Grid>
</Shell.TitleView>
Button creation as follows
BadgeButton vo = new SimpleControls.BadgeButton();
vo.StyleId = name;
vo.Padding = new Thickness(0, 0, 0, 0);
vo.Margin = new Thickness(0, 0, 0, 0);
vo.ImageSize = 40;
vo.BadgeImageText = img;
vo.HorizontalOptions = LayoutOptions.CenterAndExpand;
vo.Clicked += CALLING_TOP_BAR_BUTTON_CLICK;
vo.VerticalOptions = LayoutOptions.Center;
return vo;
Badge button XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiSY.SimpleControls.BadgeButton" Padding="0" Margin="0">
<Grid Padding="0" RowSpacing="0" ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="BadgeIconImage" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2"
Margin="3" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
/>
<Frame x:Name="BadgeFrame" Grid.Row="0" Grid.Column="1" CornerRadius="8"
Padding="0" HasShadow="False" BorderColor="Transparent"
VerticalOptions="Fill" HorizontalOptions="Fill"
WidthRequest="35" HeightRequest="35">
<Label x:Name="BadgeTextLabel" FontSize="3" HorizontalOptions="Center" VerticalOptions="Center" />
</Frame>
</Grid>
</ContentView>
Related
My desired output is that if I click on the "male" image it will look like it is CLICKED/SELECTED so it will change from "male" to "selected_male".
I last code that I posted here was working if I don't place the but If I place a background image the TapGestureRecognizer seems to be not working, but I want to have a background for my application, please help.
This is the code that I tried:
I have this overlapping Image in my page1.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"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:App1.Renderers"
mc:Ignorable="d"
x:Class="App1.SignUpPage">
<ContentPage.Content>
<StackLayout>
<RelativeLayout>
<Image Source="blue_gradient1"
Aspect ="AspectFill"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height}"/>
<Grid Margin="0,10,0,0" VerticalOptions="CenterAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Source="male"
WidthRequest="200"
HeightRequest="165"
x:Name="ImgSrcMale"
Grid.Row="0"
Grid.Column="0">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="MaleClick"
NumberOfTapsRequired="1"
Tapped="MaleClick_Tapped"/>
</Image.GestureRecognizers>
</Image>
<Image Source="Record"
WidthRequest="200"
HeightRequest="165"
x:Name="ImgSrcMaleSelected"
Grid.Row="0"
Grid.Column="0"
IsVisible="False">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="SelectedMaleClick"
NumberOfTapsRequired="1"
Tapped="SelectedMaleClick_Tapped"/>
</Image.GestureRecognizers>
</Image>
<Image Source="female1"
WidthRequest ="200"
HeightRequest="165"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
Aspect="AspectFit"
Grid.Row="0"
Grid.Column="1"/>
</Grid>
<Grid RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height}">
<ScrollView>
<StackLayout>
<Grid Margin="20,0,20,0" VerticalOptions="CenterAndExpand" RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="Gender"
FontSize="Title"
TextColor="WhiteSmoke"
HorizontalOptions="Center"
FontAttributes = "Bold"
Grid.Row="0"/>
</Grid>
</StackLayout>
</ScrollView>
</Grid>
</RelativeLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
I have this code in my page1.xaml.cs:
public void MaleClick_Tapped(object sender, EventArgs e)
{
if (ImgSrcMale.IsVisible == true)
{
ImgSrcMaleSelected.IsVisible = true;
ImgSrcMale.IsVisible = false;
}
else if (ImgSrcMaleSelected.IsVisible == true)
{
ImgSrcMale.IsVisible = true;
ImgSrcMaleSelected.IsVisible = false;
}
}
private void SelectedMaleClick_Tapped(object sender, EventArgs e)
{
if (ImgSrcMale.IsVisible == true)
{
ImgSrcMaleSelected.IsVisible = true;
ImgSrcMale.IsVisible = false;
}
else if (ImgSrcMaleSelected.IsVisible == true)
{
ImgSrcMale.IsVisible = true;
ImgSrcMaleSelected.IsVisible = false;
}
}
I reproduce with the code you provided. It caused by the WidthConstraint and HeightConstraint. Delete it in image and grid. Everything would be okay.
If you want to make the image fill all the screen as background. Delete the image which you used to set as background. And set the background image with BackgroundImageSource property in ContentPage.
<Image Source="blue_gradient1"
Aspect ="AspectFill"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height}"/>
Xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="ImageDemo.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"
BackgroundImageSource="pink.jpg"
mc:Ignorable="d">
<ContentPage.Content>
<StackLayout>
<RelativeLayout>
<!--<Image
Aspect="AspectFill"
Source="pink.jpg" />-->
<Grid Margin="0,10,0,0" VerticalOptions="CenterAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image
x:Name="ImgSrcMale"
Grid.Row="0"
Grid.Column="0"
HeightRequest="165"
Source="dog.jpg"
WidthRequest="200">
<Image.GestureRecognizers>
<TapGestureRecognizer
x:Name="MaleClick"
NumberOfTapsRequired="1"
Tapped="MaleClick_Tapped" />
</Image.GestureRecognizers>
</Image>
<Image
x:Name="ImgSrcMaleSelected"
Grid.Row="0"
Grid.Column="0"
HeightRequest="165"
IsVisible="False"
Source="walrus.jpg"
WidthRequest="200">
<Image.GestureRecognizers>
<TapGestureRecognizer
x:Name="SelectedMaleClick"
NumberOfTapsRequired="1"
Tapped="SelectedMaleClick_Tapped" />
</Image.GestureRecognizers>
</Image>
<Image
Grid.Row="0"
Grid.Column="1"
Aspect="AspectFit"
HeightRequest="165"
HorizontalOptions="CenterAndExpand"
Source="lighthouse.jpg"
VerticalOptions="CenterAndExpand"
WidthRequest="200" />
</Grid>
<Grid>
<ScrollView>
<StackLayout>
<Grid
Margin="20,0,20,0"
RowSpacing="20"
VerticalOptions="CenterAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
FontAttributes="Bold"
FontSize="Title"
HorizontalOptions="Center"
Text="Gender"
TextColor="WhiteSmoke" />
</Grid>
</StackLayout>
</ScrollView>
</Grid>
</RelativeLayout>
</StackLayout>
</ContentPage.Content>
I have this code:
<Grid Margin="0,0,0,0" VerticalOptions="CenterAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- EACH IMAGE SHOULD BE CENTERED IN THE GRID 0 AND ROW 0-->
<StackLayout Grid.Row="0" Grid.Column="0" Padding="0,18,0,0">
<Image Source="male"
WidthRequest ="200"
HeightRequest="165"
TranslationX="5"
TranslationY="10"
HorizontalOptions="LayoutOptions.Center"
VerticalOptions="LayoutOptions.Fill"
Aspect="AspectFit"/>
</StackLayout>
<StackLayout Grid.Row="0" Grid.Column="1" Padding="0,15,0,0">
<Image Source="female"
WidthRequest ="160"
HeightRequest="125"
TranslationX="5"
TranslationY="31"
HorizontalOptions="LayoutOptions.Center"
VerticalOptions="LayoutOptions.Fill"
Aspect="AspectFit"/>
</StackLayout>
</Grid>
It looks centered in my designer, but when I run the code in my emulator it does not look centered. This is mostly the answers that I have found when I was searching on how to do it. I dont know If I have missed a certain property.
I am still new in Xamarin and I am still learning on how this works.
If you want to center the image, you could try the code below. Delete padding, TranslationX, TranslationY, add a column, and use the CenterAndExpand for layoutoptions. For better understanding, I use the backgroundcolor of stacklayout to show the results.
You could change the ColumnDefinition to Auto, it works as well.
<Grid Margin="0,0,0,0" VerticalOptions="CenterAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<!-- EACH IMAGE SHOULD BE CENTERED IN THE GRID 0 AND ROW 0 -->
<StackLayout
Grid.Row="0"
Grid.Column="0"
BackgroundColor="Accent">
<Image
Aspect="AspectFit"
HeightRequest="165"
HorizontalOptions="CenterAndExpand"
Source="dog.jpg"
VerticalOptions="CenterAndExpand"
WidthRequest="200" />
</StackLayout>
<StackLayout
Grid.Row="0"
Grid.Column="1"
BackgroundColor="Accent">
<Image
Aspect="AspectFit"
HeightRequest="125"
HorizontalOptions="CenterAndExpand"
Source="pig.jpg"
VerticalOptions="CenterAndExpand"
WidthRequest="160" />
</StackLayout>
</Grid>
I have to admit absolutelayout is the thing that does not get into my head.
Can you help?
I need to put an image on top of a frame -grid etc.. on few screen so I must find a solution that works.
This is what I want to achieve
This is what I have done used boxview (purple) supposed to be my img1.
MyXaml
<AbsoluteLayout>
<StackLayout Margin="20">
<BoxView Color="Purple" WidthRequest="40" HeightRequest="40"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"></BoxView>
<Frame
Padding="0"
BorderColor="Green"
CornerRadius="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<BoxView Grid.Row="0" Grid.Column="0" Margin="5" Color="Red"/>
<BoxView Grid.Row="0" Grid.Column="4" Margin="5" Color="GreenYellow"/>
</Grid>
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" HeightRequest="50" BackgroundColor="Coral" Margin="20,0,20,0"
TextColor="White" Text="Label 3" />
<!--other stuff down here -->
</Grid>
</Frame>
</StackLayout>
</AbsoluteLayout>
My Result (as you can see I get a long rectangle when all i want is the boxview in the middle like above). Can you help?
This should get you started (I mod'ed a demo of mine, so adjust accordingly):
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,1,1,.50" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#66000000" Margin="10,10,10,10">
<Frame CornerRadius="10" Margin="20,20,20,20" BackgroundColor="Black" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="1,1,1,1">
<Grid Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Text="Left" BackgroundColor="White" HorizontalTextAlignment="Center" Grid.Column="0" />
<Label Text="Right" BackgroundColor="White" HorizontalTextAlignment="Center" Grid.Column="2" />
<Label Text="Across Page" BackgroundColor="White" HorizontalTextAlignment="Center" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" />
</Grid>
</Frame>
<Image Source="yt.png"
BackgroundColor="Transparent"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".5,0,50,50" />
</AbsoluteLayout>
I have the following grid layout set up in my XAML page.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BoxView BackgroundColor="Red" Grid.Row="0" Grid.Column="0">
<BoxView.GestureRecognizers>
<PanGestureRecognizer PanUpdated="PanGestureRecognizer_OnPanUpdated"/>
</BoxView.GestureRecognizers>
</BoxView>
<BoxView BackgroundColor="Green" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" />
<BoxView BackgroundColor="Red" Grid.Row="0" Grid.Column="3" />
<BoxView BackgroundColor="Blue" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" />
<BoxView BackgroundColor="Purple" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2"/>
<BoxView BackgroundColor="Aqua" Grid.Row="2" Grid.Column="0" />
<BoxView BackgroundColor="Fuchsia" Grid.Row="2" Grid.Column="1" />
<BoxView BackgroundColor="GreenYellow" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2">
</BoxView>
</Grid>
I want to add a drag and drop functionality on each box view. The idea is I should be able to drag each box view and drop it on another box view having the same column span. Can someone please advise me on how to do this ? Please help.
Unfortunately, there is no built-in drag and drop functionality in Xamarin.Forms just yet. You can still implement it yourself using PanGestureRecognizer.
You can add gesture recognizer to your view, for example Label, like this:
<Label>
<Label.GestureRecognizers>
<PanGestureRecognizer PanUpdated="PanGestureRecognizer_OnPanUpdated" />
</Label.GestureRecognizers>
</Label>
Now in the PanUpdated event handler you can use TranslationX and TranslationY to move a view around.
private double _startTranslationX, _startTranslationY
private void PanGestureRecognizer_OnPanUpdated(object sender,
PanUpdatedEventArgs e)
{
var box = (BoxView) sender;
if (e.StatusType == GestureStatus.Started)
{
_startTranslationX = box.TranslationX;
_startTranslationY = box.TranslationY;
}
else if (e.StatusType == GestureStatus.Running)
{
box.TranslationX = _startTranslationX + e.TotalX;
box.TranslationY = _startTranslationY + e.TotalY;
}
else if (e.StatusType == GestureStatus.Completed)
{
box.TranslationX = _startTranslationX + e.TotalX;
box.TranslationY = _startTranslationY + e.TotalY;
//handle drop here (depending on your requirements)
}
}
To actually implement a drop functionality you will have to manually test where the object is currently located and if dropping is allowed there.
I have following layout
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid Height="100" Background="Wheat" Opacity="0.4">
<StackPanel Orientation="Vertical" VerticalAlignment="Bottom">
<Slider Orientation="Vertical" Height="170" HorizontalAlignment="Center" Background="White" />
<Button Content="Btn" Width="100"/>
</StackPanel>
</Grid>
</Grid>
In this scenario Grid will clip rest of Slider which overflows Grid.
So I’m getting result like this
While I want to get result like this
So how can I force Slider to overflow Grid without clipping? Is it any alternatives solutions to this?
In fact I have more complicated layout so using Canvas instead of Grid is now welcome.
You can do this using a single Grid and playing with its childrens' Grid.RowSpan and Grid.ColumnSpan properties.
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Height="100"
Fill="Wheat"
Opacity="0.4" />
<StackPanel Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="1">
<Slider Orientation="Vertical"
Height="170"
HorizontalAlignment="Center"
Background="White" />
<Button Content="Btn"
Width="100" />
</StackPanel>
</Grid>