Freigeben über


Xamarin.Forms Knopf

Die Schaltfläche antwortet auf ein Tippen oder Klicken, das eine Anwendung angibt, um eine bestimmte Aufgabe auszuführen.

Dies Button ist das grundlegendste interaktive Steuerelement in allen Xamarin.Forms. In der Button Regel wird eine kurze Textzeichenfolge angezeigt, die einen Befehl angibt, kann aber auch ein Bitmapbild oder eine Kombination aus Text und einem Bild anzeigen. Der Benutzer drückt mit einem Finger oder Button klickt mit der Maus darauf, um diesen Befehl zu initiieren.

Behandeln von Schaltflächenklicks

Button definiert ein Clicked Ereignis, das ausgelöst wird, wenn der Benutzer mit einem Finger oder Mauszeiger auf den Button Finger tippt. Das Ereignis wird ausgelöst, wenn der Finger oder die Maustaste von der Oberfläche der Button. Die Button Eigenschaft muss so festgelegt true seinIsEnabled, dass sie auf Tippen reagiert.

Auf der Seite "Schaltflächenklick " im Beispiel wird veranschaulicht, wie sie ein Button In-XAML-Code instanziieren und das Clicked Ereignis behandeln. Die Datei "BasicButtonClickPage.xaml" enthält sowohl eine Label als auch eine StackLayout Button:

<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>

Die Button tendiert dazu, den gesamten Platz zu belegen, der dafür zulässig ist. Wenn Sie z. B. die HorizontalOptions Eigenschaft Button nicht auf einen anderen FillWert als festlegen, belegt die Button gesamte Breite des übergeordneten Elements.

Standardmäßig ist das Button Rechteck rechteckig, sie kann jedoch abgerundet werden, indem Sie die CornerRadius Eigenschaft verwenden, wie im Abschnitt "Schaltflächendarstellung" beschrieben.

Die Text-Eigenschaft gibt den Text an, der auf der Button angezeigt wird. Das Ereignis Clicked wird auf einen Ereignishandler mit dem Namen OnButtonClicked festgelegt. Dieser Handler befindet sich in der CodeBehind-Datei BasicButtonClickPage.xaml.cs:

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

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

Wenn die Button angetippt wird, wird die OnButtonClicked-Methode ausgeführt. Das sender-Argument ist das Button-Objekt, das für dieses Ereignis verantwortlich ist. Sie können dies verwenden, um auf das Button-Objekt zuzugreifen oder zwischen mehreren Button-Objekten zu unterscheiden, die dasselbe Clicked-Ereignis gemeinsam nutzen.

Dieser spezielle Clicked Handler ruft eine Animationsfunktion auf, die die Label 360 Grad in 1000 Millisekunden dreht. Hier sehen Sie das Programm, das auf iOS- und Android-Geräten ausgeführt wird, und als Universelle Windows-Plattform(UWP)-Anwendung auf dem Windows 10-Desktop:

Schaltfläche

Beachten Sie, dass die OnButtonClicked Methode den async Modifizierer enthält, da await sie innerhalb des Ereignishandlers verwendet wird. Ein Clicked Ereignishandler erfordert den async Modifizierer nur, wenn der Textkörper des Handlers verwendet awaitwird.

Jede Plattform rendert die Button eigene spezifische Weise. Im Abschnitt "Schaltflächendarstellung" erfahren Sie, wie Sie Farben festlegen und den Button Rahmen für angepasste Darstellungen sichtbar machen. Buttonimplementiert die IFontElement Schnittstelle, sodass sie , FontSizeund FontAttributes Eigenschaften enthältFontFamily.

Erstellen einer Schaltfläche im Code

Es ist üblich, ein Button XAML-Code zu instanziieren, aber Sie können auch einen Button Code erstellen. Dies kann praktisch sein, wenn Ihre Anwendung mehrere Schaltflächen basierend auf Daten erstellen muss, die mit einer foreach Schleife aufgezählt werden können.

