询问者
windows8 store app(C#) -- the OnHolding Event can not be triggered

问题
-
purpose:use your Finger to draw a polyline,then use the OnHolding Event end of the draw.
the complete code is as follows:
PolyLineContainer.cs
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace test1 { public class PolyLineContainer : Panel { protected override Size MeasureOverride(Size availableSize) { foreach (UIElement element in base.Children) { element.Measure(availableSize); } return base.MeasureOverride(availableSize); } protected override Size ArrangeOverride(Size finalSize) { foreach (UIElement element in base.Children) { var line = element as PolyLineElement; var points = line.pc; if (points.Count == 0) continue; var left = points[0].X; var top = points[0].Y; var right = points[0].X; var bottom = points[0].Y; for (var i = 1; i < points.Count; i++) { var p = points[i]; if (left > p.X) left = p.X; if (top > p.Y) top = p.Y; if (right < p.X) right = p.X; if (bottom < p.Y) bottom = p.Y; } var w = right - left; var h = bottom - top; if (w > 0 && h > 0) { element.Arrange(new Rect(left, top, w+50, h+50)); //Debug.WriteLine("container--x:" + left + "'top:" + top + ",width:" + w + ",height:" + h); foreach (Point p in line.Points) { //Debug.WriteLine("change--X:" + p.X + "'Y:" + p.Y); } foreach (Point p in line.pc) { //Debug.WriteLine("origin--X:" + p.X + "'Y:" + p.Y); } } else { element.Arrange(new Rect(new Point(0, 0), element.DesiredSize)); } } return base.ArrangeOverride(finalSize); } } }
PolyLineElement.cs
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Shapes; namespace test1 { public class PolyLineElement : UserControl { public Point2DCollection pc { get { return (Point2DCollection)GetValue(pcProperty); } set { SetValue(pcProperty, value); } } public static readonly DependencyProperty pcProperty = DependencyProperty.Register("pc", typeof(Point2DCollection), typeof(PolyLineElement), new PropertyMetadata(null, new PropertyChangedCallback(Point2Ds_Changed))); private static void Point2Ds_Changed(DependencyObject o, DependencyPropertyChangedEventArgs e) { PolyLineElement sb = o as PolyLineElement; if (sb != null) { Point2DCollection oldValue = e.OldValue as Point2DCollection; if (oldValue != null) { oldValue.CollectionChanged -= new NotifyCollectionChangedEventHandler(sb.Point2Ds_CollectionChanged); } Point2DCollection newValue = e.NewValue as Point2DCollection; if (newValue != null) { newValue.CollectionChanged += new NotifyCollectionChangedEventHandler(sb.Point2Ds_CollectionChanged); } sb.ScreenUpdated(); } } private void Point2Ds_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { this.ScreenUpdated(); } private void ScreenUpdated() { var points = this.pc; if (points.Count == 0) return; var left = points[0].X; var top = points[0].Y; var right = points[0].X; var bottom = points[0].Y; for (var i = 1; i < points.Count; i++) { var p = points[i]; if (left > p.X) left = p.X; if (top > p.Y) top = p.Y; if (right < p.X) right = p.X; if (bottom < p.Y) bottom = p.Y; } //Debug.WriteLine("line--x:" + left + "'top:" + top + ",width:" + (right - left) + ",height:" + (bottom - top)); var pointsc = new PointCollection(); foreach (Point p in points) { var pp = new Point(p.X, p.Y); pp.X -= left; pp.Y -= top; pointsc.Add(pp); } this.Points = pointsc; } public PointCollection Points { get { return ((Polyline)this.shape).Points; } set { ((Polyline)this.shape).Points = value; } } private Shape shape; public PolyLineElement() { base.Content = this.shape = new Polyline(); pc = new Point2DCollection(); } public Brush Stroke { get { return (Brush)this.shape.GetValue(Shape.StrokeProperty); } set { this.shape.SetValue(Shape.StrokeProperty, value); } } public double StrokeThickness { get { return (double)this.shape.GetValue(Shape.StrokeThicknessProperty); } set { this.shape.SetValue(Shape.StrokeThicknessProperty, value); } } } }
Point2DCollection.cs
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Foundation; namespace test1 { public class Point2DCollection : ObservableCollection<Point> { public double x{get;set;} public double y{get;set;} public double w{get;set;} public double h{get;set;} public Point2DCollection() { } } }
start page
MainPage.xaml
<Page x:Class="test1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:test1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Name="grid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" PointerPressed="grid_PointerPressed_1" PointerMoved="grid_PointerMoved_1" Holding="grid_Holding_1"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Black" Opacity="1"> <Polyline Name="line" Stroke="AntiqueWhite" StrokeThickness="6"/> </Grid> </Grid> </Page>
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Windows.Devices.Input; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI; using Windows.UI.Input; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍 namespace test1 { /// <summary> /// 可用于自身或导航至 Frame 内部的空白页。 /// </summary> public sealed partial class MainPage : Page { private PolyLineContainer container; private bool isFirst = true; private PolyLineElement le; public MainPage() { this.InitializeComponent(); } /// <summary> /// 在此页将要在 Frame 中显示时进行调用。 /// </summary> /// <param name="e">描述如何访问此页的事件数据。Parameter /// 属性通常用于配置页。</param> protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { container = new PolyLineContainer(); grid.Children.Add(container); } } private void grid_PointerPressed_1(object sender, PointerRoutedEventArgs e) { var p = e.GetCurrentPoint(grid).Position; if (isFirst) { isFirst = false; le = new PolyLineElement(); le.Stroke = new SolidColorBrush(Colors.White); le.StrokeThickness = 1; container.Children.Add(le); le.Points.Add(p); le.pc.Add(p); } le.pc.Add(p); } private void grid_PointerMoved_1(object sender, PointerRoutedEventArgs e) { if (le == null || le.pc.Count == 0) return; var p = e.GetCurrentPoint(grid).Position; le.pc.RemoveAt(le.pc.Count - 1); le.pc.Add(p); } private void grid_Holding_1(object sender, HoldingRoutedEventArgs e) { if (e.HoldingState == HoldingState.Started) { isFirst = true; le.pc.Clear(); } } } }
Test Results
via the touch screen, the OnHolding Event can not be triggered sometimes. why?
全部回复
-
Hi,
Does Holding event can not be triggered everytime? Or it can't be triggered in some special scenario?
You have to keep the finger touching the screen for a while without moving to fire holding event.
Aaron
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.