Freigeben über


Schaltfläche

Die Button für die Benutzeroberfläche der .NET Multi-Plattform App (.NET MAUI) zeigt Text an und reagiert auf ein Tippen oder Klicken, mit dem die Anwendung angewiesen wird, eine Aufgabe auszuführen. Eine Button zeigt in der Regel eine kurze Textzeichenfolge an, die einen Befehl angibt, aber es kann auch ein Bitmap-Bild oder eine Kombination aus Text und einem Bild angezeigt werden. Wenn die Button mit einem Finger gedrückt wird oder mit der Maus angeklickt wird, wird dieser Befehl initiiert.

Button definiert die folgenden Eigenschaften:

  • BorderColor, vom Typ Color, beschreibt die Rahmenfarbe der Schaltfläche.
  • BorderWidth, vom Typ double, definiert die Breite des Rahmens der Schaltfläche.
  • CharacterSpacing, vom Typ double, definiert den Abstand zwischen den Zeichen des Textes der Schaltfläche.
  • Command, vom Typ ICommand, definiert den Befehl, der beim Tippen auf die Schaltfläche ausgeführt wird.
  • CommandParameter, vom Typ object: ist der Parameter, der an den Command übergeben wird.
  • ContentLayout, vom Typ ButtonContentLayout, definiert das Objekt, das die Position des Schaltflächenbildes und den Abstand zwischen dem Bild und dem Text der Schaltfläche steuert.
  • CornerRadius, vom Typ int, beschreibt den Eckenradius des Rahmens der Schaltfläche.
  • FontAttributes, vom Typ FontAttributes, bestimmt den Textstil.
  • FontAutoScalingEnabled, vom Typ bool, definiert, ob der Schaltflächentext Skalierungspräferenzen widerspiegelt, die im Betriebssystem festgelegt sind. Der Standardwert dieser Eigenschaft ist true.
  • FontFamily, vom Typ string, definiert die Schriftartfamilie.
  • FontSize, vom Typ double, definiert den Schriftgrad.
  • ImageSource, vom Typ ImageSource, gibt ein Bitmap-Bild an, das als Inhalt der Schaltfläche angezeigt werden soll.
  • LineBreakMode, vom Typ LineBreakMode, bestimmt, wie Text behandelt werden soll, wenn er nicht in eine Zeile passen kann.
  • Padding, vom Typ Thickness, bestimmt den Innenabstand der Schaltfläche.
  • Text, vom Typ string, definiert den Text, der als Inhalt der Schaltfläche angezeigt wird.
  • TextColor, vom Typ Color, beschreibt die Farbe des Schaltflächentexts.
  • TextTransform, vom Typ TextTransform, definiert die Groß-/Kleinschreibung des Schaltflächentexts.

Diese Eigenschaften werden von BindableProperty-Objekten unterstützt, was bedeutet, dass sie Ziele von Datenbindungen sein können und formatiert werden können.

Hinweis

Während Button eine ImageSource-Eigenschaft definiert, mit der Sie ein Bild auf der Button anzeigen können, soll diese Eigenschaft beim Anzeigen eines kleinen Symbols neben dem Button-Text verwendet werden.

Darüber hinaus definiert Button die Ereignisse Clicked, Pressed und Released. Das Ereignis Clicked wird ausgelöst, wenn ein Tippen auf eine Button mit einem Finger oder Mauszeiger von der Oberfläche der Schaltfläche losgelassen wird. Das Ereignis Pressed wird ausgelöst, wenn ein Finger auf eine Button drückt oder eine Maustaste gedrückt wird, wobei der Mauszeiger über der Button positioniert ist. Das Ereignis Released wird ausgelöst, wenn der Finger nicht mehr drückt oder die Maustaste losgelassen wird. Im Allgemeinen wird ein Clicked-Ereignis auch gleichzeitig mit dem Released-Ereignis ausgelöst. Wenn der Finger oder der Mauszeiger jedoch vor dem Loslassen von der Oberfläche des Button weg gleitet, tritt das Clicked-Ereignis möglicherweise nicht auf.

Wichtig

Die Eigenschaft IsEnabled einer Button muss auf true festgelegt sein, damit sie auf Tippen reagiert.

