【问题标题】:Xamarin Forms Button Command binding inside a ListViewListView 内的 Xamarin 表单按钮命令绑定
【发布时间】:2017-04-16 06:09:07
【问题描述】:

我有以下问题,在我看来我有一个 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 中是我需要的一切,我已经使用不在列表视图中的按钮测试了命令,并且它运行良好。

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

【问题讨论】:

    标签: c# xaml listview xamarin.forms


    【解决方案1】:

    一月,

    由于您使用了列表视图并且您的命令位于 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
                        });
                }
            }
    

    【讨论】:

    • 非常感谢。您的解决方案正在运行。竖起大拇指:)
    • 如果DataTemplate 是从其他文件中定义并像这样检索:&lt;dataTemplate:CustomAdapter /&gt;
    • 我正在尝试按照这个来解决我的问题,但没有运气。有什么帮助吗? stackoverflow.com/questions/62718381/…
    【解决方案2】:

    那是因为您绑定到 EintragList 属性中的一个项目(这就是您绑定到 BeginnEnde 等文本属性的原因)。命令绑定会尝试从您的列表中而不是从您的视图模型中获取单个项目中的命令。

    选项 1:您在项目类中设置命令并在那里处理水龙头。

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

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

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

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

    CommandParameter="{Binding .}"
    

    另外:当您使用外部模板显示列表中的项目时,您可以尝试something I described in another answer(原理相同)。

    【讨论】:

    • &lt;TapGestureRecognizer Command="{Binding Source={x:Reference ListElementView}, Path=BindingContext.OpenElement}" CommandParameter="{Binding Id}" /&gt;
    【解决方案3】:

    如果你想绑定按钮点击,你也可以尝试在按钮属性中使用 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>
    

    在代码方面,您可以简单地使用类似的参数实现删除方法

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

    【讨论】:

    • 比其他方法简单 100 倍...我只知道你不应该做所有这些!
    【解决方案4】:

    这里还有一件事会让你大吃一惊。如果您不小心将 ViewModel 中的 ICommand 定义为私有属性,则不会发生与命令的绑定。

    【讨论】:

      猜你喜欢
      • 2019-05-11
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 2014-09-07
      • 2019-12-13
      • 1970-01-01
      • 2011-04-08
      相关资源
      最近更新 更多