Xamarin - очистка выбора ListView

Я действительно работаю с этим фрагментом кода

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

Но в настоящее время я не могу понять, как мне интегрировать его с приведенным выше кодом :)


person Guido Magrin    schedule 05.12.2014    source источник
comment
Во-первых, для этого не нужно разделять события ItemSelected. Я думаю, вы можете просто вызвать это listview.SelectedItem = null, чтобы сбросить свойство listview selecteditem. Либо до, либо после того, как вы нажмете новую страницу. Во-вторых, может быть лучше использовать ItemTapped для начала перехода страницы и использовать itemselected для обработки / передачи данных в следующее представление.   -  person Jared Reeves    schedule 05.12.2014


Ответы (5)


Вы дважды назначаете обработчик ItemSelected, что является плохой идеей. Все, что вам нужно сделать, это добавить эту строку в существующий обработчик ItemSelected.

  ((ListView)sender).SelectedItem = null; 
person Jason    schedule 05.12.2014
comment
Спасибо за быстрый ответ! В любом случае, я уже пробовал это ранее, все, что я получаю, это: 1drv.ms/1s0K0cO, как только я нажимаю на любом элементе в ListView - person Guido Magrin; 05.12.2014
comment
Если вы добавите эту строку в начало обработчика ItemSelected, все последующие ссылки на SelectedItem будут прерваны, потому что теперь он равен нулю. Попробуйте добавить его в конец обработчика после того, как будет выполнен весь остальной код, ссылающийся на него. - person Jason; 05.12.2014
comment
Что ж, если вы посмотрите на скриншот, который я там связал, я делаю то, что вы говорите, но все равно все рушится :( - person Guido Magrin; 06.12.2014
comment
Попробуйте проверить SelectedItem! = Null, прежде чем вводить этот большой блок IF. - person Jason; 06.12.2014

Я хотел бы добавить к ответу Джейсона, потому что в нем отсутствует важная информация. Когда вы устанавливаете для свойства 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;
}
person Rodolfo De Los Santos    schedule 15.08.2015
comment
Это правильный ответ, спасибо, мужик, вот суть, подтверждающая вашу идею gist.github.com/ajonno/6ae0d2aebfaec79d2ec9 / а> - person Badr Bellaj; 23.10.2018

У меня была такая же проблема, но другие решения мне не помогли. Поскольку мне нужно было передать настраиваемый объект на следующую страницу, я аннулировал ссылку на выбранный элемент и использовал ссылку на выбранный элемент для своего настраиваемого объекта.

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

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

};
person Kelsey    schedule 22.12.2016

ListView.SelectedItem не имеет установщика (я имею в виду простой Xamarin Android, а не Xamarin.Forms). Предлагаю использовать следующий код:

private void DeselectEntities()
{
    if (this.listView != null && this.listView.CheckedItemPositions != null)
    {
        this.listView.CheckedItemPositions.Clear();
    }
}
person Alexander S    schedule 12.02.2019

Я уважаю все полученные ответы, но в приложении MVVM вам лучше избегать слишком большого количества кода. Обычно я делаю следующее:

  1. Свяжите ItemsSource из ListView, как обычно, с ObservableCollection, где T - это CarViewModel в моем случае

  2. Установите SelectionMode = None: это позволяет избежать выбора SelectedItem при нажатии.

  3. Используйте EventToCommandBehavior (я использую свою собственную реализацию; см. Github.com или использую тот из Prism.Forms), чтобы привязать событие ItemTapped ListView к моей команде ViewModel SelectedCarChangedCommand.

  4. В SelectedCarChangedCommand ViewModel вы получите элемент с вкладками как объект ItemTappedEventArgs.

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