Как отключить выделение в ListView в Xamarin.Forms

Я работаю с Xamarin.Forms и XAML, и я пытаюсь создать приложение, в котором хранится список продуктов. Я перечислил список продуктов в ListView. Это прекрасно работает. Вот мой XAML:

<ListView x:Name="listSushi"
        ItemsSource="{x:Static local:myListSushi.All}"
        SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
        RowHeight="{StaticResource rowHeight}"
        >
<ListView.ItemTemplate>
  <DataTemplate>
    <ViewCell>
      <ViewCell.View>
        <StackLayout Padding="5, 5, 0, 5"
                     Orientation="Horizontal"
                     Spacing="15">
          <StackLayout>
            <Image Source="{Binding ImageSource}" />
          </StackLayout>

          <StackLayout Padding="0, 0, 0, 0"
                       VerticalOptions="Center"
                       HorizontalOptions="FillAndExpand">                
                <Label Text="{Binding Name}"
                   Font="Bold, Medium" />
                <Label Text="{Binding Description}" 
                    Font="Small"/>
          </StackLayout>

          <StackLayout Orientation="Horizontal"
                        Padding="0, 0, 10, 0">
            <Button Text=" - " 
                    HorizontalOptions="EndAndExpand"
                    VerticalOptions="FillAndExpand"
                    Command="{Binding DeleteSushiCommand}"
                    CommandParameter="{Binding Name}"
                    />
            <Label VerticalOptions="Center" 
                   Text="{Binding Number,StringFormat='{0}'}"
                   TextColor="Black"/>
            <Button Text=" + " 
                    HorizontalOptions="EndAndExpand"
                    VerticalOptions="FillAndExpand" 
                    Command="{Binding AddSushiCommand}"
                    CommandParameter="{Binding Name}"
                    />
            </StackLayout>
        </StackLayout>
      </ViewCell.View>
    </ViewCell>
  </DataTemplate>
</ListView.ItemTemplate>

У меня просто проблема, что если я нажму на ячейку моего списка, ячейка будет выделена и останется в центре внимания. Я пытаюсь отключить его с помощью этого кода в файле xaml.cs

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

Но когда я касаюсь ячейки, теперь мой список прокручивается автоматически. Это очень странно.

Кто-нибудь знает, является ли это ошибкой или знает какое-либо исправление, например, если есть свойство, в котором я могу отключить выделение?

Ответ 1

Вместо этого вы можете попробовать использовать событие ItemTapped, т.е.

listSushi.ItemTapped += (object sender, ItemTappedEventArgs e) => {
    // don't do anything if we just de-selected the row.
    if (e.Item == null) return;

    // Optionally pause a bit to allow the preselect hint.
    Task.Delay(500);

    // Deselect the item.
    if (sender is ListView lv) lv.SelectedItem = null;

    // Do something with the selection.
    ...
};

Я проверил это на ListView (на устройстве Android), в котором достаточно элементов для прокрутки в миксе. Я не вижу поведения автоматической прокрутки, и ваша идея установить SelectedItem равным NULL, чтобы победить выделение, прекрасно работает.

Ответ 2

Я просто нашел другой способ отключить эффект выделения. И я хотел бы поделиться этим с другими пользователями.

Вы можете сделать это прямо в xaml. Но этот метод не только отключает эффект выделения, но также отключает событие click.

Вы можете установить для IsEnabled атрибут ViewCell значение false.

<ViewCell IsEnabled="false">
    //Your Item Layout Coding
</ViewCell>

Кроме того, вы также можете отключить/активировать каждый эффект выделения элемента путем привязки:

<ViewCell IsEnabled="{Binding IsHighlightEnabled}">
    //Your Item Layout Coding
</ViewCell>

Надеюсь, что это поможет, спасибо.

Ответ 3

Я предполагаю, что вы используете MVVM. В этих случаях я назначаю null свойству после его использования. В вашей модели view вы, похоже, имеете свойство SelectedItem, так как вы привязываете его к свойству SelectedItem ListView. Поэтому я бы сделал что-то вроде этого:

private Product _selectedItem;
public Product SelectedItem
{
  get
  {
    return _selectedItem;
  }
  set
  {
    _selectedItem = value;

    //USE THE VALUE

    _selectedItem = null;
    NotifyPropertyChanged("SelectedItem");
  }
}

Ответ 4

YourList.ItemSelected+=DeselectItem;

 public void DeselectItem(object sender, EventArgs e)
  {
     ((ListView)sender).SelectedItem = null;
  }

Это должно быть полезно для вашего сценария. @dpfauwadel

Ответ 5

В iOS-методе решение не решило его для меня, мне пришлось создать CustomRenderer для представления списка и использовать его вместо этого.

NonSelectableListView.cs(в вашем проекте Forms)

using System;
using Xamarin.Forms;

namespace YourProject
{
    public class NonSelectableListView : ListView
    {
        public NonSelectableListView()
        {
        }
    }
}

NonSelectableListViewRenderer.cs(CustomRenderer в вашем проекте iOS)

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

using YourProject.iOS;
using YourProject;

[assembly: ExportRenderer(typeof(NonSelectableListView), typeof(NonSelectableListViewRenderer))]
namespace YourProject.iOS
{
    public class NonSelectableListViewRenderer : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe from event handlers and cleanup any resources
            }

            if (e.NewElement != null)
            {
                // Configure the native control and subscribe to event handlers
                Control.AllowsSelection = false;
            }
        }
    }

}