Anton
Anton

Reputation: 33

Changing Data in CollectionView (Xamarin)

I use CollectionView to show data on screen, but when I change data, UI is not changing, although I am using OnPropertyChanged. Here is the code:

Xaml

<CollectionView ItemsSource="{Binding GridData}" Margin="15">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Margin="15" Padding="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Label Grid.Row="0"
                       Grid.Column="0"
                       HorizontalTextAlignment="Start"
                       Text="{Binding Title}"
                       FontSize="Small"/>
        <Label Grid.Row="0"
                       Grid.Column="1"
                       HorizontalTextAlignment="End"
                       Text="{Binding Data}"
                       TextColor="Black"
                       FontSize="Medium">
            <Label.GestureRecognizers>
                <TapGestureRecognizer
                        Command="{Binding Source={x:Reference Page} , Path=BindingContext.TapCommand}"
                        CommandParameter="{Binding Title}" />
            </Label.GestureRecognizers>
        </Label>
        <BoxView Grid.Row="1"
                         Grid.Column="0"
                         Grid.ColumnSpan="2"                                                
                    BackgroundColor="LightGray"
                    CornerRadius="2"
                    HorizontalOptions="FillAndExpand" 
                    HeightRequest="1"></BoxView>
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

ViewModel

private List<CollectionEntity> _gridData;
public List<CollectionEntity> GridData
{
    get => _gridData;
    set
    {
        if (_gridData != value)
        {
            _gridData = value;
            OnPropertyChanged(nameof(GridData));
        }
    }
}

public ICommand TapCommand
{
    get
    {
        return new Command<CollectionView>((commandParameters) =>
        {
            OpenEditing(commandParameters.ToString());
            OnPropertyChanged(nameof(GridData));
        });
    }
}

Model (is in the same file, as is ViewModel)

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

    public string Title { get; set; }
    public string Data { get; set; }        
}

So, when I tap on the Label, UI does not react. I tried to write it according to this answer, but cannot understand, what is incorrect.

UPD: new command

public ICommand TapCommand => new Command<object>((commandParameters) =>
    {
        OpenEditing(commandParameters.ToString()); // changing data
    });

Upvotes: 1

Views: 555

Answers (1)

Lucas Zhang
Lucas Zhang

Reputation: 18861

Though you had write the code about INotifyPropertyChanged in your model but you didn't implement it on the property Title and Data . Modify the code like following

private string title;
public string Title
{
    get => title;
    set
    {
        if (title!= value)
        {
            title = value;
            OnPropertyChanged(nameof(Title));
        }
    }
}

private string data;
public string Data
{
    get => data;
    set
    {
        if (data!= value)
        {
            data= value;
            OnPropertyChanged(nameof(Data));
        }
    }
}

In addition, the code in TapCommand seems will not change the value of source . You could binding the whole model to the command and set the title or data in command as you want .

 CommandParameter="{Binding .}"
public ICommand TapCommand
{
    get
    {
        return new Command<CollectionView>((arg) =>
        {
            var model = arg as CollectionEntity;
             // model.Title = "xxx";
        });
    }
}

Upvotes: 1

Related Questions