我有一个用于控制手势的自定义控件“容器”,以及一个内部的Skiasharp可绘制控件。我要寻找的功能是,在第一步中,用户可以缩放/移动容器内的图像,然后禁用容器的手势,并且用户可以用手指绘制可见图像。它曾经可以工作几个月,但是当移至xamarin 3.x时,它开始失败。
这是容器的代码
public class GestureContainer : ContentView
{
private const double MIN_SCALE = 1;
private const double MAX_SCALE = 4;
private double startScale, currentScale;
private double startX, startY;
private double xOffset, yOffset;
private PanGestureRecognizer pan;
private PinchGestureRecognizer pinchGesture;
private TapGestureRecognizer tap;
public static readonly BindableProperty GestureOnProperty =
BindableProperty.Create("GestureOn", typeof(bool), typeof(GestureContainer), defaultValue: true, defaultBindingMode: BindingMode.TwoWay, propertyChanged: GestureOnChanges);
public bool GestureOn
{
get
{
return (bool)GetValue(GestureOnProperty);
}
set
{
SetValue(GestureOnProperty, value);
}
}
private static void GestureOnChanges(BindableObject bindable, object oldvalue, object newvalue)
{
GestureContainer gestureContainer = bindable as GestureContainer;
if ((bool)newvalue)
gestureContainer.SetGestures();
else
gestureContainer.GestureRecognizers.Clear();
}
public GestureContainer()
{
pinchGesture = new PinchGestureRecognizer();
pan = new PanGestureRecognizer();
tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };
SetGestures();
Scale = MIN_SCALE;
TranslationX = TranslationY = 0;
}
private void SetGestures()
{
pinchGesture.PinchUpdated += OnPinchUpdated;
GestureRecognizers.Add(pinchGesture);
pan.PanUpdated += OnPanUpdated;
GestureRecognizers.Add(pan);
tap.Tapped += OnTapped;
GestureRecognizers.Add(tap);
}
private void OnTapped(object sender, EventArgs e)
{
/**/
}
void RestoreScaleValues()
{
/**/
}
void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
{
/**/
}
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
/**/
}
}
具有“怪异”功能的部分是这样的:
gestureContainer.GestureRecognizers.Clear();
当我将binded属性设置为false时,将调用该方法,并调用.Clear(),但是无论捏/平移/敲击仍在起作用,这都会导致绘图无法正常工作< / p>
编辑
这是XAML代码
<controls:GestureContainer GestureOn="{Binding OptionsVisibility, Converter={StaticResource BooleanConverter}}" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All">
<controls:GestureContainer.Content>
<Grid>
<ffimageloading:CachedImage
Rotation="{Binding Rotation}"
x:Name="originalView"
Aspect="AspectFit"
DownsampleToViewSize="True"
Source="{Binding Imagen.ImageStream}"/>
<Grid IsEnabled="{Binding OptionsVisibility}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Transparent">
<controls:BindableSKCanvasView x:Name="canvasView"
Color="{Binding StrokeColor}"
WidthStroke="{Binding StrokeWidth}"
EnableTouchEvents="True"
PaintSurface="OnCanvasViewPaintSurface" />
<Grid.Effects>
<skiacontrols:TouchEffect Capture="True" TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
</Grid>
</controls:GestureContainer.Content>
</controls:GestureContainer>
答案 0 :(得分:0)
似乎正在创建多个引用。
尝试编写这样的函数
void clearGesture() {
pinchGesture.PinchUpdated -= OnPinchUpdated;
pan.PanUpdated -= OnPanUpdated;
tap.Tapped -= OnTapped;
}
并像gestureContainer.clearGesture();
答案 1 :(得分:0)
我认为您错过的要点:
使用nameof(PropertyName)
代替"PropertyName"
,因为它可以帮助我们忽略人为错误,例如:拼写错误。
在设置器中调用OnPropertyChanged方法,以确保您不会错过PropertyChanged事件。
在构造函数上调用基类实现,只是为了确保一切正常。(只是一种习惯,我不认为这是强制性的)
因此,我进行了必要的更改,可以在下面找到它们,我已经对其进行了更改,可以在下面找到它们
public class GestureContainer : ContentView
{
private const double MIN_SCALE = 1;
private const double MAX_SCALE = 4;
private double startScale, currentScale;
private double startX, startY;
private double xOffset, yOffset;
private PanGestureRecognizer pan;
private PinchGestureRecognizer pinchGesture;
private TapGestureRecognizer tap;
public static readonly BindableProperty GestureOnProperty =
BindableProperty.Create(nameof(GestureOn), typeof(bool), typeof(GestureContainer),
defaultValue: true, defaultBindingMode: BindingMode.TwoWay, propertyChanged: GestureOnChanges);
private static void GestureOnChanges(BindableObject bindable, object oldValue, object newValue)
{
GestureContainer gestureContainer = bindable as GestureContainer;
if ((bool)newValue)
{
gestureContainer.SetGestures();
}
else
{
gestureContainer.GestureRecognizers.Clear();
}
}
public bool GestureOn
{
get
{
return (bool)GetValue(GestureOnProperty);
}
set
{
SetValue(GestureOnProperty, value);
OnPropertyChanged(nameof(GestureOn));
}
}
public GestureContainer() : base()
{
pinchGesture = new PinchGestureRecognizer();
pan = new PanGestureRecognizer();
tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };
SetGestures();
Scale = MIN_SCALE;
TranslationX = TranslationY = 0;
}
private void SetGestures()
{
pinchGesture.PinchUpdated += OnPinchUpdated;
GestureRecognizers.Add(pinchGesture);
pan.PanUpdated += OnPanUpdated;
GestureRecognizers.Add(pan);
tap.Tapped += OnTapped;
GestureRecognizers.Add(tap);
}
private void OnTapped(object sender, EventArgs e)
{
/**/
}
private void RestoreScaleValues()
{
/**/
}
private void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
{
/**/
}
private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
/**/
}
}