Auf der Seite "Schaltflächenklick code" wird veranschaulicht, wie Sie eine Seite erstellen, die funktionell der Klickseite der Standardschaltfläche entspricht, aber vollständig in 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
            }
        };
    }
}

Alles wird im Konstruktor der Klasse ausgeführt. Da der Clicked Handler nur eine Anweisung lang ist, kann er sehr einfach an das Ereignis angefügt werden:

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

Natürlich können Sie den Ereignishandler auch als separate Methode definieren (genau wie die OnButtonClick Methode in "Basic Button Click") und diese Methode an das Ereignis anfügen:

button.Clicked += OnButtonClicked;

Deaktivieren der Schaltfläche

Manchmal befindet sich eine Anwendung in einem bestimmten Zustand, in dem ein bestimmter Button Klick kein gültiger Vorgang ist. In solchen Fällen sollte Button deaktiviert werden, indem die zugehörige IsEnabled-Eigenschaft auf false festgelegt wird. Das klassische Beispiel ist ein Entry Steuerelement für einen Dateinamen, der von einem dateioffenen ButtonElement begleitet wird: Dies Button sollte nur aktiviert werden, wenn ein Text in die EntryDatei eingegeben wurde. Sie können eine DataTrigger für diese Aufgabe verwenden, wie im Artikel "Datentrigger" dargestellt.

Verwenden der Befehlsschnittstelle

Es ist möglich, dass eine Anwendung auf Button Tippen reagiert, ohne das Clicked Ereignis zu behandeln. Der Button implementiert einen alternativen Benachrichtigungsmechanismus, der als Befehls- oder Kommandoschnittstelle bezeichnet wird. Dies besteht aus zwei Eigenschaften:

Dieser Ansatz eignet sich besonders bei der Datenbindung und insbesondere bei der Implementierung der Model-View-ViewModel (MVVM)-Architektur. Diese Themen werden in den Artikeln Data Binding, From Data Bindings to MVVM und MVVM behandelt.

In einer MVVM-Anwendung definiert das Ansichtsmodell Eigenschaften vom Typ ICommand , die dann mit den XAML-Elementen Button mit Datenbindungen verbunden sind. Xamarin.Forms definiert Command und Command<T> Klassen, die die ICommand Schnittstelle implementieren und das Viewmodel beim Definieren von Eigenschaften des Typs ICommandunterstützen.

Die Befehle werden im Artikel "Befehlsschnittstelle" ausführlicher beschrieben, aber die Befehlsseite " Standardschaltfläche" im Beispiel zeigt den grundlegenden Ansatz.

Die CommandDemoViewModel Klasse ist ein sehr einfaches Ansichtsmodell, das eine Eigenschaft des Typs double namens Numberdefiniert, und zwei Eigenschaften des Typs ICommand benannt MultiplyBy2Command und DivideBy2Command:

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; }
}

Die beiden ICommand Eigenschaften werden im Konstruktor der Klasse mit zwei Objekten vom Typ Commandinitialisiert. Die Command Konstruktoren enthalten eine kleine Funktion (als execute Konstruktorargument bezeichnet), die entweder verdoppelt oder halbiert wird Number .

Die Datei BasicButtonCommand.xaml legt den zugehörigen BindingContext Wert auf eine Instanz von CommandDemoViewModel. Das Label Element und zwei Button Elemente enthalten Bindungen an die drei Eigenschaften in 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>

Wenn auf die beiden Button Elemente getippt wird, werden die Befehle ausgeführt, und der Wert der Zahl ändert sich:

Befehl 'Standardschaltfläche'

Der Vorteil dieses Ansatzes gegenüber Clicked-Handlern ist, dass sich die gesamte Logik, die die Funktionalität dieser Seite betrifft, im ViewModel und nicht in der Code-Behind-Datei befindet, wodurch eine bessere Trennung der Benutzeroberfläche von der Geschäftslogik erreicht wird.

