Ответ 1
Существуют различные решения этого вопроса. Обязательно прочитайте их все, прежде чем выбрать один - мой любимый (самый простой) будет указан до конца...
Подход №1:
Как было предложено несколькими людьми, вы можете создать некоторый элемент управления коллекцией (я приду к этому через мгновение), определите ObservableCollection
в ViewModel, задайте страницу Binding Context
экземпляру этой ViewModel и добавьте элементы в коллекцию при нажатии кнопки:
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);
};
Тип ObservableCollection
фактически не имеет значения, поскольку мы используем один и тот же статический ItemTemplate
для всех элементов:
<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>
Основная проблема с этим подходом заключается в том, что Xamarin.Forms ListView
не может отображать свои объекты по горизонтали. Это означает, что вам нужно загрузить один из доступных пакетов HorizontalListView
Nuget или использовать встроенный (только в Xamarin.Forms 2.3 и выше!) CarouselView
:
<CarouselView ItemTemplate="{StaticResource ScoreItemTemplate}" ItemsSource="{Binding Items}"/>
Затем вы можете потратить некоторое время на удаление всех визуальных эффектов для прокрутки карусели и для выбора элементов, если вы решите использовать горизонтальный ListView...
Вместо этого существуют два альтернативных решения, которые требуют меньших усилий:
Подход № 2:
Очевидно, что простым подходом было бы создать метку "шаблон" в коде:
private Label CreateScoreLabel()
{
return new Label {Text = FontAwesome.FACheck, TextColor = Color.Green, FontFamily = "FontAwesome"};
}
... добавьте горизонтальный StackLayout
к странице:
<StackLayout Orientation="Horizontal" x:Name="LabelStack"/>
... и добавить новые ярлыки:
correctButton.Clicked += (sender, e) =>
{
App.DB.IncrementScore();
LabelStack.Children.Add(CreateScoreLabel());
};
Однако все это кажется довольно взломанным для создания списка зеленых галочек. Это приводит нас к...
... подход № 3:
Технически это не совсем то, о чем вы просили (увеличивайте количество ярлыков), но в соответствии с вашим снимком экрана он может удовлетворить ваши потребности гораздо проще.
Удалите существующий текст ярлыка (поскольку он не будет отображаться при запуске) и вместо этого дайте ему уникальное имя:
<Label x:Name="ScoreLabel" FontFamily="FontAwesome" TextColor="Green"/>
Теперь определите простой метод расширения для типа string
, который повторяет заданную строку для определенного количества раз:
public static class StringExtensions
{
public static string Repeat(this string input, int num)
{
return String.Concat(Enumerable.Repeat(input, num));
}
}
(Существует несколько способов сделать эту функцию повторения максимально возможной, я просто выбрал простейший однострочный доступ, поиск StackOverflow для подробных обсуждений...)
Теперь вы можете работать с единственным элементом управления Label
, определенным в XAML, и просто назначить ему несколько меток на кнопке:
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
};
Конечно, этот подход также можно адаптировать, чтобы следовать методу MMVM, просто используя общедоступное свойство bindable string
вместо того, чтобы напрямую устанавливать атрибут метки Text
, но для этого я бы посоветовал вам взять посмотрите учебник MVVM для начинающих.