Xamarin.Forms 단추

Download Sample 샘플 다운로드

단추는 특정 작업을 수행하도록 애플리케이션을 지시하는 탭 또는 클릭에 응답합니다.

Button 모든 항목에서 Xamarin.Forms가장 기본적인 대화형 컨트롤입니다. Button 일반적으로 명령을 나타내는 짧은 텍스트 문자열을 표시하지만 비트맵 이미지 또는 텍스트와 이미지의 조합을 표시할 수도 있습니다. 사용자가 손가락으로 누르 Button 거나 마우스로 클릭하여 해당 명령을 시작합니다.

아래에 설명된 대부분의 항목은 ButtonDemos 샘플의 페이지에 해당합니다 .

처리 단추 클릭

ButtonClicked 사용자가 손가락이나 마우스 포인터로 탭할 Button 때 발생하는 이벤트를 정의합니다. 이 이벤트는 손가락 또는 마우스 단추가 표면에서 해제될 때 발생합니다 Button. Button 탭에 응답하려면 true 해당 IsEnabled 속성이 설정되어 있어야 합니다.

ButtonDemos 샘플의 기본 단추 클릭 페이지는 XAML에서 인스턴스화 Button 하고 해당 Clicked 이벤트를 처리하는 방법을 보여 줍니다. BasicButtonClickPage.xaml 파일에는 a LabelButtona StackLayout 가 모두 포함됩니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.BasicButtonClickPage"
             Title="Basic Button Click">
    <StackLayout>

        <Label x:Name="label"
               Text="Click the Button below"
               FontSize="Large"
               VerticalOptions="CenterAndExpand"
               HorizontalOptions="Center" />

        <Button Text="Click to Rotate Text!"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="Center"
                Clicked="OnButtonClicked" />

    </StackLayout>
</ContentPage>

허용되는 Button 모든 공간을 차지하는 경향이 있습니다. 예를 들어 속성을 Button 다른 FillButton 값으로 설정 HorizontalOptions 하지 않으면 해당 부모의 전체 너비를 차지합니다.

기본적으로 Button 직사각형이지만 아래 섹션 단추 모양에 설명된 대로 속성을 사용하여 CornerRadius 둥근 모서리를 제공할 수 있습니다.

Text 속성은 Button에 나타나는 텍스트를 지정합니다. 이벤트는 Clicked 이름이 OnButtonClicked지정된 이벤트 처리기로 설정됩니다. 이 처리기는 코드 숨김 파일에 BasicButtonClickPage.xaml.cs.

public partial class BasicButtonClickPage : ContentPage
{
    public BasicButtonClickPage ()
    {
        InitializeComponent ();
    }

    async void OnButtonClicked(object sender, EventArgs args)
    {
        await label.RelRotateTo(360, 1000);
    }
}

Button을 탭하면 OnButtonClicked 메서드가 실행됩니다. 인수는 sender 이 이벤트를 담당하는 개체입니다 Button . 이를 사용하여 개체에 Button 액세스하거나 동일한 Clicked 이벤트를 공유하는 여러 Button 개체를 구분할 수 있습니다.

이 특정 Clicked 처리기는 360도를 1000밀리초 단위로 회전하는 Label 애니메이션 함수를 호출합니다. 다음은 iOS 및 Android 디바이스 및 Windows 10 데스크톱에서 UWP(유니버설 Windows 플랫폼) 애플리케이션으로 실행되는 프로그램입니다.

Basic Button Click

OnButtonClicked 이벤트 처리기 내에서 사용되므로 메서드에 한정자가 await 포함 async 됩니다. Clicked 이벤트 처리기는 처리기의 본문에서 async 사용하는 await경우에만 한정자가 필요합니다.

각 플랫폼은 고유한 방식으로 렌더링합니다 Button . 단추 모양 섹션에서 색을 설정하고 더 많은 사용자 지정 모양에 테두리를 Button 표시하도록 하는 방법을 볼 수 있습니다. Button는 인터페이스를 IFontElement 구현하므로 , FontSizeFontAttributes 속성이 포함됩니다FontFamily.

코드에서 단추 만들기

XAML에서 인스턴스화하는 Button 것이 일반적이지만 코드에서 만들 Button 수도 있습니다. 이는 애플리케이션이 루프를 사용하여 열거 가능한 데이터를 기반으로 여러 단추를 만들어야 하는 경우에 편리할 수 있습니다 foreach .

코드 단추 클릭 페이지에서는 기본 단추 클릭 페이지와 기능적으로 동일하지만 전적으로 C#에 있는 페이지를 만드는 방법을 보여 줍니다.

