I have the following simple XAML 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="Test.UserGuides.VPN">
<ContentPage.Content>
<ScrollView>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center" Margin="10,10,10,10">
<Label Margin="10,10,10,10" Text="How to connect to VPN." HorizontalOptions="Center" />
<Label Margin="10,10,10,10" Text="If you have a corporate notebook, look for the Cisco AnyConnect application. Either in your start menu, on your desktop, or in your taskbar." />
<Image x:Name="imgVPN1" Margin="10,10,10,10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
<Label Margin="10,10,10,10" Text="Select your region and press the Connect button." />
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
In the constructor, I call a method to load the images:
private void LoadImages()
{
imgVPN1.Aspect = Aspect.AspectFit;
ImageSource imagesrc = ImageSource.FromResource("Test.Files.CiscoAnyConnect.PNG");
imgVPN1.Source = imagesrc;
}
The result looks like this on my (rather large, high DPI) phone:
imgur link 1
Of course, I want the image to automatically expand so it takes up the entire width of the screen. While maintaining the aspect ratio. But how can I achieve this? I've already tried putting the Aspect to "AspectFill", and added
imgVPN1.WidthRequest = Application.Current.MainPage.Width;
To the LoadImages method, but that makes the end result look like this:
imgur link 2
I've been toying around with various HorizontalOptions, VerticalOptions, Aspects, GridView, StackLayouts,... The end result is always either the first or the second screenshot. So how can I achieve what I want here?
Answer: Use the CSS max-width Property You can simply use the CSS max-width property to auto-resize a large image so that it can fit into a smaller width <div> container while maintaining its aspect ratio.
To make an image responsive, you need to give a new value to its width property. Then the height of the image will adjust itself automatically. The important thing to know is that you should always use relative units for the width property like percentage, rather than absolute ones like pixels.
Here is what can be done. XML almost didn't change, I just removed image Layout Options
<ContentPage.Content>
<ScrollView>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center" Margin="10,10,10,10">
<Label Margin="10,10,10,10" Text="How to connect to VPN." HorizontalOptions="Center" />
<Label Margin="10,10,10,10" Text="If you have a corporate notebook, look for the Cisco AnyConnect application. Either in your start menu, on your desktop, or in your taskbar." />
<Image x:Name="imgVPN1" Margin="10,10,10,10" />
<Label Margin="10,10,10,10" Text="Select your region and press the Connect button." />
</StackLayout>
</ScrollView>
</ContentPage.Content>
After implementing everything in relative layout which also was not simple (I have the code if anybody needs it let me know) I found easier way. The key point is that image doesn't scale correctly and occupies too much space in height. But we know the size ratio of this image so we can use it. In the code we need to override OnSizeAllocated because in constructor the width is unknown yet. Then it's easy
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
imgVPN1.WidthRequest = width;
imgVPN1.HeightRequest = width / 2.152; //given that image is 411 x 191
}
You could use other width than page with if you want. For example you could use stack layout width to consider margins for more accuracy but this is already tuning. Or you actually could use the image width itself like that
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
double needHeight=imgVPN1.Width / 2.152;
if (imgVPN1.Height != needHeight)
imgVPN1.HeightRequest = needHeight;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With