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 Fill
Wert 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:
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 await
wird.
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. Button
implementiert die IFontElement
Schnittstelle, sodass sie , FontSize
und 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 Button
Element begleitet wird: Dies Button
sollte nur aktiviert werden, wenn ein Text in die Entry
Datei 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:
Command
vom TypICommand
, eine im NamespaceSystem.Windows.Input
definierte Schnittstelle.CommandParameter
-Eigenschaft vom TypObject
.
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 ICommand
unterstü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 Number
definiert, 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 Command
initialisiert. 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:
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:
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 NavigateCommand
gebunden, 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 Button
oder eine Maustaste gedrückt wird, wobei der Mauszeiger über dem Button
Zeiger 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 Button
Finger in Kontakt ist, und stoppt, wenn der Finger losgelassen wird:
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 desButton
Texts.BackgroundColor
ist die Farbe des Hintergrunds für diesen Text.BorderColor
ist die Farbe einer Umgebung, die dieButton
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 desButton
CharacterSpacing
ist der Abstand zwischen den Zeichen desButton
Texts.TextTransform
bestimmt die Groß-/Kleinschreibung desButton
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, Image
wird 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
, BorderWidth
und CornerRadius
Eigenschaften der Button
.
Mit diesem Programm können Sie mit Kombinationen aller folgenden Eigenschaften experimentieren:
Um den Button
Rahmen anzuzeigen, müssen Sie einen BorderColor
anderen Wert als Default
und 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 Button
entscheiden, 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.FormsSwitch
definiert 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 ToggleButton
Datei gehostet wird.
Die Schaltflächendemoseite zum Umschalten enthält zwei Instanzen von ToggleButton
, einschließlich Visual State Manager-Markup, das die Text
Schaltfläche TextColor
BackgroundColor
basierend 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:
Verwenden von Bitmaps mit Schaltflächen
Die Button
Klasse definiert eine ImageSource
Eigenschaft, mit der Button
Sie 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 Button
Datei 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
oderBottom
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 OnPlatform
vermeiden 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:
Sie haben nun die verschiedenen Möglichkeiten gesehen, wie Sie Ereignisse behandeln Button
und die Button
Darstellung ändern können.