web-dev-qa-db-fra.com

Liaison de commande du bouton Xamarin Forms dans un ListView

J'ai le problème suivant, à mon avis, j'ai un Listview. Dans cette liste, j'aimerais avoir deux boutons. Un pour modifier l'élément, un pour le supprimer.

Voici ma vue de liste en XAML

<ListView Grid.Row="1" x:Name="ArbeitsEinträgeList" ItemsSource="{Binding EintragList}" SelectedItem="{Binding SelectedItem}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <ViewCell.View>
              <Grid>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Titel}" TextColor="{Binding Fehlerhaft, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="1" Text="{Binding Beginn}" TextColor="{Binding BeginnManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="2" Text="{Binding Ende}" TextColor="{Binding EndeManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Button Grid.Column="3" Command="{Binding EditEintragCommand}" Text="&#xf040;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
                <Button Grid.Column="4" Command="{Binding DeleteEintragCommand}" Text="&#xF00D;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
              </Grid>
            </ViewCell.View>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

Dans mon ViewModel est tout ce dont j'ai besoin, j'ai testé les commandes avec un bouton qui n'est pas dans la liste et cela fonctionne parfaitement.

Si je survole la liaison, le message "Impossible de résoudre le symbole '...'" apparaît

Cannot resolve symbol

20
JanMer

Jan,

Étant donné que vous avez utilisé une vue de liste et que vos commandes sont à l'intérieur du DataTemplate, la liaison est attachée au contexte de liaison de chaque modèle individuel dans ItemSource.

Pour contourner ce problème, procédez comme suit:

<ListView Grid.Row="1" x:Name="ArbeitsEinträgeList" ItemsSource="{Binding EintragList}" SelectedItem="{Binding SelectedItem}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <ViewCell.View>
              <Grid x:Name="Item">
                <Grid.ColumnDefinitions>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Titel}" TextColor="{Binding Fehlerhaft, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="1" Text="{Binding Beginn}" TextColor="{Binding BeginnManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="2" Text="{Binding Ende}" TextColor="{Binding EndeManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Button Grid.Column="3" BindingContext="{Binding Source={x:Reference ArbeitsEinträgeList}, Path=BindingContext}"   Command="{Binding EditEintragCommand}"   CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" Text="&#xf040;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
                <Button Grid.Column="4" BindingContext="{Binding Source={x:Reference ArbeitsEinträgeList}, Path=BindingContext}" Command="{Binding DeleteEintragCommand}"  CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" Text="&#xF00D;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
              </Grid>
            </ViewCell.View>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

Vous définissez donc la source de liaison pour référencer le contexte de liaison de la vue de liste (c'est-à-dire votre modèle de vue ou "ArbeitsEinträgeList". Vous pouvez également définir le paramètre de commande comme étant le contexte de liaison de chaque élément individuel. Comme vous pouvez le voir, j'ai x: Name = "Item" sur la grille et CommandParameter = "{Binding Source = {x: Reference Item}, Path = BindingContext}".

Simplement, déclarer des commandes comme celle-ci vous permet de définir une commande générique dans votre modèle de vue et lorsque la commande est exécutée avec le paramètre de commande comme contexte de liaison de l'élément individuel.

 public ICommand DeleteEintragCommand
        {
            get
            {
                return new Command((e) =>
                    {
                        var item = (e as MyModelObject);
                        // delete logic on item
                    });
            }
        }
37
DParry
12
Joehl

Si vous souhaitez lier le clic sur le bouton, vous pouvez également essayer d'utiliser l'événement Clicked dans l'attribut Button Voici mon code et son travail pour moi

  <ListView x:Name="lst1" RowHeight="80">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Vertical" Padding="8,0,8,0">
                        <Label Text="{Binding Fname}" TextColor="#000" FontSize="14" LineBreakMode="TailTruncation" />
                        <Label Text="{Binding Mobile}" TextColor="#000" LineBreakMode="TailTruncation" />
                        <Button Text="Remove" Clicked="Delete" CommandParameter="{Binding ID}" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

et côté code, vous pouvez simplement implémenter la méthode de suppression avec un argument comme

   public void Delete(Object Sender, EventArgs args)
    {
        Button button = (Button)Sender;
        string ID = button.CommandParameter.ToString();
        // Do your Stuff.....
    }
5
Ankit

Voici une autre chose qui peut vous surprendre. La liaison à la commande ne se produira jamais si vous définissez accidentellement votre ICommand dans le ViewModel en tant que propriété privée.

0
Blanthor