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="" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
<Button Grid.Column="4" Command="{Binding DeleteEintragCommand}" Text="" 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
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="" 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="" 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
});
}
}
C'est parce que vous vous liez à un élément de votre propriété EintragList
c'est pourquoi votre liaison aux propriétés de texte comme Beginn
et Ende
fonctionne). Et la liaison de commande essaie d'atteindre une commande en un seul élément à partir de votre liste et non à partir de votre modèle de vue.
Option 1: vous définissez la commande dans votre classe d'objets et vous y manipulez le robinet.
Option 2: indiquez à votre liaison que la source doit être votre page (et non l'élément unique):
Command="{Binding BindingContext.EditEintragCommand, Source={x:Reference Name=MyPageName}}"
Assurez-vous simplement que le nom de l'élément racine de vos pages est défini x:Name="MyPageName"
Pour savoir quel élément déclenche la commande, vous pouvez définir la propriété CommandParameter, qui est ensuite également envoyée à la commande en tant qu'objet:
CommandParameter="{Binding .}"
De plus: lorsque vous utilisez des modèles externes pour afficher les éléments de votre liste, vous pouvez essayer --- (quelque chose que j'ai décrit dans une autre réponse (même principe).
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.....
}
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.