public class CodeButtonClickPage : ContentPage
{
    public CodeButtonClickPage ()
    {
        Title = "Code Button Click";

        Label label = new Label
        {
            Text = "Click the Button below",
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            VerticalOptions = LayoutOptions.CenterAndExpand,
            HorizontalOptions = LayoutOptions.Center
        };

        Button button = new Button
        {
            Text = "Click to Rotate Text!",
            VerticalOptions = LayoutOptions.CenterAndExpand,
            HorizontalOptions = LayoutOptions.Center
        };
        button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);

        Content = new StackLayout
        {
            Children =
            {
                label,
                button
            }
        };
    }
}

모든 작업은 클래스의 생성자에서 수행됩니다. Clicked 처리기는 단 하나의 문이므로 매우 간단하게 이벤트에 연결할 수 있습니다.

button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);

물론 이벤트 처리기를 별도의 메서드(기본 단추 클릭OnButtonClick 메서드처럼)로 정의하고 해당 메서드를 이벤트에 연결할 수도 있습니다.

button.Clicked += OnButtonClicked;

단추 사용 안 림

애플리케이션이 특정 클릭이 유효한 작업이 아닌 특정 Button 상태에 있는 경우가 있습니다. 이러한 경우 Button 해당 IsEnabled 속성을 false.로 설정하여 사용하지 않도록 설정해야 합니다. 클래식 예제는 Entry 파일 열기 ButtonButton 와 함께 파일 이름에 대한 컨트롤입니다. 일부 텍스트를 입력Entry한 경우에만 사용하도록 설정해야 합니다. 데이터 트리거 문서에 표시된 것처럼 이 작업에 사용할 DataTrigger 수 있습니다.

명령 인터페이스 사용

애플리케이션이 이벤트를 처리하지 않고 탭에 응답할 ButtonClicked 있습니다. 명령 Button 또는 명령 인터페이스라는 대체 알림 메커니즘을 구현합니다. 이 속성은 다음 두 가지 속성으로 구성됩니다.

이 방법은 데이터 바인딩과 관련하여 특히 MVVM(Model-View-ViewModel) 아키텍처를 구현할 때 적합합니다. 이러한 항목은 데이터 바인딩, 데이터 바인딩에서 MVVM 및 MVVM으로의 문서에서 설명합니다.

MVVM 애플리케이션에서 viewmodel은 데이터 바인딩을 사용하여 XAML Button 요소에 연결된 형식 ICommand 의 속성을 정의합니다. Xamarin.Forms또한 인터페이스를 Command 구현 ICommand 하고 Command<T> viewmodel이 형식ICommand의 속성을 정의하는 데 도움이 되는 클래스를 정의하고 클래스를 정의합니다.

명령 인터페이스 문서에 명령이 자세히 설명되어 있지만 ButtonDemos 샘플의 기본 단추 명령 페이지에는 기본 방법이 표시됩니다.

클래스는 CommandDemoViewModel 명명된 형식의 속성과 다음과 DivideBy2CommandMultiplyBy2Command 같은 Number두 가지 형식 doubleICommand 속성을 정의하는 매우 간단한 viewmodel입니다.

class CommandDemoViewModel : INotifyPropertyChanged
{
    double number = 1;

    public event PropertyChangedEventHandler PropertyChanged;

    public CommandDemoViewModel()
    {
        MultiplyBy2Command = new Command(() => Number *= 2);

        DivideBy2Command = new Command(() => Number /= 2);
    }

    public double Number
    {
        set
        {
            if (number != value)
            {
                number = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Number"));
            }
        }
        get
        {
            return number;
        }
    }

    public ICommand MultiplyBy2Command { private set; get; }

    public ICommand DivideBy2Command { private set; get; }
}

ICommand 속성은 형식 Command의 두 개체를 사용하여 클래스의 생성자에서 초기화됩니다. 생성자에는 Command 속성을 두 배로 늘리거나 반으로 줄이는 작은 함수(생성자 인수라고 함 execute )가 포함됩니다 Number .

BasicButtonCommand.xaml 파일은 해당 BindingContext 파일을 인스턴스로 CommandDemoViewModel설정합니다. Label 요소와 두 Button 요소는 다음의 세 가지 속성에 대한 바인딩을 포함합니다.CommandDemoViewModel

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ButtonDemos"
             x:Class="ButtonDemos.BasicButtonCommandPage"
             Title="Basic Button Command">

    <ContentPage.BindingContext>
        <local:CommandDemoViewModel />
    </ContentPage.BindingContext>

    <StackLayout>
        <Label Text="{Binding Number, StringFormat='Value is now {0}'}"
               FontSize="Large"
               VerticalOptions="CenterAndExpand"
               HorizontalOptions="Center" />

        <Button Text="Multiply by 2"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="Center"
                Command="{Binding MultiplyBy2Command}" />

        <Button Text="Divide by 2"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="Center"
                Command="{Binding DivideBy2Command}" />
    </StackLayout>