Erstellen einer Schaltfläche

Um eine Schaltfläche zu erstellen, erstellen Sie ein Button-Objekt und bearbeiten dessen Ereignis Clicked.

Das folgende XAML-Beispiel zeigt, wie Sie eine Button erstellen:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.BasicButtonClickPage"
             Title="Basic Button Click">
    <StackLayout>
        <Button Text="Click to Rotate Text!"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Clicked="OnButtonClicked" />
        <Label x:Name="label"
               Text="Click the Button above"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

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:

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. Der Clicked-Handler ruft eine Animationsfunktion auf, die das Label 360 Grad in 1000 Millisekunden dreht:

Screenshot einer Schaltfläche.

Der entsprechende C#-Code zum Erstellen einer Button lautet:

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

Verwenden der Befehlsschnittstelle

Eine App kann auf Button-Tippen reagieren, 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 im Zusammenhang mit der Datenbindung und vor allem bei der Implementierung des Model-View-ViewModel (MVVM)-Musters. In einer MVVM-Anwendung definiert das ViewModel Eigenschaften vom Typ ICommand, die dann mit Button-Objekten mit Datenbindungen verbunden sind. .NET MAUI definiert auch Command- und Command<T>-Kllassen, die die ICommand-Schnittstelle implementieren und das ViewModel beim Definieren von Eigenschaften vom Typ ICommand unterstützen. Weitere Informationen zu Befehlen finden Sie unter Befehlsübersicht.

Das folgende Beispiel zeigt eine sehr einfache ViewModel-Klasse, die eine Eigenschaft des Typs double namens Number und zwei Eigenschaften des Typs ICommand namens MultiplyBy2Command und DivideBy2Command definiert:

public class CommandDemoViewModel : INotifyPropertyChanged
{
    double number = 1;

    public event PropertyChangedEventHandler PropertyChanged;

