xamarin表单Listview多选

时间:2019-12-17 12:04:31

标签: listview xamarin.forms xamarin.android

我有xamarin.forms应用程序,其中包含一个列表视图。我要实现的是多选择列表视图并执行一些操作。当前,listview包含一个Item tapped事件,它将打开另一个页面。当用户像其他所有应用程序(例如,消息,whatsapp等)中一样握住列表视图项单元格时,如何实现多重选择listview。我的粗略计划是,如果以某种方式实现了长按活动,我将在列表视图中显示复选框。

那么,多选列表视图的最佳方法是什么?按住列表视图项单元格是否可以启用它?

感谢您的帮助。

编辑1 :我使用了 Jason 建议的“收藏夹”视图。它提供了单个和多个选择模式,效果很好。但是,当用户按住单个单元格时,如何将集合视图的选择模式从单个更改为多个?

编辑2 :如 LeonLu-MSFT 所建议,对于长按事件,我使用了 alexdunn.org 的效果。但是我没有使用MVVM模式。我正在后面的代码上实现它。因此,根据alexdunn.org的文章link,它可以根据命令运行。如何使用命令在后端C#上获得长按事件?

具有长按效果的“我的列表”视图。

 <ListView  x:Name="TimesheetListView"  ItemsSource="{Binding} " 
              HasUnevenRows="True"                                                                        
              HeightRequest="{Binding Path=Height, Source={x:Reference ListLayout}}"
              CachingStrategy="RecycleElement"
              SeparatorVisibility="None"                                       
              BackgroundColor="Transparent"                      
              HorizontalOptions="FillAndExpand"                        
              VerticalOptions="FillAndExpand">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <ViewCell.View>
                                    <Frame  BorderColor="LightGray" 
                                    CornerRadius="5" BackgroundColor="White" 
                                    Margin="2" Padding="5" HasShadow="False"
                                    Text="Long Press Me!" effects:LongPressedEffect.Command="{Binding ShowAlertCommand}"
                                    effects:LongPressedEffect.CommandParameter="{Binding .}"
                                    >
                                                         <Frame.Effects>
                                    <effects:LongPressedEffect />
                                    </Frame.Effects>        
                                    <Label Text="Lognpress" FontSize="Micro" TextColor="Black"  VerticalOptions="Center">
                                    </Label>                                
                                    </Frame>
                                </ViewCell.View>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

如何在后端获取命令?

3 个答案:

答案 0 :(得分:1)

您不能直接通过Portable实现此功能,但可以通过特定于平台的功能来实现。

注意:对于复选框之类的多项选择,您可以在模型类中创建属性,例如IsSelected,然后基于此属性,选中并取消选中复选框。

创建CustomView以在ListView中呈现模板,如下所示,其中,公开用于处理MVVM中的hold操作的命令。以及用于从渲染器引发保持操作的界面。

public interface ICustomViewController : IViewController
{
    void SendHoldAction();
}

public class CustomView : ContentView, ICustomViewController
{
    public CustomView()
    {
    }

    public static readonly BindableProperty HoldCommandProperty = BindableProperty.Create("HoldCommand", typeof(Command), typeof(CustomView), null);

    public Command HoldCommand
    {
        get { return (Command)GetValue(HoldCommandProperty); }
        set { SetValue(HoldCommandProperty, value); }
    }

    public void SendHoldAction()
    {
        HoldCommand.Execute(this.BindingContext);
    }
}

自定义视图的XAML部分如下所示,

<ListView x:Name="listView" 
        ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <local:CustomView HoldCommand="{Binding BindingContext.HoldCommand, Source={x:Reference listView}}">
                    <Label Text="{Binding Name}" />
                </local:CustomView>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

下面 Android 的渲染器部分

public class CustomViewRenderer : ViewRenderer<CustomView, Android.Views.View>
{
    public CustomViewRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<CustomView> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            if (this.Control == null)
                this.SetNativeControl(new Android.Views.View(this.Context));