</ContentPage>

Button 요소를 탭하면 명령이 실행되고 숫자가 값을 변경합니다.

Basic Button Command

처리기에 비해 Clicked 이 방법의 장점은 이 페이지의 기능과 관련된 모든 논리가 코드 숨김 파일이 아닌 viewmodel에 있으므로 비즈니스 논리에서 사용자 인터페이스를 더 잘 분리할 수 있다는 것입니다.

개체가 요소의 CommandButton 사용 및 비활성화를 제어할 수도 있습니다. 예를 들어 숫자 값의 범위를 2 10에서 2-10 사이로 제한하려는 경우를 가정해 보겠습니다. 사용하도록 설정해야 하는 경우 반환 true 되는 생성자(인수라고 함canExecute)에 다른 함수를 Button 추가할 수 있습니다. 생성자에 대한 수정 CommandDemoViewModel 사항은 다음과 같습니다.

class CommandDemoViewModel : INotifyPropertyChanged
{
    ···
    public CommandDemoViewModel()
    {
        MultiplyBy2Command = new Command(
            execute: () =>
            {
                Number *= 2;
                ((Command)MultiplyBy2Command).ChangeCanExecute();
                ((Command)DivideBy2Command).ChangeCanExecute();
            },
            canExecute: () => Number < Math.Pow(2, 10));

        DivideBy2Command = new Command(
            execute: () =>
            {
                Number /= 2;
                ((Command)MultiplyBy2Command).ChangeCanExecute();
                ((Command)DivideBy2Command).ChangeCanExecute();
            },
            canExecute: () => Number > Math.Pow(2, -10));
    }
    ···
}

메서드를 ChangeCanExecute 호출 canExecute 하고 메서드를 사용하지 않도록 설정할지 여부를 결정할 수 있도록 Command 메서드에 대한 호출이 Button 필요합니다.Command 이 코드가 변경되면 숫자가 한도 Button 에 도달하면 사용할 수 없습니다.

Basic Button Command - Modified

둘 이상의 Button 요소가 동일한 ICommand 속성에 바인딩될 수 있습니다. 의 Button 속성을 Button사용하여 CommandParameter 요소를 구분할 수 있습니다. 이 경우 제네릭 Command<T> 클래스를 사용하려고 합니다. CommandParameter 그런 다음 개체가 및 canExecute 메서드에 execute 인수로 전달됩니다. 이 기술은 명령 인터페이스 문서의 기본 명령 섹션에 자세히 나와 있습니다.

ButtonDemos 샘플은 클래스에서도 MainPage 이 기술을 사용합니다. MainPage.xaml 파일에는 샘플의 각 페이지에 대한 a Button 가 포함되어 있습니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ButtonDemos"
             x:Class="ButtonDemos.MainPage"
             Title="Button Demos">
    <ScrollView>
        <FlexLayout Direction="Column"
                    JustifyContent="SpaceEvenly"
                    AlignItems="Center">

            <Button Text="Basic Button Click"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:BasicButtonClickPage}" />

            <Button Text="Code Button Click"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:CodeButtonClickPage}" />

            <Button Text="Basic Button Command"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:BasicButtonCommandPage}" />

            <Button Text="Press and Release Button"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:PressAndReleaseButtonPage}" />

            <Button Text="Button Appearance"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:ButtonAppearancePage}" />

            <Button Text="Toggle Button Demo"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:ToggleButtonDemoPage}" />

            <Button Text="Image Button Demo"
                    Command="{Binding NavigateCommand}"
                    CommandParameter="{x:Type local:ImageButtonDemoPage}" />

        </FlexLayout>
    </ScrollView>
</ContentPage>

Button 속성은 Command 명명 NavigateCommand된 속성에 바인딩되어 있으며 CommandParameter 프로젝트의 페이지 클래스 중 하나에 해당하는 개체로 설정 Type 됩니다.

해당 NavigateCommand 속성은 형식 ICommand 이며 코드 숨김 파일에 정의됩니다.

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        NavigateCommand = new Command<Type>(async (Type pageType) =>
        {
            Page page = (Page)Activator.CreateInstance(pageType);
            await Navigation.PushAsync(page);
        });

        BindingContext = this;
    }

    public ICommand NavigateCommand { private set; get; }
}

