How to pass value from Binding in the CommandParameter from a Button ?

Andreeh_AraujoAndreeh_Araujo BRMember ✭✭
edited December 2016 in Xamarin.Forms

I have a ListView with some labels and buttons.
I need to pass value from a label in the CommandParameter of the buttons and get this value in the ViewModel, but doesn't work of the way that i'm doing.
I don't know too how to get this value in the ViewModel.
How to i can do it ?

My code:

// XAML

<ListView x:Name="lvEnderecos" RowHeight="205">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
            <Label x:Name="lblCEP" Font="14" TextColor="Black" Text="{Binding CliEndCep, StringFormat='CEP: {0}'}"></Label>
              <Grid x:Name="GridControl3" RowSpacing="0" ColumnSpacing="0">
                <Grid.RowDefinitions>
                  <RowDefinition Height="25"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto" />
                  <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <StackLayout x:Name="stkManipularEndereco" Grid.Row="0" Grid.Column="0" Padding="5, 0, 0, 0" HeightRequest="25" WidthRequest="25">
                  <Button x:Name="btnEditarEndereco" BackgroundColor="Transparent" Image="editar2.png" HeightRequest="25" WidthRequest="25" BindingContext="{Binding Source={x:Reference lvEnderecos}, Path=BindingContext}" Command="{Binding EditarEnderecoCommand}" CommandParameter="{Binding CliEndCep}" />
                </StackLayout>
              </Grid>
            </StackLayout>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>

// ViewModel

this.EditarEnderecoCommand = new Command(async () =>
    {
        try
        {
             page.DisplayAlert("Alerta", "Hello World", "OK");
        }                
        catch (Exception ex)
        {
             throw ex;
        }
    }
});

Best Answer

Answers

  • ionixjuniorionixjunior USMember ✭✭✭

    Your listview has BindingContext for an property of your viewmodel, not entire class.

    Try this...
    1) In your xaml, define a x:Name attribute:
    <ContentPage x:Name="nameYourPage" ....>...</ContentPage>

    2) In your command property, define source reference to your page and path to your command on viewmodel
    <Button .... Command="{Binding Source={x:Reference Name=nameYourPage}, Path=BindingContext. EditarEnderecoCommand}" CommandParameter="{Binding CliEndCep}" ... />

    Your page have BindingContext with instance of your viewmodel, so I guess makes more sense your binding refer the current page and path property refer your command located in binding context of viewmodel.

    This will be works.

  • Andreeh_AraujoAndreeh_Araujo BRMember ✭✭

    @ionixjunior It did not work for me. To access the method in ViewModel i used BindingContext="{Binding Source={x:Reference lvEnderecos}, Path=BindingContext}" and my command stayed normal.
    Do you have another idea ?

  • Andreeh_AraujoAndreeh_Araujo BRMember ✭✭

    @ionixjunior Pô cara estamos falando inglês porquê ? rsrs Cara muito obrigado, consegui dessa vez.

  • ionixjuniorionixjunior USMember ✭✭✭

    @Andreeh_Araujo desculpe, é que aqui neste fórum o padrão é somente inglês. Bacana cara, legal que conseguisse, qualquer coisa, estamos aí :smile:

  • Andreeh_AraujoAndreeh_Araujo BRMember ✭✭

    @ionixjunior Cara, outra dúvida um pouco fora dessa, Como faço para que abra a view mesmo se a lista estiver vazia ? Pq agora minha lista está vazia, ai a view da erro pra abrir pq a lista está vazia.

  • BrentSaferBrentSafer USMember ✭✭

    This works well for me for MVVM. I was stuck with the commandparameter. So MenuItem inside a listview returning the list item back to the Command.

    Name the content page
    x:Name="CAGroupMembersViewPage"

        <MenuItem Text="Remove" CommandParameter="{Binding .}"
                  Command="{Binding Path=BindingContext.RemoveSingleClicked, Source={x:Reference CAGroupMembersViewPage} }" 
                    IsDestructive="True" />
    

    In Codebehind
    public ICommand NotifySingleClicked { protected set; get; }
    In Codebehind Constructor
    NotifySingleClicked = new Command<Members>(async (key) => { _userDialogs.Alert("Notify Clicked" + key.Id); });

Sign In or Register to comment.