【问题标题】:Xamarin - clearing ListView selectionXamarin - 清除 ListView 选择
【发布时间】:2014-12-05 00:17:14
【问题描述】:

我实际上正在使用这段代码

using System;
using Xamarin.Forms;
using System.Diagnostics;

namespace CryptoUI
{
    public class HomePage : Xamarin.Forms.MasterDetailPage
    {
        public HomePage()
        {
        // Set up the Master, i.e. the Menu
            Label header = new Label
            {
                Text = "MENU",
                Font = Font.SystemFontOfSize(20, FontAttributes.Bold),
                HorizontalOptions = LayoutOptions.Center
            };
        // create an array of the Page names
        string[] myPageNames = {
            "Main",
            "Page 2",
            "Page 3",
        };

        // Create ListView for the Master page.
        ListView listView = new ListView
        {
            ItemsSource = myPageNames,
        };

        // The Master page is actually the Menu page for us
        this.Master = new ContentPage
        {
            Title = "Test",
            Content = new StackLayout
            {
                Children = 
                {
                    header, 
                    listView
                },
            }
        };

        // Define a selected handler for the ListView contained in the Master (ie Menu) Page.
        listView.ItemSelected += (sender, args) =>
        {
            // Set the BindingContext of the detail page.
            this.Detail.BindingContext = args.SelectedItem;

            string currentPage = this.GetType().Name.ToString();

            // This is where you would put your “go to one of the selected pages”
            if(listView.SelectedItem.Equals("Main") && !currentPage.Equals("HomePage")){
                AsyncPush(new HomePage());
            }
            else if(listView.SelectedItem.Equals("Page 2") && !currentPage.Equals("SecondPage")){
                AsyncPush(new SecondPage());
            }
            else if(listView.SelectedItem.Equals("Page 3") && !currentPage.Equals("ThirdPage")){
                AsyncPush(new ThirdPage());
            }               

            // Show the detail page.
            this.IsPresented = false;
        };
            listView.ItemSelected += (senders, e) => {
                if (e.SelectedItem == null) return; // don't do anything if we just de-selected the row
                // do something with e.SelectedItem
                ((ListView)senders).SelectedItem = null; // de-select the row
            };

        // Set up the Detail, i.e the Home or Main page.
        Label myHomeHeader = new Label
        {
            Text = "Home Page",
            HorizontalOptions = LayoutOptions.Center
        };

        string[] homePageItems = { "Alpha", "Beta", "Gamma" };
        ListView myHomeView = new ListView {
            ItemsSource = homePageItems,
        };

        var myHomePage = new ContentPage();

        myHomePage.Content = new StackLayout
        {
            Children = 
            {
                myHomeHeader, 
                myHomeView
            } ,
        };
        this.Detail = myHomePage;
    }

        public async void AsyncPush(Page page)
        {
            await Navigation.PushAsync(page);
        }
    }
}

此代码实际上显示了一个简单的 FlyOut 菜单,使用 Xamarin Forms 技术。 我目前正在尝试了解如何在选择要前往的页面后轻松清除 ListView 选择!

我在 Xamarin 的开发者网站 (http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/) 上找到了这段代码;

listView.ItemSelected += (sender, e) => {
    if (e.SelectedItem == null) return; // don't do anything if we just de-selected the row
    // do something with e.SelectedItem
    ((ListView)sender).SelectedItem = null; // de-select the row
};

但我目前无法弄清楚我应该如何将它与上面的代码集成:)

【问题讨论】:

  • 首先,您不需要单独的 ItemSelected 事件来执行此操作。我想你可以调用这个listview.SelectedItem = null 来重置listview selecteditem 属性。在您推送新页面之前或之后。其次,使用ItemTapped 启动页面转换并使用 itemselected 处理/传递数据到下一个视图可能会更好。
  • 你的代码: public async void AsyncPush(Page page) { await Navigation.PushAsync(page); } 引入了一个错误,允许用户双击链接并打开多个页面到导航堆栈。