생성자는 XAML 파일에 설정된 개체의 CommandParameter 형식이므로 개체 Type 로 속성을 Command<Type> 초기화 NavigateCommand 합니다. 즉, 메서드에 executeCommandParameter 개체에 해당하는 형식 Type 의 인수가 있습니다. 함수는 페이지를 인스턴스화한 다음 페이지로 이동합니다.

생성자는 자체적으로 설정 BindingContext 하여 종료됩니다. XAML 파일의 속성이 속성에 바인딩되는 데 NavigateCommand 필요합니다.

단추 누르기 및 해제

Clicked 이벤트 외에도 ButtonPressedReleased 이벤트도 정의합니다. 이 Pressed 이벤트는 손가락을 눌렀 Button거나 포인터를 포인터 위에 놓아 마우스 단추를 누를 때 발생합니다 Button. 이 Released 이벤트는 손가락 또는 마우스 단추를 놓을 때 발생합니다. 일반적으로 Clicked 이벤트도 이벤트와 Released 동시에 발생하지만 손가락 또는 마우스 포인터가 놓 Clicked 이기 전에 표면 Button 에서 멀어지면 이벤트가 발생하지 않을 수 있습니다.

Pressed 이벤트 및 Released 이벤트는 자주 사용되지 않지만 누름 및 릴리스 단추 페이지에 설명된 것처럼 특별한 용도로 사용할 수 있습니다. XAML 파일에는 LabelButton 및 이벤트에 연결된 PressedReleased 처리기가 포함됩니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.PressAndReleaseButtonPage"
             Title="Press and Release Button">
    <StackLayout>

        <Label x:Name="label"
               Text="Press and hold the Button below"
               FontSize="Large"
               VerticalOptions="CenterAndExpand"
               HorizontalOptions="Center" />

        <Button Text="Press to Rotate Text!"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="Center"
                Pressed="OnButtonPressed"
                Released="OnButtonReleased" />

    </StackLayout>
</ContentPage>

코드 숨김 파일은 이벤트가 발생할 때 Pressed 애니메이션 Label 효과를 주지만 이벤트가 발생할 때 회전을 Released 일시 중단합니다.

public partial class PressAndReleaseButtonPage : ContentPage
{
    bool animationInProgress = false;
    Stopwatch stopwatch = new Stopwatch();

    public PressAndReleaseButtonPage ()
    {
        InitializeComponent ();
    }

    void OnButtonPressed(object sender, EventArgs args)
    {
        stopwatch.Start();
        animationInProgress = true;

        Device.StartTimer(TimeSpan.FromMilliseconds(16), () =>
        {
            label.Rotation = 360 * (stopwatch.Elapsed.TotalSeconds % 1);

            return animationInProgress;
        });
    }

    void OnButtonReleased(object sender, EventArgs args)
    {
        animationInProgress = false;
        stopwatch.Stop();
    }
}

그 결과 손가락이 Label 접촉 Button하는 동안만 회전하고 손가락이 놓일 때 중지됩니다.

Press and Release Button

이러한 종류의 동작에는 게임에 대한 응용 프로그램이 있습니다. 손가락을 붙들 Button 면 화면의 개체가 특정 방향으로 움직일 수 있습니다.

단추 모양

모양 Button 에 영향을 주는 여러 속성을 상속하거나 정의합니다.

  • TextColor은 텍스트의 색입니다.Button
  • BackgroundColor 는 해당 텍스트의 배경색입니다.
  • BorderColor 는 주변 영역의 색입니다. Button
  • FontFamily 는 텍스트에 사용되는 글꼴 패밀리입니다.
  • FontSize 는 텍스트의 크기입니다.
  • FontAttributes 텍스트가 기울임을 나타내거나 굵게 표시합니다.
  • BorderWidth 은 테두리의 너비입니다.
  • CornerRadius 는 다음의 모퉁이 반경입니다. Button
  • CharacterSpacing 는 텍스트 문자 사이의 간격입니다 Button .
  • TextTransform 는 텍스트의 대/소문자를 결정합니다 Button .

참고 항목

클래스에는 ButtonMargin .의 Button레이아웃 동작을 제어하는 속성도 있습니다Padding. 자세한 내용은 여백 및 패딩을 참조하세요.

이러한 속성 중 6개(제외 FontFamilyFontAttributes)의 효과는 단추 모양 페이지에 설명되어 있습니다. 다른 속성인 Image는 단추가 있는 비트맵 사용 섹션에서 설명합니다.

