Xamarin.forms Flexlayout不适用于命令和命令参数

Xamarin.forms Flexlayout不适用于命令和命令参数,xamarin.forms,Xamarin.forms,我正在尝试使用flexlayout,它很棒,但现在对于堆栈布局中的每个项目,我需要添加点击的手势器、命令等 无论我尝试什么都不起作用。唯一起作用的是stacklayout.TapGestureRecognizer,但只要我尝试使用该命令,它就不起作用 我甚至试过 并添加了commandparameter可绑定属性,但也不起作用 如何将带有commandparameter的命令添加到flexlayout。下面是我的代码 <FlexLayout BindableLayout.ItemsSo

我正在尝试使用flexlayout,它很棒,但现在对于堆栈布局中的每个项目,我需要添加点击的手势器、命令等

无论我尝试什么都不起作用。唯一起作用的是stacklayout.TapGestureRecognizer,但只要我尝试使用该命令,它就不起作用

我甚至试过 并添加了commandparameter可绑定属性,但也不起作用

如何将带有commandparameter的命令添加到flexlayout。下面是我的代码

  <FlexLayout BindableLayout.ItemsSource="{Binding Customers}"
                                         AlignContent="Start"
                                         AlignItems="Start"
                                         Direction="Row"
                                         JustifyContent="Start"
                                         Wrap="Wrap">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <StackLayout                            
                        FlexLayout.AlignSelf="Start"
                        FlexLayout.Basis="50%">
                        <!--<StackLayout.GestureRecognizers>
                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
                        </StackLayout.GestureRecognizers>-->
                        <Frame>
                            <!--<Frame.GestureRecognizers>
                                <TapGestureRecognizer 
                                    Command="{Binding ItemTappedCommand}" 
                                    CommandParameter="{Binding .}" />
                            </Frame.GestureRecognizers>-->
                            <StackLayout>
                                <Label Text="whatever"></Label>
                                <!--<Image Source="myimage.png">
                                    <Image.GestureRecognizers>
                                        <TapGestureRecognizer Command="{Binding ItemTappedCommand}" CommandParameter="AAAA"
                                                              NumberOfTapsRequired="1"></TapGestureRecognizer>
                                    </Image.GestureRecognizers>
                                </Image>-->
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
            <!--<FlexLayout.Behaviors>
                <behaviors:FlexLayoutItemTappedBehavior
                    Command="{Binding ItemTappedCommand2}"  CommandParameter="{Binding .}"/>
            </FlexLayout.Behaviors>-->

        </FlexLayout>

FlexLayout可能会错过触摸事件和命令,请尝试使用行为来实现它

创建从
行为继承的新类


关于可重用事件到CommandBehavior,您可以参考。

FlexLayout可能会错过触摸事件和命令,请尝试使用行为来实现它

创建从
行为继承的新类


关于ReusableEventToCommandBehavior,您可以参考。