Es ist auch möglich, dass die Command Objekte die Aktivierung und Deaktivierung der Button Elemente steuern können. Sie möchten z. B. den Bereich der Zahlenwerte auf zwischen 210 und 2-10 begrenzen. Sie können dem Konstruktor (als canExecute Argument bezeichnet) eine weitere Funktion hinzufügen, die zurückgegeben true wird, wenn dies Button aktiviert werden soll. Dies ist die Änderung des CommandDemoViewModel Konstruktors:

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));
    }
    ···
}

Die Aufrufe der ChangeCanExecute Methode Command sind erforderlich, damit die Command Methode die canExecute Methode aufrufen und bestimmen kann, ob die Button Methode deaktiviert werden soll. Wenn sich dieser Code ändert, wird die Anzahl deaktiviert, Button sobald die Zahl den Grenzwert erreicht:

Befehl 'Standardschaltfläche' – Geändert

Es ist möglich, dass zwei oder mehr Button Elemente an dieselbe ICommand Eigenschaft gebunden werden. Die Button-Elemente können mithilfe der CommandParameter-Eigenschaft der Button unterschieden werden. In diesem Fall sollten Sie die generische Command<T>-Klasse verwenden. Das CommandParameter-Objekt wird als ein Argument an die Methoden execute und canExecute übergeben. Diese Technik wird im Abschnitt "Grundlegende Befehle" des Artikels "Befehlsschnittstelle" ausführlich gezeigt.

Im Beispiel wird diese Technik auch in der MainPage Klasse verwendet. Die Datei "MainPage.xaml " enthält eine Button für jede Seite des Beispiels:

<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>

Jede Button hat ihre Command Eigenschaft an eine Eigenschaft mit dem Namen NavigateCommandgebunden, und die Eigenschaft wird auf ein Objekt festgelegt, das CommandParameter einer Type der Seitenklassen im Projekt entspricht.

Diese NavigateCommand Eigenschaft ist vom Typ ICommand und wird in der CodeBehind-Datei definiert:

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; }
}

Der Konstruktor initialisiert die NavigateCommand Eigenschaft auf ein Command<Type> Objekt, da Type es sich um den Typ des CommandParameter Objektsatzes in der XAML-Datei handelt. Dies bedeutet, dass die execute Methode ein Argument vom Typ Type aufweist, das diesem CommandParameter Objekt entspricht. Die Funktion instanziiert die Seite und navigiert dann zu der Seite.

Beachten Sie, dass der Konstruktor abgeschlossen wird, indem er auf BindingContext sich selbst festgelegt wird. Dies ist für Eigenschaften in der XAML-Datei erforderlich, um eine Bindung an die NavigateCommand Eigenschaft durchzuführen.

Drücken und Loslassen der Schaltfläche

Neben dem Clicked-Ereignis definiert das Button-Element auch die Ereignisse Pressed und Released. Das Pressed Ereignis tritt auf, wenn ein Finger auf eine Buttonoder eine Maustaste gedrückt wird, wobei der Mauszeiger über dem ButtonZeiger positioniert ist. Das Released Ereignis tritt auf, wenn der Finger oder die Maustaste losgelassen wird. Im Allgemeinen wird ein Clicked Ereignis auch gleichzeitig mit dem Released Ereignis ausgelöst, aber wenn der Finger oder der Mauszeiger von der Oberfläche Button der vor dem Loslassen entfernt wird, tritt das Clicked Ereignis möglicherweise nicht auf.

Die Pressed Ereignisse Released werden nicht häufig verwendet, können aber für besondere Zwecke verwendet werden, wie auf der Seite "Presse- und Freigabeschaltfläche" gezeigt. Die XAML-Datei enthält eine Label und eine Button mit Handlern, die für die Pressed und Released ereignisse angefügt sind:

<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>

Die Code-Behind-Datei animiert das Label, wenn ein Pressed-Ereignis auftritt, aber hält die Drehung an, wenn ein Released-Ereignis auftritt:

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();
    }
}

Das Ergebnis ist, dass sich der Label einzige Dreht, während ein Finger mit dem ButtonFinger in Kontakt ist, und stoppt, wenn der Finger losgelassen wird:

Schaltfläche