标签: c# listview xamarin xamarin-studio xamarin.forms


【解决方案1】:

我想补充 Jason 的答案,因为它遗漏了一些重要信息。当您将 ListView SelectedItem 属性设置为 null 时,它将再次触发 ItemSelected 事件。所以如果没有空检查,就会抛出异常。

它应该是这样的:

void ItemSelected(object sender, EventArgs args)
{
    if (((ListView)sender).SelectedItem == null)
      return;
    //Do stuff here with the SelectedItem ...
    ((ListView)sender).SelectedItem = null;
}

【讨论】:

【解决方案2】:

您分配了两次 ItemSelected 处理程序,这是一个坏主意。您所要做的就是将此行添加到您现有的 ItemSelected 处理程序

  ((ListView)sender).SelectedItem = null; 

【讨论】:

  • 感谢您的及时答复!无论如何,我之前已经尝试过,我得到的只是:1drv.ms/1s0K0cO 只要我点击 ListView 中的任何元素
  • 如果您将该行添加到 ItemSelected 处理程序的顶部,那么对 SelectedItem 的所有后续引用都将中断,因为它现在为空。在所有其他引用它的代码完成后,尝试将它添加到处理程序的底部。
  • 好吧,如果你看一下我在那里链接的截图,我正在做你所说的,仍然一切都在崩溃:(
  • 在输入大 IF 块之前尝试检查 SelectedItem != null。
【解决方案3】:

我遇到了同样的问题,但其他解决方案对我不起作用。由于我需要将自定义对象传递到下一页,因此我取消了选定的项目引用并将项目点击引用用于我的自定义对象。

listView.ItemTapped += async (sender, e) =>{

    await Navigation.PushAsync(new DetailPage(e.Item as CustomObject));
    ((ListView)sender).SelectedItem = null;

};

【讨论】:

  • 由于您在导航上是异步的,因此您引入了一个错误,如果用户双击足够快,则可以将两个项目推送到导航堆栈。您必须按两次后退按钮才能清除两个页面。
【解决方案4】:

ListView.SelectedItem 没有设置器(我的意思是简单的 Xamarin Android - 不是 Xamarin.Forms)。我建议使用以下代码:

private void DeselectEntities()
{
    if (this.listView != null && this.listView.CheckedItemPositions != null)
    {
        this.listView.CheckedItemPositions.Clear();
    }
}

【讨论】:

    【解决方案5】:

    我尊重所有给出的答案,但在 MVVM 应用程序中,您最好避免使用太多代码。我通常做的是:

    1. 像往常一样将 ListView 的 ItemsSource 绑定到 ObservableCollection,在我的例子中,T 是 CarViewModel

    2. 设置 SelectionMode="None":这确实避免了在点击时选择 SelectedItem

    3. 使用 EventToCommandBehavior(我使用我自己的实现;参见 github.com 或使用 Prism.Forms 中的那个)将 ListView 的 ItemTapped 事件绑定到我的 ViewModel 命令 SelectedCarChangedCommand。

    4. 在 ViewModel 的 SelectedCarChangedCommand 中,您将收到选项卡式项目作为 ItemTappedEventArgs 对象。

       <ListView
         x:Name="CarsListView"
         ItemsSource="{Binding Cars}"
         SelectionMode="None">
           <ListView.Behaviors>
               <behaviors:EventToCommandBehavior
                   Command="{Binding SelectedCarChangedCommand}"
                   EventName="ItemTapped" />
           </ListView.Behaviors>
      

    【讨论】:

    • 通常这很好,但我发现在推送导航堆栈的情况下,命令无效,因为您可以双击三次 10 并打开许多实例。
    • 是的。您可以通过在 SelectedCarChangedCommand 实现中设置 canExecute 标志来处理此类多点触控情况。我想这就是我解决它的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    相关资源
    最近更新 更多