단추 모양 페이지의 모든 보기 및 데이터 바인딩은 XAML 파일에 정의됩니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ButtonDemos"
             x:Class="ButtonDemos.ButtonAppearancePage"
             Title="Button Appearance">
    <StackLayout>
        <Button x:Name="button"
                Text="Button"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="Center"
                TextColor="{Binding Source={x:Reference textColorPicker},
                                    Path=SelectedItem.Color}"
                BackgroundColor="{Binding Source={x:Reference backgroundColorPicker},
                                          Path=SelectedItem.Color}"
                BorderColor="{Binding Source={x:Reference borderColorPicker},
                                      Path=SelectedItem.Color}" />

        <StackLayout BindingContext="{x:Reference button}"
                     Padding="10">

            <Slider x:Name="fontSizeSlider"
                    Maximum="48"
                    Minimum="1"
                    Value="{Binding FontSize}" />

            <Label Text="{Binding Source={x:Reference fontSizeSlider},
                                  Path=Value,
                                  StringFormat='FontSize = {0:F0}'}"
                   HorizontalTextAlignment="Center" />

            <Slider x:Name="borderWidthSlider"
                    Minimum="-1"
                    Maximum="12"
                    Value="{Binding BorderWidth}" />

            <Label Text="{Binding Source={x:Reference borderWidthSlider},
                                  Path=Value,
                                  StringFormat='BorderWidth = {0:F0}'}"
                   HorizontalTextAlignment="Center" />

            <Slider x:Name="cornerRadiusSlider"
                    Minimum="-1"
                    Maximum="24"
                    Value="{Binding CornerRadius}" />

            <Label Text="{Binding Source={x:Reference cornerRadiusSlider},
                                  Path=Value,
                                  StringFormat='CornerRadius = {0:F0}'}"
                   HorizontalTextAlignment="Center" />

            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Grid.Resources>
                    <Style TargetType="Label">
                        <Setter Property="VerticalOptions" Value="Center" />
                    </Style>
                </Grid.Resources>

                <Label Text="Text Color:"
                       Grid.Row="0" Grid.Column="0" />

                <Picker x:Name="textColorPicker"
                        ItemsSource="{Binding Source={x:Static local:NamedColor.All}}"
                        ItemDisplayBinding="{Binding FriendlyName}"
                        SelectedIndex="0"
                        Grid.Row="0" Grid.Column="1" />

                <Label Text="Background Color:"
                       Grid.Row="1" Grid.Column="0" />

                <Picker x:Name="backgroundColorPicker"
                        ItemsSource="{Binding Source={x:Static local:NamedColor.All}}"
                        ItemDisplayBinding="{Binding FriendlyName}"
                        SelectedIndex="0"
                        Grid.Row="1" Grid.Column="1" />

                <Label Text="Border Color:"
                       Grid.Row="2" Grid.Column="0" />

                <Picker x:Name="borderColorPicker"
                        ItemsSource="{Binding Source={x:Static local:NamedColor.All}}"
                        ItemDisplayBinding="{Binding FriendlyName}"
                        SelectedIndex="0"
                        Grid.Row="2" Grid.Column="1" />
            </Grid>
        </StackLayout>
    </StackLayout>
</ContentPage>

페이지 맨 위에는 Button 페이지 아래쪽의 요소에 Picker 바인딩된 세 Color 가지 속성이 있습니다. 요소의 Picker 항목은 프로젝트에 포함된 클래스의 NamedColor 색입니다. 세 Slider 가지 요소에는 에 대한 FontSizeBorderWidth양방향 바인딩과 CornerRadius 의 속성이 포함됩니다Button.

이 프로그램을 사용하면 다음 모든 속성의 조합을 실험할 수 있습니다.

Button Appearance

테두리를 Button 보려면 다른 값과 BorderWidth 양수 값으로 설정 BorderColorDefault해야 합니다.

iOS에서는 큰 테두리 너비가 내부 Button 로 침입하여 텍스트 표시를 방해한다는 것을 알 수 있습니다. iOS Button에서 테두리를 사용하도록 선택하는 경우 표시 유형을 유지하기 위해 공백으로 속성을 시작하고 종료 Text 하려고 할 수 있습니다.

UWP에서 높이의 Button 절반을 초과하는 값을 선택하면 CornerRadius 예외가 발생합니다.

단추 시각적 상태

ButtonPressedVisualState 에는 사용자가 누를 때 시각적 변경을 Button 시작하는 데 사용할 수 있는 기능이 있습니다.

다음 XAML 예제에서는 상태에 대한 Pressed 시각적 상태를 정의하는 방법을 보여줍니다.