Diese Art von Verhalten hat Anwendungen für Spiele: Ein Finger, der auf einem Bildschirm gehalten wird, kann dazu führen, dass ein Objekt auf dem Button Bildschirm in eine bestimmte Richtung verschoben wird.

Schaltflächendarstellung

Die Button Erben oder Definieren mehrerer Eigenschaften, die sich auf ihre Darstellung auswirken:

  • TextColor ist die Farbe des Button Texts.
  • BackgroundColor ist die Farbe des Hintergrunds für diesen Text.
  • BorderColor ist die Farbe einer Umgebung, die die Button
  • FontFamily ist die Schriftartfamilie, die für den Text verwendet wird.
  • FontSize ist die Größe des Texts.
  • FontAttributes gibt an, ob der Text kursiv oder fett formatiert ist.
  • BorderWidth ist die Breite des Rahmens.
  • CornerRadius ist der Eckenradius des Button
  • CharacterSpacing ist der Abstand zwischen den Zeichen des Button Texts.
  • TextTransform bestimmt die Groß-/Kleinschreibung des Button Texts.

Hinweis

Die Button Klasse verfügt Margin außerdem über Eigenschaften und Padding Eigenschaften, die das Layoutverhalten der Button. Weitere Informationen finden Sie unter Ränder und Abstände.

Die Auswirkungen von sechs dieser Eigenschaften (ausgenommen FontFamily und FontAttributes) werden auf der Seite " Schaltflächendarstellung " veranschaulicht. Eine weitere Eigenschaft, Imagewird im Abschnitt "Verwenden von Bitmaps mit Schaltfläche" erläutert.

Alle Ansichten und Datenbindungen auf der Seite "Schaltflächendarstellung " werden in der XAML-Datei definiert:

<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>

Am Button oberen Rand der Seite sind die drei Color Eigenschaften an Picker Elemente am unteren Rand der Seite gebunden. Die Elemente in den Picker Elementen sind Farben aus der Klasse, die NamedColor im Projekt enthalten ist. Drei Slider Elemente enthalten bidirektionale Bindungen an die FontSize, BorderWidthund CornerRadius Eigenschaften der Button.

Mit diesem Programm können Sie mit Kombinationen aller folgenden Eigenschaften experimentieren:

Schaltflächendarstellung

Um den Button Rahmen anzuzeigen, müssen Sie einen BorderColor anderen Wert als Defaultund den BorderWidth Wert auf einen positiven Wert festlegen.

Unter iOS werden Sie feststellen, dass große Rahmenbreiten in das Innere des Button Texts eindringen und die Anzeige von Text beeinträchtigen. Wenn Sie sich für die Verwendung eines Rahmens mit einem iOS Buttonentscheiden, sollten Sie die Text Eigenschaft wahrscheinlich mit Leerzeichen beginnen und beenden, um die Sichtbarkeit beizubehalten.

Wählen Sie unter UWP eine CornerRadius Option aus, die die Hälfte der Höhe der Button Ausnahme überschreitet.

Visuelle Zustände der Schaltfläche

Button verfügt über ein Pressed VisualState Element, das verwendet werden kann, um eine visuelle Änderung beim Button Drücken durch den Benutzer zu initiieren, sofern dies aktiviert ist.

Das folgende XAML-Beispiel zeigt, wie ein visueller Zustand für den Zustand Pressed definiert wird:

<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>

Der Pressed VisualState Wert gibt an, Scale dass die Eigenschaft beim Button Drücken von 1 auf 0,8 geändert wird. Der Normal VisualState gibt an, dass die Eigenschaft Scale der Button auf 1 festgelegt wird, wenn sie sich in einem normalen Zustand befindet. Daher ist der Gesamteffekt, dass beim Drücken von Button die Skalierung etwas kleiner ist. Wenn Button losgelassen wird, wird wieder auf die Standardgröße skaliert.

Weitere Informationen zu visuellen Zuständen finden Sie im Xamarin.Forms Visual State-Manager.

Erstellen einer Umschaltfläche

