1
votes

I have a problem. I created a CollectionView with a Label as a counter on each row and a button. What I want is that when I push the button, the label value will go up by +1, depending on the row you click. I already created the button event like this:

private void btnPlus_Clicked(object sender, EventArgs e)
{
    int currentValue = Convert.ToInt32(txtCounter.Text);
    txtCounter.Text = (currentValue + 1).ToString();
}

And here is my xaml:

<CollectionView ItemsSource="{Binding imageList}">
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout HorizontalOptions="Center" 
                <Label Text="1" TextColor="Black" x:Name="txtCounter" FontAttributes="Bold" VerticalOptions="Center"/>
                <Button CornerRadius="13" WidthRequest="25" Text="+" Padding="0"
                        HeightRequest="25" VerticalOptions="Center" Clicked="btnPlus_Clicked" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

But txtCounter doesn't get recognized!?

What am I doing wrong?

2
Items inside a DataTemplate do not work with `x:Name, you need to add bindings for this to be easierFreakyAli
Did you solve the issue ?Lucas Zhang

2 Answers

3
votes

Since you had used MVVM, you would better handle the logic in ViewModel .

in Xaml

<?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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Name="MyPage"  //set name of content page
             x:Class="xxx.MainPage">
<StackLayout HorizontalOptions="Center" 
      <Label Text="{Binding Count}" TextColor="Black" x:Name="txtCounter" FontAttributes="Bold" VerticalOptions="Center"/>
      <Button CornerRadius="13" WidthRequest="25" Text="+" Padding="0" HeightRequest="25" VerticalOptions="Center" Command="{Binding AddCommand}" CommandParameter="{Binding }"/>
</StackLayout>

in model

public class MyImage : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private string count ;
        public string Count
        {
            set
            {
                if (count != value)
                {
                    count = value;
                    NotifyPropertyChanged("Count");
                }
            }
            get { return count; }
        }
    }

  // ... other property

in ViewModel

public VM_CounterList()
{
  
   imageList= new ObservableCollection<MyImage>() {

     new MyImage(){Count="0" },
     new MyImage(){Count="0" },
     new MyImage(){Count="0" },
     new MyImage(){Count="0" },
     new MyImage(){Count="0" },
     new MyImage(){Count="0" },
                     
   };

   AddCommand = new Command((obj)=> {

      var myimage = obj as MyImage;

      int currentValue = Convert.ToInt32(myimage.Count);
      myimage.Count = (currentValue + 1).ToString();

   });
}
0
votes

x:Name is not within the context of what you want. To bind a property from a Template into something on the XAML.cs Back Code use:

PropertyOnTemplate="{Binding Path=NameOfProperty, Source={x:Reference Name=NameOfFile}}

Then whenever you update the property NameOfProperty the UI will update accordingly

Since you have a list, keep a list of counters so that you can update the correct counter indexed by the selected item from the list