<Button Text="Click me!"
        ...>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal">
                <VisualState.Setters>
                    <Setter Property="Scale"
                            Value="1" />
                </VisualState.Setters>
            </VisualState>

            <VisualState x:Name="Pressed">
                <VisualState.Setters>
                    <Setter Property="Scale"
                            Value="0.8" />
                </VisualState.Setters>
            </VisualState>

        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Button>

PressedVisualState 눌렀을 Button 때 해당 Scale 속성이 기본값 1에서 0.8로 변경되도록 지정합니다. 이 NormalVisualState 속성은 정상 상태일 때 Button 해당 Scale 속성이 1로 설정되도록 지정합니다. 따라서 전반적인 효과는 누를 때 Button 크기가 약간 더 작게 조정되고 Button 릴리스되면 기본 크기로 다시 크기가 조정된다는 것입니다.

시각적 상태에 대한 자세한 내용은 Visual State Manager를 참조 Xamarin.Forms 하세요.

토글 단추 만들기

온-오프 스위치처럼 작동하도록 서브클래스를 Button 수행할 수 있습니다. 단추를 한 번 탭하여 단추를 토글하고 다시 탭하여 해제합니다.

다음 ToggleButton 클래스는 명명된 새 이벤트와 명명 ToggledIsToggled된 부울 속성을 파생 Button 하고 정의합니다. 이러한 속성은 다음에서 정의한 것과 동일한 두 가지 속성입니다 Xamarin.FormsSwitch.

class ToggleButton : Button
{
    public event EventHandler<ToggledEventArgs> Toggled;

    public static BindableProperty IsToggledProperty =
        BindableProperty.Create("IsToggled", typeof(bool), typeof(ToggleButton), false,
                                propertyChanged: OnIsToggledChanged);

    public ToggleButton()
    {
        Clicked += (sender, args) => IsToggled ^= true;
    }

    public bool IsToggled
    {
        set { SetValue(IsToggledProperty, value); }
        get { return (bool)GetValue(IsToggledProperty); }
    }

    protected override void OnParentSet()
    {
        base.OnParentSet();
        VisualStateManager.GoToState(this, "ToggledOff");
    }

    static void OnIsToggledChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ToggleButton toggleButton = (ToggleButton)bindable;
        bool isToggled = (bool)newValue;

        // Fire event
        toggleButton.Toggled?.Invoke(toggleButton, new ToggledEventArgs(isToggled));

        // Set the visual state
        VisualStateManager.GoToState(toggleButton, isToggled ? "ToggledOn" : "ToggledOff");
    }
}

ToggleButton 생성자는 속성 값을 변경할 수 있도록 이벤트에 처리기를 Clicked 연결합니다IsToggled. 이 메서드는 OnIsToggledChanged 이벤트를 발생합니다 Toggled .

메서드의 OnIsToggledChanged 마지막 줄은 두 개의 텍스트 문자열 "ToggledOn" 및 "ToggledOff"를 사용하여 정적 VisualStateManager.GoToState 메서드를 호출합니다. Visual State Manager 문서에서 Xamarin.Forms 이 메서드와 애플리케이션이 시각적 상태에 응답하는 방법을 읽을 수 있습니다.

호출하기 VisualStateManager.GoToState때문에 ToggleButton 클래스 자체는 상태에 따라 IsToggled 단추의 모양을 변경하는 추가 기능을 포함할 필요가 없습니다. 이는 을 호스트하는 XAML의 책임입니다 ToggleButton.

토글 단추 데모 페이지에는 시각적 상태를 기반으로 단추를 설정하는 TextBackgroundColorVisual State Manager 태그를 TextColor 비롯한 두 개의 인스턴스ToggleButton가 포함됩니다.

<?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:ButtonDemos"
             x:Class="ButtonDemos.ToggleButtonDemoPage"
             Title="Toggle Button Demo">

    <ContentPage.Resources>
        <Style TargetType="local:ToggleButton">
            <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            <Setter Property="HorizontalOptions" Value="Center" />
        </Style>
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">
        <local:ToggleButton Toggled="OnItalicButtonToggled">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup Name="ToggleStates">
                    <VisualState Name="ToggledOff">
                        <VisualState.Setters>
                            <Setter Property="Text" Value="Italic Off" />
                            <Setter Property="BackgroundColor" Value="#C0C0C0" />
                            <Setter Property="TextColor" Value="Black" />
                        </VisualState.Setters>
                    </VisualState>

                    <VisualState Name="ToggledOn">
                        <VisualState.Setters>
                            <Setter Property="Text" Value=" Italic On " />
                            <Setter Property="BackgroundColor" Value="#404040" />
                            <Setter Property="TextColor" Value="White" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
        </local:ToggleButton>

        <local:ToggleButton Toggled="OnBoldButtonToggled">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup Name="ToggleStates">
                    <VisualState Name="ToggledOff">
                        <VisualState.Setters>
                            <Setter Property="Text" Value="Bold Off" />
                            <Setter Property="BackgroundColor" Value="#C0C0C0" />
                            <Setter Property="TextColor" Value="Black" />
                        </VisualState.Setters>
                    </VisualState>

                    <VisualState Name="ToggledOn">
                        <VisualState.Setters>
                            <Setter Property="Text" Value=" Bold On " />
                            <Setter Property="BackgroundColor" Value="#404040" />
                            <Setter Property="TextColor" Value="White" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
        </local:ToggleButton>

        <Label x:Name="label"
               Text="Just a little passage of some sample text that can be formatted in italic or boldface by toggling the two buttons."
               FontSize="Large"
               HorizontalTextAlignment="Center"
               VerticalOptions="CenterAndExpand" />

    </StackLayout>
