问题描述
我正在尝试实现自定义PlatformEffect
,该自定义Xamarin.UWP
将在用户为我的GestureSettings
按住控件很长时间时执行。但是我发现我的应用程序不响应鼠标单击。我读到我需要根据备注here更改应用程序的{{1}}来解决此问题。问题是我不知道如何为Xamarin.UWP应用程序做到这一点,任何想法都将非常有帮助。
解决方法
如何更改Xamarin.UWP应用程序的GestureSettings?
源自官方document, Touch可以产生Hold动作,但是鼠标设备通常不能产生。因此,如果要实现鼠标保持,则需要使用add {{ 1}}作为元素,并使用GestureRecognizer的holding事件来实现鼠标保持。有关更多详细信息,请参阅以下内容。
GestureRecognizer
UWPMouseEffect
public static class MouseHoldingEffect
{
public static readonly BindableProperty MouseHoldingProperty =
BindableProperty.CreateAttached("MouseHolding",typeof(Action),typeof(MouseHoldingEffect),default(Action),propertyChanged: OnhandlerChanged);
public static Action GetMouseHolding(BindableObject view)
{
return (Action)view.GetValue(MouseHoldingProperty);
}
public static void SetMouseHolding(BindableObject view,Action value)
{
view.SetValue(MouseHoldingProperty,value);
}
static void OnhandlerChanged(BindableObject bindable,object oldValue,object newValue)
{
var view = bindable as View;
if (view == null)
{
return;
}
Action action = (Action)newValue;
if (action != null)
{
view.Effects.Add(new ControlTooltipEffect());
}
else
{
var toRemove = view.Effects.FirstOrDefault(e => e is ControlTooltipEffect);
if (toRemove != null)
{
view.Effects.Remove(toRemove);
}
}
}
class ControlTooltipEffect : RoutingEffect
{
public ControlTooltipEffect() : base($"Microsoft.{nameof(MouseHoldingEffect)}")
{
}
}
}
用法
public class UWPMouseEffect : PlatformEffect
{
Windows.UI.Input.GestureRecognizer recognizer;
ManipulationInputProcessor manipulationProcessor;
protected override void OnAttached()
{
var control = Control ?? Container;
if (control is UIElement)
{
var mouseHolding = Element.GetValue(MouseHoldingEffect.MouseHoldingProperty) as Action;
var target = control as UIElement;
var parent = Window.Current.Content;
recognizer = new Windows.UI.Input.GestureRecognizer();
manipulationProcessor = new ManipulationInputProcessor(recognizer,target,parent,mouseHolding);
}
}
protected override void OnDetached()
{
}
}
class ManipulationInputProcessor
{
Action mouseHolding;
Windows.UI.Input.GestureRecognizer recognizer;
UIElement element;
UIElement reference;
TransformGroup cumulativeTransform;
MatrixTransform previousTransform;
CompositeTransform deltaTransform;
public ManipulationInputProcessor(Windows.UI.Input.GestureRecognizer gestureRecognizer,UIElement target,UIElement referenceFrame,Action holdingAction)
{
recognizer = gestureRecognizer;
element = target;
reference = referenceFrame;
mouseHolding = holdingAction;
// Initialize the transforms that will be used to manipulate the shape
InitializeTransforms();
// The GestureSettings property dictates what manipulation events the
// Gesture Recognizer will listen to. This will set it to a limited
// subset of these events.
recognizer.GestureSettings = GenerateDefaultSettings();
// Set up pointer event handlers. These receive input events that are used by the gesture recognizer.
element.PointerPressed += OnPointerPressed;
element.PointerMoved += OnPointerMoved;
element.PointerReleased += OnPointerReleased;
element.PointerCanceled += OnPointerCanceled;
recognizer.Holding += Recognizer_Holding;
}
private void OnPointerMoved(object sender,PointerRoutedEventArgs e)
{
recognizer.ProcessMoveEvents(e.GetIntermediatePoints(reference));
}
private void OnPointerCanceled(object sender,PointerRoutedEventArgs e)
{
recognizer.CompleteGesture();
element.ReleasePointerCapture(e.Pointer);
}
private void OnPointerReleased(object sender,PointerRoutedEventArgs e)
{
recognizer.ProcessUpEvent(e.GetCurrentPoint(reference));
// Release the pointer
element.ReleasePointerCapture(e.Pointer);
}
private void OnPointerPressed(object sender,PointerRoutedEventArgs e)
{
element.CapturePointer(e.Pointer);
// Feed the current point into the gesture recognizer as a down event
recognizer.ProcessDownEvent(e.GetCurrentPoint(reference));
}
private GestureSettings GenerateDefaultSettings()
{
return GestureSettings.HoldWithMouse;
}
private void Recognizer_Holding(Windows.UI.Input.GestureRecognizer sender,HoldingEventArgs args)
{
System.Diagnostics.Debug.WriteLine("-----------Holding---------");
mouseHolding();
}
private void InitializeTransforms()
{
cumulativeTransform = new TransformGroup();
deltaTransform = new CompositeTransform();
previousTransform = new MatrixTransform() { Matrix = Matrix.Identity };
cumulativeTransform.Children.Add(previousTransform);
cumulativeTransform.Children.Add(deltaTransform);
element.RenderTransform = cumulativeTransform;
}
}
ViewModel
<StackLayout>
<Label
effect:MouseHoldingEffect.MouseHolding="{Binding MouseHoldingAction}"
FontSize="25"
Text="Hello" VerticalOptions="Center" HorizontalOptions="Center" Margin="100"/>
</StackLayout>