ぴーさんログ

だいたいXamarin.Formsのブログ

【Xamarin.Forms】XAMLでViewの縦横比を一定に保つ

teratail.com

Teratailの"Xamarin Studioで幅は画面と同じ大きさ、高さが画面の幅に対して50%のViewを作りたい"(iOS)という質問に回答した時に、Aspect RatioのConstraint便利だなーと思ったのでXamarin.Formsでも同じようなことをやってみましょう。

C#でイベントハンドリングすれば実現できることは自明なので、XAMLで行いきます。

Bindingで縦横サイズを同じにすることができるので、ここにConverterをかませて比率を変えてやります。

こんな感じのConverterを定義、比率はConverterParameterで指定します。

using System;
using System.Globalization;
using Xamarin.Forms;

namespace XFApp34
{
    public class DoubleMultiplierConverter: IValueConverter
    {
        public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
        {
            double multiplier;

            if (!Double.TryParse (parameter as string, out multiplier))
                multiplier = 1;

            return multiplier * (double)value;
        }

        public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException ();
        }
    }
}

使い方はこんな感じ。

<?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:XFApp34"
             x:Class="XFApp34.XFApp34Page">
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:DoubleMultiplierConverter x:Key="doubleMultiplier" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout VerticalOptions="Center">
        <BoxView x:Name="box"
                 Color="Lime"
                 HorizontalOptions="Center"
                 WidthRequest="100"
                 HeightRequest="{Binding Width, Source={x:Reference box},
                  Converter={StaticResource doubleMultiplier}, ConverterParameter=0.5}"
                 />
        <Slider Minimum="0" Maximum="500" Value="{Binding WidthRequest, Source={x:Reference box}, Mode=TwoWay}" />
        <Label Text="{Binding Width, Source={x:Reference box}, StringFormat='Width:{0:f3}'}" HorizontalOptions="Center" />
        <Label Text="{Binding Height, Source={x:Reference box}, StringFormat='Height:{0:f3}'}" HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

x:Referenceで自分自身をBindingのSourceにするのがポイント。

f:id:ticktack623:20160820122633g:plain

はいできました。