</ContentPage>

Toggled 이벤트 처리기는 코드 숨김 파일에 있습니다. 단추의 상태에 따라 속성을 Label 설정 FontAttributes 해야 합니다.

public partial class ToggleButtonDemoPage : ContentPage
{
    public ToggleButtonDemoPage ()
    {
        InitializeComponent ();
    }

    void OnItalicButtonToggled(object sender, ToggledEventArgs args)
    {
        if (args.Value)
        {
            label.FontAttributes |= FontAttributes.Italic;
        }
        else
        {
            label.FontAttributes &= ~FontAttributes.Italic;
        }
    }

    void OnBoldButtonToggled(object sender, ToggledEventArgs args)
    {
        if (args.Value)
        {
            label.FontAttributes |= FontAttributes.Bold;
        }
        else
        {
            label.FontAttributes &= ~FontAttributes.Bold;
        }
    }
}

iOS, Android 및 UWP에서 실행되는 프로그램은 다음과 같습니다.

Toggle Button Demo

단추에 비트맵 사용

클래스는 Button 단독으로 또는 텍스트와 함께 비트맵 이미지를 Button표시할 수 있는 속성을 정의 ImageSource 합니다. 텍스트와 이미지를 정렬하는 방법을 지정할 수도 있습니다.

속성은 ImageSource 형식 ImageSource입니다. 즉, 파일, 포함된 리소스, URI 또는 스트림에서 비트맵을 로드할 수 있습니다.

참고 항목

애니메이션 GIF는 Button 로드할 수 있지만 GIF의 첫 번째 프레임만 표시합니다.

지원되는 Xamarin.Forms 각 플랫폼에서는 애플리케이션이 실행될 수 있는 다양한 디바이스의 다양한 픽셀 해상도를 위해 이미지를 여러 크기로 저장할 수 있습니다. 이러한 여러 비트맵은 운영 체제에서 디바이스의 비디오 표시 해상도에 가장 적합한 항목을 선택할 수 있는 방식으로 명명되거나 저장됩니다.

비트맵 Button의 경우 원하는 크기에 따라 일반적으로 32~64개의 디바이스 독립적 단위가 가장 좋습니다. 이 예제에 사용된 이미지는 48개의 디바이스 독립적 단위 크기를 기반으로 합니다.

iOS 프로젝트에서 Resources 폴더에는 다음 이미지의 세 가지 크기가 포함됩니다.

  • /Resources/MonkeyFace.png로 저장된 48픽셀 정사각형 비트맵
  • /Resource/로 저장된 96픽셀 정사각형 비트맵MonkeyFace@2x.png
  • /Resource/로 저장된 144픽셀 정사각형 비트맵MonkeyFace@3x.png

세 비트맵 모두 BundleResource빌드 동작이 주어졌습니다.

Android 프로젝트의 경우 비트맵은 모두 이름이 같지만 Resources 폴더의 다른 하위 폴더에 저장됩니다.

  • /Resources/drawable-hdpi/MonkeyFace.png로 저장된 72픽셀 정사각형 비트맵
  • /Resources/drawable-xhdpi/MonkeyFace.png로 저장된 96픽셀 정사각형 비트맵
  • /Resources/drawable-xxhdpi/MonkeyFace.png로 저장된 144픽셀 정사각형 비트맵
  • /Resources/drawable-xxxhdpi/MonkeyFace.png로 저장된 192픽셀 정사각형 비트맵

여기에는 AndroidResource빌드 작업이 제공되었습니다.