Hi,这是forms和VS的版本。@JuniorJiang MSFT VS 2019 XF 4.0.0.618610Okey,我已经更新了一个解决方案以供参考。如果works让我知道。我已经在Xamain.forms 4.1和VS 2019中进行了测试,它可以工作。您可以尝试更新Xamarin.forms.Hi,这是forms和VS的版本。@JuniorJiang MSFT VS 2019 XF 4.0.0.618610Okey,我已经更新了一个解决方案以供参考。如果可行,请告诉我。我已经在Xamain.forms 4.1和VS 2019中进行了测试,它可以工作。你可以尝试更新Xamarin.Forms.Jiang,我也这样做了,但是当命令启动时,没有commandparameter,我甚至添加了命令参数绑定到属性,但没有。I当前的建议您如何知道您单击了哪个项目?@developer9969是的,这无法知道要单击哪个项目。@developer9969如果要在此解决方案中添加命令参数,需要为
FlexLayoutItemTappedBehavior
添加Paramater
BindableProperty
@Jiang奇妙的帮助仍然没有解决,但我正在继续。Jiang我也这样做了,但是当命令触发时,没有commandparameter,我甚至添加了绑定到属性的命令参数,但什么都没有。我当前的建议您如何知道您单击了哪个项目?@developer9969是的,这无法知道要单击哪个项目。@developer9969如果要在此解决方案中添加命令参数,需要为
FlexLayoutItemTappedBehavior
添加Paramater
BindableProperty
@help仍然没有解决,但我正在继续。
public class FlexLayoutItemTappedBehavior : Behavior<FlexLayout>
{
    public static readonly BindableProperty CommandProperty =
        BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(FlexLayoutItemTappedBehavior), defaultBindingMode: BindingMode.OneWay);

    public static readonly BindableProperty ParamaterProperty =
        BindableProperty.Create(nameof(Paramater), typeof(object), typeof(FlexLayoutItemTappedBehavior), defaultBindingMode: BindingMode.OneWay);

    public ICommand Command
    {
        get => (ICommand)this.GetValue(CommandProperty);
        set => this.SetValue(CommandProperty, value);
    }

    public object Paramater
    {
        get => (object)this.GetValue(ParamaterProperty);
        set => this.SetValue(ParamaterProperty, value);
    }

    protected override void OnAttachedTo(FlexLayout bindable)
    {
        base.OnAttachedTo(bindable);

        if (bindable.BindingContext != null)
        {
            this.BindingContext = bindable.BindingContext;
        }

        bindable.BindingContextChanged += this.OnFlexLayoutBindingChanged;
        bindable.ChildAdded += this.OnFlexLayoutChildAdded;
    }

    protected override void OnDetachingFrom(FlexLayout bindable)
    {
        base.OnDetachingFrom(bindable);

        bindable.BindingContextChanged -= this.OnFlexLayoutBindingChanged;
        bindable.ChildAdded -= this.OnFlexLayoutChildAdded;

        foreach (var child in bindable.Children)
        {
            if (child is View childView && childView.GestureRecognizers.Any())
            {
                var tappedGestureRecognizers = childView.GestureRecognizers.Where(x => x is TapGestureRecognizer).Cast<TapGestureRecognizer>();
                foreach (var tapGestureRecognizer in tappedGestureRecognizers)
                {
                    tapGestureRecognizer.Tapped -= this.OnItemTapped;
                    childView.GestureRecognizers.Remove(tapGestureRecognizer);
                }
            }
        }
    }

    private void OnFlexLayoutBindingChanged(object sender, EventArgs e)
    {
        if (sender is FlexLayout flexLayout)
        {
            this.BindingContext = flexLayout.BindingContext;
        }
    }

    private void OnFlexLayoutChildAdded(object sender, ElementEventArgs args)
    {
        if (args.Element is View view)
        {
            var tappedGestureRecognizer = new TapGestureRecognizer();
            tappedGestureRecognizer.Tapped += this.OnItemTapped;

            view.GestureRecognizers.Add(tappedGestureRecognizer);
        }
    }

    private async void OnItemTapped(object sender, EventArgs e)
    {
        if (sender is VisualElement visualElement)
        {
            var animations = new List<AnimationBase>();
            var scaleIn = new ScaleToAnimation
            {
                Target = visualElement,
                Scale = .95,
                Duration = "50"
            };
            animations.Add(scaleIn);

            var scaleOut = new ScaleToAnimation
            {
                Target = visualElement,
                Scale = 1,
                Duration = "50"
            };
            animations.Add(scaleOut);

            var storyBoard = new StoryBoard(animations);
            await storyBoard.Begin();
        }

        if (sender is BindableObject bindable && this.Command != null && this.Command.CanExecute(null))
        {
            object resolvedParameter;
            if (Paramater != null)
            {
                resolvedParameter = Paramater;
            }
            else
            {
                resolvedParameter = e;
            }
            if (Command.CanExecute(resolvedParameter))
            {
                this.Command.Execute(bindable.BindingContext);
            }
        }
    }
}
<FlexLayout.Behaviors>
    <behaviors:FlexLayoutItemTappedBehavior
        Command="{Binding NavigateToDetailCommand}" Paramater="{Binding .}"/>
</FlexLayout.Behaviors>