【问题标题】:How to navigate to another Page from button's Clicked event and pass listview's ItemSelected as argument?如何从按钮单击事件导航到另一个页面并将 listview Item Selected 作为参数传递?
【发布时间】:2019-08-15 05:15:23
【问题描述】:

我正在用 Xamarin Forms 编写一个适用于 Android 的应用程序。当用户单击“EditList”按钮(中间一个)时,我想将用户从一个页面导航到另一个页面,但同时我想传递一个特定类型的参数:“ShoppingList”,我从 ListView 的 ItemSelected事件,以便在下一页上显示其内容。

问题是 - 我可以获得该值的唯一方法是单击列表视图中的项目。如何从按钮中获取该列表视图项目的点击值,而无需事先点击列表视图项目?

外观

这里也是参考页面。 ListView with ShoppingList items

我正在使用 Navigation.PushAsync(),其中我还传递了一个 ShoppingListDetailViewModel 并从 SelectedItem 注入项目

OnItemSelected

这是 ListView 的 ItemSelected 事件的 OnItemSelected 事件处理程序:

        async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
        {
            var item = args.SelectedItem as ShoppingList;
            if (item == null)
                return;

            await Navigation.PushAsync(new ShoppingListDetailPage(new ShoppingListDetailViewModel(item)));

            // Manually deselect item.
            ItemsListView.SelectedItem = null;
        }

(ItemsListView 是我在 XAML 中定义的 ListView 的名称,如 x:Name="ItemsListView")

我尝试制作可能会通过 Command 参数传递购物清单对象的 Command,但我对这一切感到困惑,我认为必须有更简单的解决方案来做到这一点,而我只是看不到。

XAML

这是我的 XAML 页面,其中包含 ListView 和按钮:

<ListView x:Name="ItemsListView" 
                ItemsSource="{Binding ShoppingLists}"
                RefreshCommand="{Binding LoadItemsCommand}"
                IsPullToRefreshEnabled="true"
                IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                CachingStrategy="RecycleElement"
                ItemSelected="OnItemSelected">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="10">
                            <Label Text="{Binding Name}" 
                                HorizontalOptions="Center"/>
                                <Label  Text="{Binding BodyHighlight}" 
                                HorizontalOptions="Center" />
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <ImageButton Grid.Column="0"
                                                 Source="delete.png"> 
                                    </ImageButton>
                                    <ImageButton 
                                        Grid.Column="1" 
                                        Source="edit.png"
                                        Clicked="EditListButton_Clicked">
                                     </ImageButton>
                                    <ImageButton 
                                        Grid.Column="2" 
                                        Source="send.png" >
                                    </ImageButton>
                                </Grid>
                            </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>


【问题讨论】:

    标签: c# xamarin.forms


    【解决方案1】:

    将列表中当前项的值赋给按钮的CommandParameter

    <ImageButton Grid.Column="1" Source="edit.png" 
      Clicked="EditListButton_Clicked" CommandParameter="{Binding .}" />
    

    然后在你的处理程序中

    public void EditListButton_Clicked(object sender, EventArgs args) 
    {
      ImageButton btn = (ImageButton)sender;
    
      var item = (ShoppingList)btn.CommandParameter;
    
      if (item == null) return;
    
      await Navigation.PushAsync(new ShoppingListDetailPage(new ShoppingListDetailViewModel(item)));
    
    }
    

    【讨论】:

      【解决方案2】:

      如何从按钮中获取该列表视图项目的点击值,而无需事先点击列表视图项目?

      解决方案一:

      Xaml 代码不变,EditListButton_Clicked 如下:

      public void EditListButton_Clicked(object sender, EventArgs args) 
      {
       ImageButton btn = sender as ImageButton;
       var item = btn.BindingContext as ShoppingList;
       if (item == null) return;
       await Navigation.PushAsync(new ShoppingListDetailPage(new ShoppingListDetailViewModel(item)));
      }
      

      解决方案二:

      如jason,将CommandParameter添加到ImageButton如下:

      <ImageButton  Grid.Column="1" Source="edit.png" Clicked="EditListButton_Clicked" CommandParameter="{Binding .}>
      

      那么在EditListButton_Clicked 中是:

      public void EditListButton_Clicked(object sender, EventArgs args) 
      {
        ImageButton btn = (ImageButton)sender;
        var item = (ShoppingList)btn.CommandParameter;
        if (item == null) return;
        await Navigation.PushAsync(new ShoppingListDetailPage(new ShoppingListDetailViewModel(item)));
      }
      

      【讨论】:

      • 非常感谢。虽然我还有一个问题。你怎么知道你必须做这两个强制转换(尤其是对 btn.Binding Context)才能获得那个 ListView 项目?我不明白这一点。
      • @Tomasz 是啊,这是对BindingContext的一点理解。如果你的 ListView 的 ItemSource 绑定到 ShoppingLists,那么每个 ViewCell 都绑定到一个 ShoppingList,ViewCell。绑定中的每个元素都是一个 ShoppingList,所以这次 Button 绑定到 ShoppingList。当项目中更多地使用BindingContext时,您可以了解它的作用。docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/…
      猜你喜欢
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      相关资源
      最近更新 更多