Schaltfläche

Die .NET Multi-Platform App UI (.NET MAUI)-Button zeigt Text an und reagiert auf ein Tippen oder Klicken, das die App anweist, eine Aufgabe auszuführen.. Eine Button zeigt in der Regel eine kurze Textzeichenfolge an, die einen Befehl angibt, aber es kann auch ein Bitmapbild oder eine Kombination aus Text und einem Bild angezeigt werden. Wenn die Button mit einem Finger gedrückt wird oder mit der Maus darauf geklickt 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 Schaltflächentexts.
  • 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, ruft ein Objekt ab, das die Position des Schaltflächenbilds 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 die Textformatvorlage.
  • FontAutoScalingEnabled, vom Typ bool, definiert, ob der Schaltflächentext Skalierungseinstellungen 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 Bitmapbild 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 passt.
  • Padding, vom Typ Thickness, bestimmt die Auffüllung 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 Texts der Schaltfläche.

Diese Eigenschaften werden durch BindableProperty-Objekte gestützt, was bedeutet, dass sie Ziele von Datenbindungen sein können, und geformt.

Hinweis

Button definiert zwar eine ImageSource-Eigenschaft, mit der Sie ein Bild auf der Button anzeigen können, diese Eigenschaft ist jedoch für die Verwendung beim Anzeigen eines kleinen Symbols neben dem Button Text bestimmt.

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

Wichtig

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

Erstellen einer Schaltfläche

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

Das folgende Codebeispiel 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 Clicked-Ereignis 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 auf die Button getippt 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 die Label um 360 Grad in 1000 Millisekunden dreht:

Screenshot of a Button.

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

Befehlszeilenschnittstelle verwenden

Eine App kann auf das Tippen auf eine Button reagieren, ohne das Clicked-Ereignis zu behandeln. Die Button implementiert einen alternativen Benachrichtigungsmechanismus, der als Befehl oder Befehlsschnittstelle bezeichnet wird. Dies besteht aus zwei Eigenschaften:

Dieser Ansatz eignet sich besonders bei der Datenbindung und insbesondere bei der Implementierung des MVVM-Musters (Model-View-ViewModel). In einer MVVM-Anwendung definiert das Ansichtsmodell Eigenschaften vom Typ ICommand, die dann mit Button-Objekten mit Datenbindungen verbunden werden. .NET MAUI definiert auch die Klassen Command and Command<T>, die die ICommand-Schnittstelle implementieren und das Ansichtsmodell beim Definieren von Eigenschaften des Typs ICommand unterstützen. Weitere Informationen zu den einzelnen Befehlen finden Sie unter Befehle.

Das folgende Beispiel zeigt eine sehr einfache Viewmodel-Klasse, die eine Eigenschaft des Typs double namens Number und zwei Eigenschaften des Typs ICommand mit dem Namen MultiplyBy2Command und DivideBy2Commanddefiniert:

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 Number-Eigenschaft 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 besteht darin, dass sich die gesamte Logik, die die Funktionalität dieser Seite umfasst, im Ansichtsmodell und nicht in der CodeBehind-Datei befindet und eine bessere Trennung der Benutzeroberfläche von der Geschäftslogik erzielt.

Es ist auch möglich, dass die Command-Objekte die Aktivierung und Deaktivierung der Button-Objekte steuern. Angenommen, Sie möchten den Bereich der Zahlenwerte zwischen 210 und 2–10 begrenzen. Sie können dem Konstruktor eine weitere Funktion hinzufügen (als canExecute-Argument bezeichnet), die true zurückgibt, wenn die Buttonaktiviert werden soll:

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 von Command erforderlich, damit die Command-Methode die canExecute-Methode aufrufen und bestimmen kann, ob die Button-Methode deaktiviert werden soll. Wenn sich dieser Code ändert, weil die Anzahl das Limit erreicht, wird Button deaktiviert.

Es ist auch möglich, dass zwei oder mehr Button-Elemente an dieselbe ICommand-Eigenschaft gebunden werden. Die Button-Elemente können mithilfe der CommandParameter-Eigenschaft von Button unterschieden werden. In diesem Fall ist es ratsam, die generische Command<T>-Klasse zu verwenden. Das CommandParameter-Objekt wird dann als Argumente an die Methoden execute und canExecute übergeben. Weitere Informationen finden Sie im Abschnitt zu den Befehlen.

Drücken und Loslassen der Schaltfläche

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

Das folgende XAML-Beispiel zeigt eine Label und eine Button mit Handlern, die für die Ereignisse Pressed und Released angefügt sind:

<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 CodeBehind-Datei animiert die Label, wenn ein Pressed-Ereignis auftritt, hält aber 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 die Label sich nur dreht, während sich ein Finger mit der Button in Kontakt befindet, und stoppt, wenn der Finger losgelassen wird.

Visuelle Zustände der Schaltfläche

Button verfügt über den PressedVisualState, der verwendet werden kann, um eine visuelle Änderung an der Button initiieren, vorausgesetzt, sie ist aktiviert.

Das folgende XAML-Beispiel zeigt, wie ein visueller Zustand für den Pressed-Zustand 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>

In diesem Beispiel gibt PressedVisualState an, dass, wenn die Button gedrückt wird, ihre Scale-Eigenschaft vom Standardwert 1 in 0,8 geändert wird. Der NormalVisualState gibt an, dass, wenn sich die Button in einem normalen Zustand befindet, ihre Scale-Eigenschaft auf 1 festgelegt wird. Daher ist der Gesamteffekt des Drückens der Button, dass sie erneut etwas kleiner skaliert wird; wenn die Button losgelassen wird, wird sie wieder auf ihre Standardgröße skaliert.

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 ein kleines Bitmapbild auf der Button entweder allein oder in Kombination mit Text anzeigen können. Sie können auch angeben, wie der Text und das Bild angeordnet werden. Die ImageSource-Eigenschaft ist vom Typ ImageSource, was bedeutet, dass die Bitmaps aus einer Datei, aus einer eingebetteten Ressource, aus einem URI oder aus einem Datenstrom geladen werden können.

Bitmaps werden nicht so skaliert, dass sie in eine Button passen. Die optimale 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 mithilfe der ContentLayout-Eigenschaft von Button auf der Button angeordnet werden. Diese Eigenschaft ist vom Typ ButtonContentLayout, und der Konstruktor hat zwei Argumente:

  • Ein Member der ImagePosition-Enumeration: Left, Top, Right oder Bottom, die angeben, wie die Bitmap im Verhältnis zum Text angezeigt wird.
  • Ein double-Wert für den Abstand zwischen der Bitmap und dem Text.

In XAML können Sie eine Button erstellen und die ContentLayout -Eigenschaft festlegen, indem Sie nur das Enumerationsmember 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)
};

Deaktivieren einer Schaltfläche

Manchmal wechselt eine App in einen Zustand, in dem ein Klicke 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.