Es ist möglich, eine Unterklasse Button so zu verwenden, dass sie wie ein On-Off-Schalter funktioniert: Tippen Sie einmal auf die Schaltfläche, um die Schaltfläche einzuschalten und erneut darauf zu tippen, um sie auszuschalten.

Die folgende ToggleButton Klasse wird von Button einem neuen Ereignis abgeleitet und definiert ein neues Ereignis namens Toggled und eine boolesche Eigenschaft mit dem Namen IsToggled. Dies sind die gleichen beiden Eigenschaften, die durch folgendes Xamarin.FormsSwitchdefiniert werden:

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");
    }
}

Der ToggleButton Konstruktor fügt einen Handler an das Clicked Ereignis an, sodass er den Wert der IsToggled Eigenschaft ändern kann. Die OnIsToggledChanged Methode löst das Toggled Ereignis aus.

Die letzte Zeile der OnIsToggledChanged Methode ruft die statische VisualStateManager.GoToState Methode mit den beiden Textzeichenfolgen "ToggledOn" und "ToggledOff" auf. Informationen zu dieser Methode und dazu, wie Ihre Anwendung auf visuelle Zustände reagieren kann, finden Sie im Artikel " Xamarin.Forms Visual State Manager".

Da ToggleButton der Aufruf erfolgt VisualStateManager.GoToState, muss die Klasse selbst keine zusätzlichen Möglichkeiten enthalten, um die Darstellung der Schaltfläche basierend auf ihrem IsToggled Zustand zu ändern. Dies liegt in der Verantwortung des XAML-Codes, in dem die ToggleButtonDatei gehostet wird.

Die Schaltflächendemoseite zum Umschalten enthält zwei Instanzen von ToggleButton, einschließlich Visual State Manager-Markup, das die TextSchaltfläche TextColor BackgroundColorbasierend auf dem visuellen Zustand festlegt:

<?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>

Die Toggled Ereignishandler befinden sich in der CodeBehind-Datei. Sie sind dafür verantwortlich, die FontAttributes Eigenschaft der Label Schaltflächen basierend auf dem Status der Schaltflächen festzulegen:

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;
        }
    }
}

Hier sehen Sie das Programm, das unter iOS, Android und der UWP ausgeführt wird:

Schaltflächendemo umschalten

Verwenden von Bitmaps mit Schaltflächen

Die Button Klasse definiert eine ImageSource Eigenschaft, mit der ButtonSie ein Bitmapbild entweder allein oder in Kombination mit Text anzeigen können. Sie können auch angeben, wie der Text und das Bild angeordnet werden.

Die Eigenschaft ImageSource ist vom Typ ImageSource, was bedeutet, dass die Bitmaps aus einer Datei, einer eingebetteten Ressource, einem URI oder einem Stream geladen werden können.

Hinweis

Während ein Button animiertes GIF geladen werden kann, wird nur der erste Frame des GIF angezeigt.

Jede plattform, die unterstützt wird, ermöglicht die Speicherung von Xamarin.Forms Bildern in mehreren Größen für unterschiedliche Pixelauflösungen der verschiedenen Geräte, auf denen die Anwendung ausgeführt werden kann. Diese mehrere Bitmaps werden so benannt oder gespeichert, dass das Betriebssystem die beste Übereinstimmung für die Videoanzeigeauflösung des Geräts auswählen kann.

Bei einer Bitmap auf einer ButtonDatei beträgt die beste Größe in der Regel zwischen 32 und 64 geräteunabhängigen Einheiten, je nachdem, wie groß sie sein soll. Die in diesem Beispiel verwendeten Bilder basieren auf einer Größe von 48 geräteunabhängigen Einheiten.

Im iOS-Projekt enthält der Ordner "Ressourcen " drei Größen dieses Bilds:

  • Eine 48-Pixel-quadratische Bitmap, die als /Resources/MonkeyFace.png
  • Eine 96-Pixel-quadratische Bitmap, die als /Resource/ gespeichert istMonkeyFace@2x.png
  • Eine 144-Pixel-quadratische Bitmap, die als /Resource/ gespeichert istMonkeyFace@3x.png