UWP 프로젝트에서 비트맵은 프로젝트의 아무 곳에나 저장할 수 있지만 일반적으로 사용자 지정 폴더 또는 Assets 기존 폴더에 저장됩니다. UWP 프로젝트에는 다음 비트맵이 포함됩니다.

  • /Assets/MonkeyFace.scale-100.png로 저장된 48픽셀 정사각형 비트맵
  • /Assets/MonkeyFace.scale-200.png로 저장된 96픽셀 정사각형 비트맵
  • /Assets/MonkeyFace.scale-400.png로 저장된 192픽셀 정사각형 비트맵

모두 콘텐츠 빌드 작업을 받았습니다.

Text 속성을 Button사용하여 ContentLayout 속성과 ImageSource 속성을 정렬하는 Button 방법을 지정할 수 있습니다. 이 속성은 포함된 클래스Button인 형식ButtonContentLayout입니다. 생성자에두 개의 인수가 있습니다.

  • 열거형의 ImagePosition 멤버: Left, Top, Right또는 Bottom 비트맵이 텍스트를 기준으로 표시되는 방식을 나타냅니다.
  • double 비트맵과 텍스트 사이의 간격에 대한 값입니다.

기본값은 10개 단위입니다 Left . 명명 Position 된 두 개의 읽기 전용 속성 ButtonContentLayoutSpacing 해당 속성의 값을 제공합니다.

코드에서 다음과 같이 속성을 만들고 Button 설정할 ContentLayout 수 있습니다.

Button button = new Button
{
    Text = "button text",
    ImageSource = new FileImageSource
    {
        File = "image filename"
    },
    ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Right, 20)
};

XAML에서는 열거형 멤버 또는 간격만 지정하거나 쉼표로 구분된 순서로 둘 다 지정해야 합니다.

<Button Text="button text"
        ImageSource="image filename"
        ContentLayout="Right, 20" />

이미지 단추 데모 페이지에서는 iOS, Android 및 UWP 비트맵 파일의 다른 파일 이름을 지정하는 데 사용합니다OnPlatform. 각 플랫폼에 대해 동일한 파일 이름을 사용하고 사용하지 OnPlatform않으려면 프로젝트의 루트 디렉터리에 UWP 비트맵을 저장해야 합니다.

이미지 단추 데모 페이지의 첫 번째는 Button속성을 설정하지만 속성은 Text 설정 Image 하지 않습니다.

<Button>
    <Button.ImageSource>
        <OnPlatform x:TypeArguments="ImageSource">
            <On Platform="iOS, Android" Value="MonkeyFace.png" />
            <On Platform="UWP" Value="Assets/MonkeyFace.png" />
        </OnPlatform>
    </Button.ImageSource>
</Button>

UWP 비트맵이 프로젝트의 루트 디렉터리에 저장되는 경우 이 태그를 상당히 간소화할 수 있습니다.

<Button ImageSource="MonkeyFace.png" />

ImageButtonDemo.xaml 파일에서 반복적인 태그를 많이 방지하려면 속성을 설정 ImageSource 하기 위해 암시적 Style 태그도 정의됩니다. 이는 Style 5개의 다른 Button 요소에 자동으로 적용됩니다. 전체 XAML 파일은 다음과 같습니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.ImageButtonDemoPage">

    <FlexLayout Direction="Column"
                JustifyContent="SpaceEvenly"
                AlignItems="Center">

        <FlexLayout.Resources>
            <Style TargetType="Button">
                <Setter Property="ImageSource">
                    <OnPlatform x:TypeArguments="ImageSource">
                        <On Platform="iOS, Android" Value="MonkeyFace.png" />
                        <On Platform="UWP" Value="Assets/MonkeyFace.png" />
                    </OnPlatform>
                </Setter>
            </Style>
        </FlexLayout.Resources>

        <Button>
            <Button.ImageSource>
                <OnPlatform x:TypeArguments="ImageSource">
                    <On Platform="iOS, Android" Value="MonkeyFace.png" />
                    <On Platform="UWP" Value="Assets/MonkeyFace.png" />
                </OnPlatform>
            </Button.ImageSource>
        </Button>

        <Button Text="Default" />

        <Button Text="Left - 10"
                ContentLayout="Left, 10" />

        <Button Text="Top - 10"
                ContentLayout="Top, 10" />

        <Button Text="Right - 20"
                ContentLayout="Right, 20" />

        <Button Text="Bottom - 20"
                ContentLayout="Bottom, 20" />
    </FlexLayout>
</ContentPage>

마지막 네 Button 요소는 속성을 사용하여 ContentLayout 텍스트와 비트맵의 위치와 간격을 지정합니다.

Image Button Demo

이제 이벤트를 처리 Button 하고 모양을 변경할 수 있는 다양한 방법을 살펴보았습니다 Button .