J'ai l'étiquette suivante:
<Label Text="{x:Static local:FontAwesome.FACheck}" FontFamily="FontAwesome" TextColor="Green"/>
Et un événement sur le bouton:
correctButton.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
};
C’est que chaque fois que je clique sur un bouton, mon score est incrémenté de 1. Ce que je voulais faire, c’est aussi incrémenter le nombre de Label
s en fonction du nombre de scores. Voir l'image ci-dessous:
Quelqu'un a une idée de comment je pourrais y arriver?
Il existe différentes solutions à cette question. Assurez-vous de les lire tous avant de choisir celui-ci - mon préféré (le plus simple) est répertorié de haut en bas ...
Approche n ° 1:
Comme plusieurs personnes l'ont suggéré, vous pouvez créer un contrôle de collection (j'y reviendrai dans un instant), définir une ObservableCollection
dans un ViewModel, définir le Binding Context
de la page sur une instance de ce ViewModel et ajouter des éléments à la collection sur le bouton Cliquez sur:
public class MyViewModel()
{
public ObservableCollection<int> Items { get; set; } = new ObservableCollection<int>();
}
private MyViewModel _viewModel = new MyViewModel();
public MainPage()
{
InitializeComponent();
BindingContext = _viewModel;
}
correctButton.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
_viewModel.Items.Add(0);
};
Le type de ObservableCollection
n'a pas d'importance, car nous utilisons la même valeur statique ItemTemplate
pour tous les éléments:
<ContentPage.Resources>
<DataTemplate x:Key="ScoreItemTemplate">
<ViewCell>
<ViewCell.View>
<Label Text="{x:Static local:FontAwesome.FACheck}" FontFamily="FontAwesome" TextColor="Green"/>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ContentPage.Resources>
Le principal problème de cette approche est que Xamarin.Forms ListView
ne peut pas afficher ses éléments horizontalement. Cela signifie que vous devez télécharger l’un des packages HorizontalListView
Nuget disponibles ou utiliser le intégré (uniquement dans Xamarin.Forms 2.3 et versions ultérieures!) CarouselView
:
<CarouselView ItemTemplate="{StaticResource ScoreItemTemplate}" ItemsSource="{Binding Items}"/>
Ensuite, vous voudrez peut-être passer un certain temps à supprimer tous les effets visuels nécessaires pour faire défiler le carrousel et pour sélectionner des éléments si vous choisissez d'utiliser un ListView horizontal ...
Au lieu de cela, il existe deux solutions alternatives qui impliquent moins d'effort:
Approche n ° 2:
Évidemment, l’approche simple consisterait à créer l’étiquette "template" dans le code:
private Label CreateScoreLabel()
{
return new Label {Text = FontAwesome.FACheck, TextColor = Color.Green, FontFamily = "FontAwesome"};
}
... ajoutez une StackLayout
horizontale à la page:
<StackLayout Orientation="Horizontal" x:Name="LabelStack"/>
... et ajouter de nouvelles étiquettes à la dure:
correctButton.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
LabelStack.Children.Add(CreateScoreLabel());
};
Cependant, tout cela semble plutôt hacky pour simplement créer une liste de coches vertes. Cela nous amène à ...
... approche n ° 3:
Techniquement, ce n'est pas exactement ce que vous avez demandé (incrémenter le nombre d'étiquettes), mais selon votre capture d'écran, il pourrait répondre à vos besoins de manière beaucoup plus simple.
Supprimez le texte de l'étiquette existante (car elle ne doit rien afficher au démarrage) et attribuez-lui un nom unique:
<Label x:Name="ScoreLabel" FontFamily="FontAwesome" TextColor="Green"/>
Maintenant, définissez une méthode d'extension simple pour le type string
qui répète une chaîne donnée un certain nombre de fois:
public static class StringExtensions
{
public static string Repeat(this string input, int num)
{
return String.Concat(Enumerable.Repeat(input, num));
}
}
(Il y a plusieurs façons de rendre cette répétition fonctionnelle aussi performante que possible, j'ai simplement choisi le type de ligne le plus simple, cherchez dans StackOverflow des discussions détaillées ...)
Vous pouvez maintenant travailler avec le contrôle Label
unique défini dans XAML et lui attribuer plusieurs coches en un clic de bouton:
correctButton.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
ScoreLabel.Text = FontAwesome.FACheck.Repeat(App.DB.Score); // replace parameter by whatever method allows you to access the current score number
};
Bien sûr, cette approche peut également être adaptée à la méthode MMVM, en utilisant simplement une propriété publique publique string
au lieu de définir directement l'attribut Text
de l'étiquette, mais pour cela, je vous conseillerais de jeter un coup d'œil au tutoriel MVVM du débutant.
Il vous suffit d'insérer un nouveau code d'étiquette dans l'événement de clic de bouton, ce qui ajoutera de nouveaux enfants à votre pile de partitions.
cs page Code: -
button.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
lblStack.Children.Add(new Label {Text = FontAwesome.FACheck, TextColor = Color.Green, FontFamily = "FontAwesome"});
};
code xamal
<StackLayout Orientation="Horizontal" x:Name="lblStack"/>
Si le score est maximal, ajoutez simplement le nombre maximal d'étiquettes et associez leur visibilité.
Vous pouvez également créer une liste des étiquettes et lier la source à une collection que vous incrémentez si nécessaire.
Note: Je ne suis pas sûr si cette réponse est correcte, mais c'est trop long pour un commentaire. Juste le tester et si cela ne fonctionne pas, je vais supprimer cette réponse
Vous pouvez ajouter des contrôles par programme. N'oubliez pas que vous devez ajouter une Label
à votre MainThread, car il s'agit d'une modification de l'interface utilisateur. Ajoutez ceci à votre événement Clicked
:
correctButton.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
Device.BeginInvokeOnMainThread(() => // On MainThread because it's a change in your UI
{
Label label = new Label();
label.Text = "{x:Static local:FontAwesome.FACheck}"; // Not sure if this is right syntax...
label.FontFamily = "FontAwesome";
label.TextColor = Color.Green;
stackPanel.Children.Add(label);
});
};
Si vous avez une Grid
, vous pouvez définir Grid.Row
et Grid.Column
avec la méthode SetValue
d'une Control
:
label.SetValue(Grid.RowProperty, 1);
label.SetValue(Grid.RowProperty, 2);