Alle drei Bitmaps erhielten eine Buildaktion von BundleResource.

Für das Android-Projekt haben alle Bitmaps denselben Namen, aber sie werden in verschiedenen Unterordnern des Ordners "Ressourcen " gespeichert:

  • Eine 72-Pixel-quadratische Bitmap, die als /Resources/drawable-hdpi/MonkeyFace.png
  • Eine quadratische Bitmap mit 96 Pixeln, die als /Resources/drawable-xhdpi/MonkeyFace.png
  • Eine quadratische Bitmap mit 144 Pixeln, die als /Resources/drawable-xxhdpi/MonkeyFace.png
  • Eine quadratische Bitmap mit 192 Pixeln, die als /Resources/drawable-xxxhdpi/MonkeyFace.png

Diese wurden mit einer Buildaktion von AndroidResource versehen.

Im UWP-Projekt können Bitmaps an einer beliebigen Stelle im Projekt gespeichert werden, aber sie werden in der Regel in einem benutzerdefinierten Ordner oder im vorhandenen Ordner "Assets " gespeichert. Das UWP-Projekt enthält die folgenden Bitmaps:

  • Eine 48-Pixel-quadratische Bitmap, die als /Assets/MonkeyFace.scale-100.png
  • Eine quadratische Bitmap mit 96 Pixeln, die als /Assets/MonkeyFace.scale-200.png
  • Eine quadratische Bitmap mit 192 Pixeln, die als /Assets/MonkeyFace.scale-400.png

Sie erhielten alle eine Buildaktion von Inhalten.

Sie können angeben, wie die Eigenschaften Text und ImageSource auf der Button mithilfe der Eigenschaft ContentLayout der Button angeordnet werden. Diese Eigenschaft ist vom Typ ButtonContentLayout, bei dem es sich um eine eingebettete Klasse handelt Button. Der Konstruktor hat zwei Argumente:

  • Ein Mitglied der ImagePosition-Enumeration: Left, Top, Right oder Bottom gibt an, wie ein Bitmap relativ zum Text angezeigt wird.
  • Ein double-Wert für den Abstand zwischen dem Bitmap und dem Text.

Die Standardwerte sind Left und 10 Einheiten. Zwei schreibgeschützte Eigenschaften benannter ButtonContentLayout Position Eigenschaften und Spacing stellen die Werte dieser Eigenschaften bereit.

Im Code können Sie eine Button eigenschaft wie folgt erstellen und festlegen ContentLayout :

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

In XAML müssen Sie nur das Enumerationselement oder den Abstand angeben, oder beides in beliebiger Reihenfolge durch Kommas getrennt:

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

Auf der Demoseite "Bildschaltfläche " werden OnPlatform verschiedene Dateinamen für die Bitmapdateien iOS, Android und UWP angegeben. Wenn Sie für jede Plattform denselben Dateinamen verwenden und die Verwendung OnPlatformvermeiden möchten, müssen Sie die UWP-Bitmaps im Stammverzeichnis des Projekts speichern.

Die erste Button auf der Bildschaltfläche Demo-Seite legt die Image Eigenschaft, aber nicht die Text Eigenschaft fest:

<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>

Wenn die UWP-Bitmaps im Stammverzeichnis des Projekts gespeichert sind, kann dieses Markup erheblich vereinfacht werden:

<Button ImageSource="MonkeyFace.png" />

Um viele wiederholte Markups in der Datei ImageButtonDemo.xaml zu vermeiden, wird auch eine implizite Style Eigenschaft definiert, um die ImageSource Eigenschaft festzulegen. Dies Style wird automatisch auf fünf weitere Button Elemente angewendet. Hier ist die vollständige XAML-Datei:

<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>

Die letzten vier Button Elemente verwenden die ContentLayout Eigenschaft, um eine Position und einen Abstand des Texts und der Bitmap anzugeben:

Demo der Bildschaltfläche

Sie haben nun die verschiedenen Möglichkeiten gesehen, wie Sie Ereignisse behandeln Button und die Button Darstellung ändern können.