Xamarin Forms中ListView内的按钮命令绑定

36

我有以下问题,我有一个Listview视图。在这个Listview中,我希望有两个按钮。一个用于编辑项目,一个用于删除项目。

这是我的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>

在我的ViewModel中有我需要的一切,我已经用不在listview中的按钮测试了命令,并且它完美地工作。

如果我悬停在绑定上,消息“无法解析符号'...'”将出现

无法解析符号

4个回答

63

Jan,

由于您使用了列表视图,并且您的命令位于DataTemplate内部,因此绑定附加到了ItemSource中每个模型的绑定上下文。

解决此问题的一种方法是执行以下操作:

<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>

所以,您将绑定源设置为引用列表视图的绑定上下文(即您的视图模型或“ArbeitsEinträgeList”)。您还可以将命令参数设置为每个单独项目的绑定上下文。正如您所看到的,我在网格上使用了x:Name="Item"和CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}"。

简而言之,像这样声明命令允许您在视图模型中定义通用命令,并且当使用命令参数执行命令时,其参数是各个项目的绑定上下文。

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

2
非常感谢。你的解决方案有效。点赞 :) - JanMer
3
如果DataTemplate是从其他文件中定义的并且通过<dataTemplate:CustomAdapter />这种方式检索,该怎么办? - mr5
我正在尝试按照这个来解决我的问题,但是没有成功。有人可以帮忙吗?https://stackoverflow.com/questions/62718381/button-in-custom-viewcell-xamarin-tableview-c-sharp - Steven Marcus

22

这是因为你绑定到了你的EintragList属性中的一个项目(这就是为什么你可以绑定到像BeginnEnde这样的文本属性)。而命令绑定试图从列表中的单个项目中找到命令,而不是来自视图模型。

选项1:在你的项类中设置命令并在那里处理点击事件。

选项2:告诉你的绑定源应该是你的页面(而不是单个项):

Command="{Binding BindingContext.EditEintragCommand, Source={x:Reference Name=MyPageName}}"

请确保您页面的根元素名称设置为x:Name="MyPageName"

要知道哪个项目触发了命令,您可以设置CommandParameter属性,该属性也将作为对象发送到命令中:

CommandParameter="{Binding .}"

此外:当您使用外部模板来显示列表中的项目时,您可以尝试我在另一个答案中描述的方法(相同的原则)。


1
<TapGestureRecognizer Command="{Binding Source={x:Reference ListElementView}, Path=BindingContext.OpenElement}" CommandParameter="{Binding Id}" /> - lsaudon

17

如果您想绑定按钮点击事件,您也可以尝试在Button属性中使用Clicked事件。以下是我的代码,对我有效。

  <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>

在代码方面,您可以简单地实现一个带有参数的删除方法,例如:

and code side you can simply implement delete method with an argument like

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

比另一种方法简单100倍...我就知道不应该做那么多! - Anthony Griggs

0

这里有另一件可能会让你感到意外的事情。如果你不小心将ICommand定义为私有属性,那么绑定命令将永远不会发生在ViewModel中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接