Xamarin.forms Flexlayout不适用于命令和命令参数
我正在尝试使用flexlayout,它很棒,但现在对于堆栈布局中的每个项目,我需要添加点击的手势器、命令等 无论我尝试什么都不起作用。唯一起作用的是stacklayout.TapGestureRecognizer,但只要我尝试使用该命令,它就不起作用 我甚至试过 并添加了commandparameter可绑定属性,但也不起作用 如何将带有commandparameter的命令添加到flexlayout。下面是我的代码Xamarin.forms Flexlayout不适用于命令和命令参数,xamarin.forms,Xamarin.forms,我正在尝试使用flexlayout,它很棒,但现在对于堆栈布局中的每个项目,我需要添加点击的手势器、命令等 无论我尝试什么都不起作用。唯一起作用的是stacklayout.TapGestureRecognizer,但只要我尝试使用该命令,它就不起作用 我甚至试过 并添加了commandparameter可绑定属性,但也不起作用 如何将带有commandparameter的命令添加到flexlayout。下面是我的代码 <FlexLayout BindableLayout.ItemsSo
<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
添加ParamaterBindableProperty
@Jiang奇妙的帮助仍然没有解决,但我正在继续。Jiang我也这样做了,但是当命令触发时,没有commandparameter,我甚至添加了绑定到属性的命令参数,但什么都没有。我当前的建议您如何知道您单击了哪个项目?@developer9969是的,这无法知道要单击哪个项目。@developer9969如果要在此解决方案中添加命令参数,需要为FlexLayoutItemTappedBehavior
添加ParamaterBindableProperty
@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>