none
windows8 store app(C#) -- the OnHolding Event can not be triggered RRS feed

  • 问题

  • 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?

    2012年12月31日 1:22

全部回复

  • 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.

    2013年1月2日 6:48
    版主
  • hi,

    Thanks very much.

    Yes.The Holding event can not be triggered in most casees when keep your finger touching the screen for a while.

    I think. Maybe the drawing area border (element.Arrange(new Rect(left,top,w,h));) stop the Holding event trigger.

    2013年1月4日 1:09