    public ICommand MultiplyBy2Command { get; private set; }
    public ICommand DivideBy2Command { get; private set; }

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

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

In diesem Beispiel werden die beiden ICommand-Eigenschaften im Konstruktor der Klasse mit zwei Objekten vom Typ Command initialisiert. Die Command-Konstruktoren enthalten eine kleine Funktion (als execute-Konstruktorargument bezeichnet), die den Wert der Eigenschaft Number verdoppelt oder halbiert.

Im folgenden XAML-Beispiel wird die CommandDemoViewModel-Klasse verwendet:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             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="18"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
        <Button Text="Multiply by 2"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Command="{Binding MultiplyBy2Command}" />
        <Button Text="Divide by 2"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Command="{Binding DivideBy2Command}" />
    </StackLayout>
</ContentPage>

In diesem Beispiel enthalten das Label-Element und zwei Button-Objekte Bindungen an die drei Eigenschaften in der CommandDemoViewModel-Klasse. Wenn auf die beiden Button-Objekte getippt wird, werden die Befehle ausgeführt, und der Wert der Zahl ändert sich. 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-Objekte steuern. Sie möchten z. B. den Bereich der Zahlenwerte auf zwischen 210 und 2-10 begrenzen. Sie können dem Konstruktor ( canExecute-Argument genannt) eine weitere Funktion hinzufügen, die true zurückgibt, wenn die Button aktiviert sein sollte:

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

In diesem Beispiel sind die Aufrufe der ChangeCanExecute-Methode des Command erforderlich, damit die Command-Methode die canExecute-Methode aufrufen und bestimmen kann, ob die Button deaktiviert werden soll. Wenn sich dieser Code ändert, wird die Button deaktiviert, wenn die Zahl den Grenzwert erreicht.

Es ist auch möglich, dass zwei oder mehr Button Elemente an dieselbe ICommand Eigenschaft gebunden sind. 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. Weitere Informationen finden Sie unter Befehlsübersicht.

Drücken und Loslassen der Schaltfläche

Das Ereignis Pressed wird ausgelöst, wenn ein Finger auf eine Button drückt oder eine Maustaste gedrückt wird, wobei der Mauszeiger über der Button positioniert ist. Das Ereignis Released wird ausgelöst, wenn der Finger nicht mehr drückt oder die Maustaste losgelassen wird. Im Allgemeinen wird gleichzeitig mit dem Ereignis Released auch das Ereignis Clicked ausgelöst, aber wenn der Finger oder Mauszeiger von der Oberfläche der Button weggleitet, bevor er losgelassen wird, tritt das Ereignis Clicked möglicherweise nicht ein.

Das folgende XAML-Beispiel zeigt ein Label und eine Button mit Handlern für die Ereignisse Pressed und Released.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.PressAndReleaseButtonPage"
             Title="Press and Release Button">
    <StackLayout>
        <Button Text="Press to Rotate Text!"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Pressed="OnButtonPressed"
                Released="OnButtonReleased" />
        <Label x:Name="label"
               Text="Press and hold the Button above"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
    </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
{
    IDispatcherTimer timer;
    Stopwatch stopwatch = new Stopwatch();

    public PressAndReleaseButtonPage()
    {
        InitializeComponent();

        timer = Dispatcher.CreateTimer();
        timer.Interval = TimeSpan.FromMilliseconds(16);
        timer.Tick += (s, e) =>
        {
            label.Rotation = 360 * (stopwatch.Elapsed.TotalSeconds % 1);
        };
    }

    void OnButtonPressed(object sender, EventArgs args)
    {
        stopwatch.Start();
        timer.Start();
    }

    void OnButtonReleased(object sender, EventArgs args)
    {
        stopwatch.Stop();
        timer.Stop();
    }
}

Das Ergebnis ist, dass sich das Label nur dreht, während sich ein Finger in Kontakt mit der Button befindet, und stoppt, wenn der Finger losgelassen wird.

Visuelle Zustände der Schaltfläche

Button verfügt über einen Pressed VisualState, der verwendet werden kann, um beim Drücken eine visuelle Änderung an der Button zu initiieren, vorausgesetzt, sie ist aktiviert.

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

<Button Text="Click me!"
        ...>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroupList>
            <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>
                <VisualState x:Name="PointerOver" />            
            </VisualStateGroup>
        </VisualStateGroupList>
    </VisualStateManager.VisualStateGroups>
</Button>

In diesem Beispiel gibt der Pressed VisualState an, dass beim Drücken von Button die Eigenschaft Scale von ihrem Standardwert 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.

Wichtig

Damit ein Button wieder in den Normal-Zustand zurückkehrt, muss auch VisualStateGroup einen PointerOver-Zustand definieren. Wenn Sie die von der Projektvorlage der .NET MAUI-App erstellten ResourceDictionary-Formatvorlagen verwenden, verfügen Sie bereits über eine implizite Button-Formatvorlage, die den PointerOver-Zustand definiert.

Weitere Informationen zu visuellen Zuständen finden Sie unter Visuelle Zustände.

Verwenden von Bitmaps mit Schaltflächen

Die Button-Klasse definiert eine ImageSource-Eigenschaft, mit der Sie auf der Button ein kleines Bitmap-Bild 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.

Bitmaps werden nicht so skaliert, dass sie in eine Button passen. Die beste Größe liegt in der Regel zwischen 32 und 64 geräteunabhängigen Einheiten, je nachdem, wie groß die Bitmap sein soll.

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, und 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.

In XAML können Sie eine Button erstellen und die Eigenschaft ContentLayout festlegen, indem Sie nur das Enumerationsmitglied oder den Abstand oder beides in beliebiger Reihenfolge durch Kommas getrennt angeben:

<Button Text="Button text"
        ImageSource="button.png"
        ContentLayout="Right, 20" />

Der entsprechende C#-Code lautet:

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

Hinweis

Wenn ein Button Text und ein Bild enthalten, ist es möglicherweise nicht möglich, den gesamten Inhalt in die Schaltfläche einzufügen. Daher sollten Sie das Bild manuell skalieren, um das gewünschte Layout zu erzielen.

Deaktivieren einer Schaltfläche

Manchmal wechselt eine App in einen Zustand, in dem ein Klick auf eine Button kein gültiger Vorgang ist. In solchen Fällen kann die Button deaktiviert werden, indem die zugehörige IsEnabled-Eigenschaft auf false festgelegt wird.