            if (Control != null)
            {
                Control.LongClickable = true;
                Control.SetOnLongClickListener(new ContentViewLongClickListener(this));
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (this.Control != null)
            {
                Control.SetOnLongClickListener(null);
            }
        }

        base.Dispose(disposing);
    }

    private class ContentViewLongClickListener : Java.Lang.Object, IOnLongClickListener
    {
        private readonly CustomViewRenderer viewRenderer;

        public ContentViewLongClickListener(CustomViewRenderer customViewRenderer)
        {
            viewRenderer = customViewRenderer;
        }

        public bool OnLongClick(Android.Views.View v)
        {
            viewRenderer?.Element?.SendHoldAction();
            return true;
        }
    }
}

同样,您可以在 iOS 上实现它。

答案 1 :(得分:0)

要获取任何控件的长按事件,请在共享代码中创建一个名为 CustomView

的类
public class CustomView: ContentView
    {
        public event EventHandler<EventArgs> LongPressEvent;

        public void RaiseLongPressEvent()
        {
            if (IsEnabled)
            LongPressEvent?.Invoke(this, EventArgs.Empty);
        }

    }

在android中, 创建了一个名为 LongTouchCustomRender

的类
 public class LongTouchCustomRender : ViewRenderer<CustomView, Android.Views.View>
    {
        private CustomViewListener _listener;
        private GestureDetector _detector;

        public CustomViewListener Listener
        {
            get
            {
                return _listener;
            }
        }

        public GestureDetector Detector
        {
            get
            {
                return _detector;
            }
        }

        protected override void OnElementChanged(ElementChangedEventArgs<CustomView> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement == null)
            {
                GenericMotion += HandleGenericMotion;
                Touch += HandleTouch;

                _listener = new CustomViewListener(Element);
                _detector = new GestureDetector(_listener);
            }
        }

        protected override void Dispose(bool disposing)
        {
            GenericMotion -= HandleGenericMotion;
            Touch -= HandleTouch;

            _listener = null;
            _detector?.Dispose();
            _detector = null;

            base.Dispose(disposing);
        }

        void HandleTouch(object sender, TouchEventArgs e)
        {
            _detector.OnTouchEvent(e.Event);
        }

        void HandleGenericMotion(object sender, GenericMotionEventArgs e)
        {
            _detector.OnTouchEvent(e.Event);
        }
    }

    public class CustomViewListener : GestureDetector.SimpleOnGestureListener
    {
        readonly CustomView _target;

        public CustomViewListener(CustomView s)
        {
            _target = s;
        }

        public override void OnLongPress(MotionEvent e)
        {
            _target.RaiseLongPressEvent();

            base.OnLongPress(e);
        }
    }

在ios中创建的名为 LongTouchCustomRender

的类
  public class LongTouchCustomRender : ViewRenderer<CustomView, UIView>
        {
            UILongPressGestureRecognizer longPressGestureRecognizer;
            protected override void OnElementChanged(ElementChangedEventArgs<CustomView> e)
            {
                longPressGestureRecognizer = longPressGestureRecognizer ??
                    new UILongPressGestureRecognizer(() =>
                    {
                        Element.RaiseLongPressEvent();
                    });

                if (longPressGestureRecognizer != null)
                {
                    if (e.NewElement == null)
                    {
                        this.RemoveGestureRecognizer(longPressGestureRecognizer);
                    }
                    else if (e.OldElement == null)
                    {
                        this.AddGestureRecognizer(longPressGestureRecognizer);
                    }
                }
            }
        }

在列表视图的Viewcell内,

<local:CustomView LongPressEvent="Handle_LongPress" />

像这样处理点击

void Handle_LongPressEvent(object sender, System.EventArgs e)
{
    //handle long press event here
}

Link那里得到了答案

答案 2 :(得分:0)

您可以将boxview添加到布局中。单击后,就可以像选择颜色一样更改颜色(您也可以直接更改布局的颜色,不需要添加boxview)。然后使用按钮处理所有选定的条。