michal_Giza
michal_Giza

Reputation: 19

Commanding property not found on viewmodel xamarin?

While i tried to implement a simple command to raise property of progress bar within listview through command fired in viewmodel assing to this page. I don't know what to do next becouse the progress bar don't increment when i'm call command from imagebutton assing to same object ?.

Output after clicking imagebutton

Bidning: 'IncrementCommand property not found on AppDemo.Models.SampleObject, target property XamarinForms.ImageButtonCommand'

A code from Viewmodel:

    public ICommand IncrementCommand { get; }
    public MainViewModel(IPageServices pageServices)
    {
        this._pageServices = pageServices; 

        Wastes = GetObjects();
        IncrementCommand = new Command(async () => await IncrementObject());

    }
    async Task IncrementObject()
    {
        await objectServices.IncrementObject(object);
        OnPropertyChanged("SampleCounter");
    }

Code from service where Task is called

    public Task IncrementObject(ObjectModel object)
    {
        object.ObjectCounter += .1;
        return objectRepository.Save(object);
    }

Model inherit INotifyPropertyChanged from Observable object

public class SampleModel: ObservableObject
{
    public int? Id { get; set; }
    public string SampleIcon{ get; set; }
    public double SampleCounter{ get; set; } 
}

Code from MainPage xaml file

<ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="3*"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <ProgressBar x:Name="progressBar"
                                    Grid.RowSpan="2" Grid.Row="0" Grid.Column="0"
                                     BackgroundColor="Transparent"
                                     ProgressColor="#614c96"
                                     Progress="{Binding ObjectCounter}"                                         
                                     />
                        <ImageButton x:Name="iconButton"
                                     Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" 
                                     WidthRequest="100"
                                     HeightRequest="100"
                                     Aspect="AspectFit"
                                     BackgroundColor="Transparent"
                                     Source="{Binding ObjectIcon}"
                                     Command="{x:Binding IncrementCommand}">
                        </ImageButton>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>

Coede form page code-behind

    public MainPage()
    {
        InitializeComponent();
        var pageServices = new PageServices();
        BindingContext = new MainViewModel(pageServices);

    }

Can i ask for some explenation of my mistake ? Thank you

Upvotes: 1

Views: 703

Answers (1)

Gerald Versluis
Gerald Versluis

Reputation: 34013

Your code and the error message is not consistent. I'm going to assume that in this error:

Bidning: 'IncrementCommand property not found on AppDemo.Models.SampleObject, target property XamarinForms.ImageButtonCommand'

SampleObject is now named SampleModel.

Like Jason pointed out in a comment, the binding context for each item in your list is different than the binding context for the whole page. Whenever you use a list, the binding context of each item will be scoped to the item in that cell.

To be able to reach something outside of that, you will have to use a reference. First, give a name to your ListView like this: <ListView x:Name="MyListView" ...>.

Then, for your ImageButton, change the Command to be this: <ImageButton Command="{Binding Source={x:Reference MyListView}, Path=BindingContext.IncrementCommand}">

By adding the source and referencing the ListView, we now scope the binding to whatever we specify in Path. So we suddenly can access the properties of the ListView and access its BindingContext (being the SampleModel) and inside that context access the command we are after, in this case, IncrementCommand.

Does that make sense?

Upvotes: 1

Related Questions