Xamarin.Forms ListView的奇怪行为

时间:2019-05-26 22:29:41

标签: xamarin.forms xamarin.forms.listview

我在使用Listview时遇到问题,并且几乎要放弃upp。

我在ListView中有一个CustomButtonOnPressUp应该触发一个事件。

问题在于,当我touch按下按钮时,它触发了多个其他按钮的事件。

这是我的代码,请告诉您是否发现奇怪的地方。

  

XAML

    <StackLayout Orientation="Vertical">
                        <Label Text="Video Properties" Style="{ StaticResource HeaderContainer}"></Label>
                        <controls:YListView x:Name="lstVideosProperties" OnSelected="LstVideosProperties_OnSelected">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <ViewCell>
                                        <Grid VerticalOptions="FillAndExpand">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="2*"></ColumnDefinition>
                                                <ColumnDefinition Width="8*"></ColumnDefinition>
                                            </Grid.ColumnDefinitions>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="60"></RowDefinition>
                                            </Grid.RowDefinitions>
                                            <Image Aspect="Fill" VerticalOptions="FillAndExpand" Source="{Binding DefaultThumbnailUrl}" Grid.Row="0" Grid.Column="0"></Image>
                                            <Grid Grid.Row="0" Grid.Column="1">
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="7*"></ColumnDefinition>
                                                    <ColumnDefinition Width="3*"></ColumnDefinition>
                                                </Grid.ColumnDefinitions>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="4*"></RowDefinition>
                                                    <RowDefinition Height="6*"></RowDefinition>
                                                </Grid.RowDefinitions>
                                                <StackLayout Style="{StaticResource FormFloatLeft}" Grid.Row="0" Grid.Column="0">
                                                    <Label Text="{Binding Title}"  Style="{StaticResource Header}" />
                                                </StackLayout>
                                                <controls:CustomButton Grid.RowSpan="2"
                                                                       CommandParameter="{Binding VideoId}"
                                                                       IsEnabled="{Binding VideoId ,Converter={StaticResource Downloadable}}"
                                                                       Grid.Row="0" Grid.Column="1"
                                                                       x:Name="_btnDownload"
                                                                       OnPressUp="_btnDownload_OnPressUp"
                                                                       Image="download.png"
                                                                       HorizontalOptions="EndAndExpand"
                                                                       VerticalOptions="StartAndExpand"
                                                                       Style="{StaticResource Icon}" />
                                                <StackLayout VerticalOptions="Start" Style="{StaticResource FormFloatLeft}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
                                                    <Label Text="{Binding Views}" Style="{StaticResource UnderText}" />
                                                </StackLayout>
                                            </Grid>
                                        </Grid>
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </controls:YListView>
  

数据绑定项

 lstVideosProperties.ItemsSource = _videos;
  

自定义按钮

 public class CustomButton : Button
    {
        public CustomButton()
        {
            ColorBeforeSelection = Color.Transparent;
        }
        public Color OnPressColor { get; set; } = ((Color)Application.Current.Resources["pressed"]);
        private Color ColorBeforeSelection;
        public TextAlignment? TextAlignment { get; set; }


        public event EventHandler OnPressUp;
        public event EventHandler OnPressDown;
        public Action<double, double> SizeAllocated;

        public bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {

                _isSelected = value;

                if (_isSelected)
                {
                    if (this.BackgroundColor != OnPressColor)
                        ColorBeforeSelection = this.BackgroundColor;
                    this.BackgroundColor = OnPressColor;
                }
                else
                    this.BackgroundColor = ColorBeforeSelection;

            }
        }

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
            SizeAllocated?.Invoke(width, height);

        }

        public void OnPressed()
        {
            OnPressDown?.Invoke(this, null);
        }

        public void OnReleased()
        {
            OnPressUp?.Invoke(this, null);
        }
    }
  

CustomButtonRenderer

public class CustomButtonRenderer : ButtonRenderer
    {
        Context _context;
        public CustomButtonRenderer(Context context) : base(context)
        {
            _context = context;
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);

            var customRendererButton = e.NewElement as CustomButton;

            var control = Control as Android.Widget.Button;

            switch (customRendererButton.TextAlignment)
            {
                case Xamarin.Forms.TextAlignment.Center:
                    control.Gravity = GravityFlags.Center | GravityFlags.CenterVertical;
                    break;
                case Xamarin.Forms.TextAlignment.Start:
                    control.Gravity = GravityFlags.Left | GravityFlags.CenterVertical;

                    break;
                case Xamarin.Forms.TextAlignment.End:
                    control.Gravity = GravityFlags.End | GravityFlags.CenterVertical;
                    break;
            }

            if (!customRendererButton.IsEnabled)
            {
                control.SetBackgroundColor(new Android.Graphics.Color(
                    ContextCompat.GetColor(_context, Resource.Color.disabled_background)
                    ));
            }

            bool selected = customRendererButton.IsSelected;
            bool prevent = false;
            Timer _timer = null;
            control.Touch += (object sender, TouchEventArgs args) =>
                {
                    if (!customRendererButton.IsEnabled)
                    {
                        control.SetBackgroundColor(new Android.Graphics.Color(
                            ContextCompat.GetColor(_context, Resource.Color.disabled_background)
                            ));

                        return;
                    }

                    if (args.Event.Action == MotionEventActions.Up)
                    {
                        _timer.Stop();
                        if (!selected)
                            customRendererButton.IsSelected = false;

                        if (!prevent)
                            customRendererButton.OnReleased();
                        prevent = false; // reset
                        return;
                    }
                    else if (args.Event.Action == MotionEventActions.Down)
                    {
                        _timer?.Stop();
                        _timer = new Timer(200);
                        _timer.Elapsed += new ElapsedEventHandler((o, arg) =>
                                    {
                                        if (!selected)
                                            customRendererButton.IsSelected = false;
                                        prevent = true;
                                    });
                        _timer.Start();
                        selected = customRendererButton.IsSelected;
                        if (!customRendererButton.IsSelected)
                            customRendererButton.IsSelected = true;
                        customRendererButton.OnPressed();
                        return;
                    }
                    else if (args.Event.Action == MotionEventActions.Move)
                    {

                    }
                };
        }
    }

1 个答案:

答案 0 :(得分:0)

以这种方式绑定按钮的命令:

Command="{Binding Path=BindingContext.CommandName,Source={x:Reference root}}" CommandParameter="{Binding .}"

在页面的开头括号中将页面名称定义为“ x:Name =“ root””。(名称可以是任意值)