【问题标题】:How to disable highlight on ListView in Xamarin.Forms如何在 Xamarin.Forms 中禁用 ListView 上的突出显示
【发布时间】:2014-12-26 18:51:01
【问题描述】:

我正在使用 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>

我的问题是,如果我单击 listView 的一个单元格,该单元格会突出显示,并保持突出显示。我尝试在 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
};

但是当我触摸一个单元格时,现在我的列表会自动滚动。很奇怪。

有谁知道这是否是一个错误,或者知道一个修复方法,比如是否有一个属性可以禁用突出显示?

【问题讨论】:

  • 如果你接受了我的回答就好了。 ;-)
  • 在 v3.1 中添加了对禁用 ListView 选择的 API 支持,有关详细信息,请参阅下面的 Jesse 的answer

标签: xamarin xamarin.forms


【解决方案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 以消除突出显示的想法效果很好。

【讨论】:

  • 虽然此解决方案未选择ViewCell,但当手指短按或按住ViewCell 时,ViewCell 仍将显示“预选”状态, as viewed in this screenshot
  • 在我遇到的所有用例中,预选都是期望的行为。如此之多,以至于我更新了我的答案以包括延迟,以确保用户获得一些反馈,他们点击了他们想要的。
  • Task.Delay(500) 不会自行延迟。您必须等待它创建的任务:await Task.Delay(500);.
【解决方案2】:

当前我们可以将 ListView.SelectionMode 设置为 None 来执行此操作。 https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/interactivity

【讨论】:

  • 但是,这种方法会阻止点击。
【解决方案3】:

我刚刚找到了另一种禁用高亮效果的方法。我想与其他用户分享。

您可以直接在 xaml 中执行此操作。 但是这种方法不仅会禁用高亮效果,还会禁用点击事件。

您可以将 ViewCell 的 IsEnabled 属性设置为 false。

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

此外,您还可以通过绑定来禁用/启用每个项目的高亮效果:

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

希望对你有帮助,谢谢。

【讨论】:

  • 这将禁用突出显示,但值得注意的是,它还会禁用 ViewCell 中可能存在的任何按钮单击事件
  • 也禁用滚动。
  • 我有一个像 IsHighlightEnabled 这样的属性绑定到一个变量,当我的键盘显示或隐藏时该变量会发生变化。这意味着当我在显示键盘时点击列表项时,键盘会消失并且我的项目是可点击的。如何先屏蔽点击,关闭键盘再隐藏键盘?
  • @IanWarburton 它不会禁用滚动。 ListView 本身上的设置IsEnabled=false 会,但如果在单个单元格上使用则不会。
  • 谢谢。这让我花了很长时间试图阻止突出显示,但这非常有效。
【解决方案4】:
YourList.ItemSelected+=DeselectItem;

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

这应该对您的方案有所帮助。 @dpfauwadel

【讨论】:

  • 谢谢,这正是我要找的 :)
【解决方案5】:

我假设您正在使用 MVVM。在这些情况下,我在使用该属性后为其分配一个空值。在您的视图模型中,您似乎有一个 SelectedItem 属性,因为您将它绑定到 ListView 的 SelectedItem 属性。所以我会做这样的事情:

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

    //USE THE VALUE

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

【讨论】:

  • 这个解决方案对我有用。我已经设置了 _selectedItem = null 但这还不够;添加 NotifyPropertyChanged 是关键(或者在我的情况下是 RaisePropertyChanged,因为我使用的是 MVVM Light)。请注意,我还必须在 XAML 视图中设置 Mode=TwoWay(作为 SelectedItem 的属性)才能使其正常工作 - 即使我认为 TwoWay 应该是 Mode 的默认值,我也必须明确设置它。
  • 在我使用 Prism 的情况下,我将其简化为 public RecapListViewItem SelectedRecap { get { return null; } set { OnPropertyChanged("SelectedRecap"); } }
  • 另一个对我有用的选项是使用get=&gt; null; 的get 访问器。请注意,您不能将 SelectedItem 属性用作选定项。但这是防止项目被突出显示的快速方法。然后我使用命令绑定行为。因此,还要为列表项选择获取异步。
【解决方案6】:

iOS 标记的解决方案没有为我解决,我必须为列表视图创建一个 CustomRenderer 并改用它。

NonSelectableListView.cs(在您的表单项目中)

using System;
using Xamarin.Forms;

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

NonSelectableListViewRenderer.cs(您的 iOS 项目中的 CustomRenderer)

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

}

【讨论】:

  • Clickable - Android 等效于 AllowsSelection 属性
猜你喜欢
  • 2014-11-06
  • 1970-01-01
  • 2022-10-16
  • 2016-07-31
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 2015-03-24
相关资源
最近更新 更多