wpf+.net 4.5 surface2.0 = 異步多點觸控 時間軸 part2

 

先來張效果圖,

然後繼續貼

 

軸控件xaml :

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="http://schemas.microsoft.com/surface/2008" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
	xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:tranvalue="clr-namespace:Transvalue.Timeline"  
    x:Class="Transvalue.Timeline.TimelineControl"
    mc:Ignorable="d" 
    Loaded="TimelineControl_Loaded" 
    Height="540"  Width="3500" 
    >
    <s:SurfaceScrollViewer   
         Name="touchPad"
		    CanContentScroll="True" VerticalScrollBarVisibility="Disabled"
			PanningMode="HorizontalOnly" Width="Auto" Height="Auto"
            ScrollChanged="SurfaceScrollViewer_ScrollChanged" 
            Elasticity="0.4,0.4" Grid.IsSharedSizeScope="True" 
            HorizontalScrollBarVisibility="Hidden" 
      >
        <Grid Height="Auto" x:Name="gridTimeline" Width="Auto" 
				IsManipulationEnabled="True" TouchDown="gridTimeline_TouchDown"
              TouchLeave="gridTimeline_TouchLeave"
				 Background="Black" RenderTransformOrigin="0.5,0.5">
            <Grid.RowDefinitions>
                <RowDefinition Height="0.3*" />
                <RowDefinition Height="0.7*" />
            </Grid.RowDefinitions>
            <tranvalue:TimelineBandControl Grid.Row="1" HorizontalAlignment="Left" Height="Auto" Width="Auto"
					x:Name="timelineBandControl" 
					VerticalAlignment="Top" PageSize="40"/>
        </Grid>
    </s:SurfaceScrollViewer>
</UserControl>


 

軸控件代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Surface.Presentation.Input;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Animation;

namespace Transvalue.Timeline
{
    /// <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class TimelineControl : UserControl, INotifyPropertyChanged
    {
        /// <summary>
        /// 點的位置
        /// </summary>
        private static List<TouchPoint> position = new List<TouchPoint>();

        /// <summary>
        /// 點移動距離
        /// </summary>
        private static List<TouchPoint> leavePosition = new List<TouchPoint>();

        /// <summary>
        /// 更換時間軸方法(從小到大)字典
        /// </summary>
        private static Dictionary<Predicate<TimeLineEnum.TimeLineBandType>,
            Func<DateTime, DateTime, ObservableCollection<TimelineLabelItem>, bool,
            Task<ObservableCollection<TimelineLabelItem>>>>
            ChangeTimeLineBandBigFuncDict =
            new Dictionary<Predicate<TimeLineEnum.TimeLineBandType>,
                Func<DateTime, DateTime, ObservableCollection<TimelineLabelItem>, bool,
                Task<ObservableCollection<TimelineLabelItem>>>>();

        /// <summary>
        /// 時間軸對應文字字典
        /// </summary>
        private static Dictionary<TimeLineEnum.TimeLineBandType, string>
            timelineBandDict = new Dictionary<TimeLineEnum.TimeLineBandType, string>();

        /// <summary>
        /// 獲取該年一共有多少天
        /// </summary>
        private static Func<int, int> GetDaysByYearFunc;

        private static Func<TimeLineEnum.TimeLineBandType, ObservableCollection<TimelineLabelItem>, int> GetTimelineLabelItems;

        /// <summary>
        /// 獲取該月一共有多少天
        /// </summary>
        private static Func<int, int, int> GetDaysOfMonthFunc;

        /// <summary>
        /// 根據點移動位置以及數量來判斷放大或縮小
        /// </summary>
        private static Func<List<TouchPoint>, List<TouchPoint>, int> TransScatterFunc;

        /// <summary>
        /// 根據標籤類型來刪除
        /// </summary>
        private static Func<TimeLineEnum.TimeLineBandType,
            ObservableCollection<TimelineLabelItem>,
            ObservableCollection<TimelineLabelItem>,
            ObservableCollection<TimelineLabelItem>> DelLabelItemsByType;

        /// <summary>
        /// 根據父座標生成子座標
        /// <para>int 最大生成子項數</para>
        /// <para>TimelineType 需要生成的子相熟類型</para>
        /// <para>TimelineLabelItem  需要擴展的父座標</para>
        /// <para>ObservableCollection 返回值</para>
        /// </summary>
        private static Func<DateTime, DateTime, int, TimeLineEnum.TimeLineBandType, TimeLineEnum.TimelineLabelItemState,
            ObservableCollection<TimelineLabelItem>, Task<ObservableCollection<TimelineLabelItem>>>
            ExtendsTimeline;

        /// <summary>
        /// 生成根座標
        /// </summary>
        private static Func<DateTime, TimeLineEnum.TimeLineBandType, ObservableCollection<TimelineLabelItem>,
            TimeLineEnum.TimelineLabelItemState, DateTime, Task<ObservableCollection<TimelineLabelItem>>>
            GenericRootLabelItems;

        /// <summary>
        /// 臨時座標
        /// </summary>
        private static int index = 0;
        private static bool isFirst = true;

        #region 開始時間
        public static DependencyProperty startDate = DependencyProperty.Register("StartDate",
            typeof(DateTime),
            typeof(TimelineControl)
            , new PropertyMetadata(new PropertyChangedCallback(StartDateCallBack)));

        public DateTime StartDate
        {
            get { return (DateTime)GetValue(startDate); }
            set { SetValue(startDate, value); }
        }

        private static void StartDateCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            TimelineControl timelineControl = sender as TimelineControl;
            if (e.Property == startDate)
            {
                timelineControl.StartDate = (DateTime)e.NewValue;
            }
        }
        #endregion

        #region 結束時間
        public static DependencyProperty endDate = DependencyProperty.Register("EndDate",
            typeof(DateTime),
            typeof(TimelineControl)
            , new PropertyMetadata(new PropertyChangedCallback(EndDateCallBack)));

        public DateTime EndDate
        {
            get { return (DateTime)GetValue(endDate); }
            set { SetValue(endDate, value); }
        }

        private static void EndDateCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            TimelineControl timelineControl = sender as TimelineControl;
            if (e.Property == startDate)
            {
                timelineControl.EndDate = (DateTime)e.NewValue;
            }
        }
        #endregion

        #region 時間軸類型
        private static TimeLineEnum.TimeLineBandType currentMode;
        public static DependencyProperty defaultTimelineMode = DependencyProperty.Register("DefaultTimelineMode",
              typeof(int), typeof(TimelineControl),
              new PropertyMetadata(new PropertyChangedCallback(CurrentTimelineModeCallBack)));

        public int DefaultTimelineMode
        {
            get
            {
                return (int)GetValue(defaultTimelineMode);
            }
            set
            {
                SetValue(defaultTimelineMode, value);
            }
        }

        private static void CurrentTimelineModeCallBack(DependencyObject sender,
            DependencyPropertyChangedEventArgs e)
        {
            var timelineBand = sender as TimelineControl;
            if (e.Property == defaultTimelineMode)
            {
                timelineBand.DefaultTimelineMode = (int)e.NewValue;
                currentMode = (TimeLineEnum.TimeLineBandType)timelineBand.DefaultTimelineMode;
            }
        }
        #endregion

        #region 時間軸事件數據源
        public static DependencyProperty timelineEventSource = DependencyProperty.Register("TimelineEventSource",
            typeof(ObservableCollection<TimelineEventItem>), typeof(TimelineControl)
            , new PropertyMetadata(new PropertyChangedCallback(timelineEventSourceCallBack)));

        public ObservableCollection<TimelineEventItem> TimelineEventSource
        {
            get { return (ObservableCollection<TimelineEventItem>)GetValue(timelineEventSource); }
            set { SetValue(timelineEventSource, value); }
        }

        private static void timelineEventSourceCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            TimelineControl o = sender as TimelineControl;
            if (e.Property == timelineEventSource)
                o.TimelineEventSource = (ObservableCollection<TimelineEventItem>)e.NewValue;
        }
        #endregion

        #region 默認軸之間的寬度
        public static DependencyProperty defaultItemWidth = DependencyProperty.Register("DefaultItemWidth",
              typeof(double), typeof(TimelineControl),
              new PropertyMetadata(new PropertyChangedCallback(DefaultItemWidthCallBack)));

        public double DefaultItemWidth
        {
            get
            {
                return (double)GetValue(defaultItemWidth);
            }
            set
            {
                SetValue(defaultItemWidth, value);
            }
        }

        private static void DefaultItemWidthCallBack(DependencyObject sender,
            DependencyPropertyChangedEventArgs e)
        {
            var timelineBand = sender as TimelineControl;
            if (e.Property == defaultItemWidth)
            {
                timelineBand.DefaultItemWidth = (double)e.NewValue;
                TimelineBandControl.defaultItemWidth = timelineBand.DefaultItemWidth;
            }
        }
        #endregion

        #region 註冊自定義事件和參數
        #region 加載完畢
        public static readonly RoutedEvent LoadComplatedEvent;

        public class LoadComplatedEventArgs : RoutedEventArgs
        {
            public bool ok
            {
                get;
                set;
            }
        }
        public delegate void LoadComplatedEventHandler(object sender,
            LoadComplatedEventArgs e);
        public event LoadComplatedEventHandler LoadComplatedEH
        {
            add
            {
                AddHandler(TimelineControl.LoadComplatedEvent,
                    value);
            }
            remove
            {
                RemoveHandler(TimelineControl.LoadComplatedEvent,
                    value);
            }
        }
        #endregion

        #region 加載中
        public static readonly RoutedEvent LoadingEvent;

        public class LoadingEventArgs : RoutedEventArgs
        {
            public bool ok
            {
                get;
                set;
            }
        }

        public delegate void LoadingEventHandler(object sender,
            LoadingEventArgs e);
        public event LoadingEventHandler LoadingEH
        {
            add
            {
                AddHandler(TimelineControl.LoadingEvent,
                    value);
            }
            remove
            {
                RemoveHandler(TimelineControl.LoadingEvent,
                    value);
            }
        }
        #endregion

        #region 加載SVI事件
        public static readonly RoutedEvent ShowScatterEvent;

        public class ShowScatterEventArgs : RoutedEventArgs
        {
            public UIElement svi
            {
                get;
                set;
            }
        }
        public delegate void ShowScatterEventHandler(object sender,
            ShowScatterEventArgs e);
        public event ShowScatterEventHandler ShowScatterEH
        {
            add
            {
                AddHandler(TimelineControl.ShowScatterEvent,
                    value);
            }
            remove
            {
                RemoveHandler(TimelineControl.ShowScatterEvent,
                    value);
            }
        }
        #endregion
        #endregion

        #region 初始化
        public TimelineControl()
        {
            InitializeComponent();
            if (isFirst)
            {
                isFirst = false;
                InitializeControlData();
                InitializeControlFunction();
            }
            timelineBandControl.LoadComplatedEH += ((sender, e) =>
            {
                LoadComplatedEventArgs args = new LoadComplatedEventArgs();
                args.RoutedEvent = LoadComplatedEvent;
                args.ok = true;
                RaiseEvent(args);
            });
            timelineBandControl.ShowScatterEH += ((sender, eventArgs) =>
            {
                ShowScatterEventArgs args = new ShowScatterEventArgs();
                args.svi = eventArgs.svi;
                args.RoutedEvent = ShowScatterEvent;
                RaiseEvent(args);
            });
            timelineBandControl.ShowDetailEH += (async (sender, eventArgs) =>
            {
                var start = eventArgs.startDate;
                var mode = eventArgs.showMode;
                var end = eventArgs.endDate;
                clearCache();
                currentMode--;
                if (await timelineBandControl.doAnimation(true))
                    await loadTimeline(start, end, mode, true);
            });

        }

        static TimelineControl()
        {
            LoadComplatedEvent = EventManager.RegisterRoutedEvent(
                "LoadComplatedEvent",
                RoutingStrategy.Bubble,
                typeof(LoadComplatedEventHandler),
                typeof(TimelineControl));
            LoadingEvent = EventManager.RegisterRoutedEvent(
                "LoadingEvent",
                RoutingStrategy.Bubble,
                typeof(LoadingEventHandler),
                typeof(TimelineControl));
            ShowScatterEvent = EventManager.RegisterRoutedEvent(
              "ShowScatterEvent",
              RoutingStrategy.Bubble,
              typeof(ShowScatterEventHandler),
              typeof(TimelineControl));
        }

        /// <summary>
        /// 初始化控件數據
        /// </summary>
        /// <returns></returns>
        private async void InitializeControlData()
        {
            await Task.Factory.StartNew(() =>
            {
                timelineBandDict.Add(TimeLineEnum.TimeLineBandType.Days, "日");
                timelineBandDict.Add(TimeLineEnum.TimeLineBandType.Months, "月");
                timelineBandDict.Add(TimeLineEnum.TimeLineBandType.Years, "年");
                timelineBandDict.Add(TimeLineEnum.TimeLineBandType.Decades, "年");
            });
        }

        /// <summary>
        /// 初始化控件方法
        /// </summary>
        /// <returns></returns>
        private async void InitializeControlFunction()
        {
            #region 初始化方法
            GetDaysByYearFunc = (year =>
            {
                var dt = new DateTime(year, 12, 31);
                int days = dt.DayOfYear;
                return 0;
            });

            GetTimelineLabelItems = ((type, controlItems) =>
            {
                return (from item in controlItems
                        where item.TimelineType.Equals(type)
                        select item).Count();
            });

            GetDaysOfMonthFunc = ((year, month) =>
            {
                int nextMonth = new DateTime(year, month, 1).AddMonths(1).DayOfYear;
                int currentMonth = new DateTime(year, month, 1).DayOfYear;
                if (month == 12) return 31;
                else return nextMonth - currentMonth;
            });

            //反回0放大 1縮小
            TransScatterFunc = ((position, leavePosition) =>
            {
                var point = new List<double>();
                position.ForEach(p =>
                    {
                        leavePosition.ForEach(l =>
                            {
                                if (p.Id == l.Id)
                                {
                                    point.Add(p.Position);
                                    point.Add(l.Position);
                                }
                            });
                    });
                if (point.Count > 3)
                {
                    var tPointA = point[0]; //按下去的點A
                    var lPointA = point[1]; //鬆開的點A
                    var tPointB = point[2]; //按下去的點B
                    var lPointB = point[3]; //鬆開的點B
                    if ((tPointA < lPointA && lPointA - tPointA > 10) && (tPointB > lPointB && tPointB - lPointB > 10)) return 1; //縮小操作
                    if ((tPointA > lPointA && tPointA - lPointA > 10) && (tPointB < lPointB && lPointB - tPointB > 10)) return 0; //放大操作
                }
                return -1;
            });

            DelLabelItemsByType = ((delType, items, controlItems) =>
            {
                var delItems = new ObservableCollection<TimelineLabelItem>(controlItems.
                                  Where(item => item.TimelineType.Equals(delType)));
                delItems.ForEach(delItem =>
                {
                    items.Remove(delItem);
                    delItem.TimelineState = TimeLineEnum.TimelineLabelItemState.Del;
                    items.Add(delItem);
                });
                return items;
            });

            ExtendsTimeline = (async (start, end, max, type, state, items) =>
            {
                return await Task.Run(() =>
                {
                    var resultItems = new ObservableCollection<TimelineLabelItem>();
                    if (type != TimeLineEnum.TimeLineBandType.Days)
                        for (DateTime i = start; i <= end; i = i.AddMonths(1))
                        {
                            var sonItem = new TimelineLabelItem();
                            var content = i.Year + timelineBandDict[type + 1] + i.Month + timelineBandDict[type];
                            sonItem.TimelineType = type;
                            sonItem.TimelineLabelContent = content;
                            sonItem.TimelineState = state;
                            sonItem.TimelineDate = i;
                            resultItems.Add(sonItem);
                        }
                    else
                    {
                        for (DateTime i = start; i < end; i = i.AddDays(1))
                        {
                            var item = new TimelineLabelItem();
                            item.TimelineIndex = index++;
                            item.TimelineState = TimeLineEnum.TimelineLabelItemState.New;
                            item.TimelineDate = i;
                            item.TimelineLabelContent = i.Year + timelineBandDict[type + 2] + i.Month + timelineBandDict[type + 1] +
                                i.Day + timelineBandDict[type];
                            item.TimelineType = TimeLineEnum.TimeLineBandType.Days;
                            resultItems.Add(item);
                        }
                    }
                    resultItems.Distinct(new TimelineLabelItemComparer());
                    return resultItems;
                });
            });

            GenericRootLabelItems = (async (start, currentType, items, newState, end) =>
            {
                return await Task.Run(() =>
                {
                    for (DateTime i = start; i < end; i = i.AddYears(1))
                    {
                        var item = new TimelineLabelItem();
                        item.TimelineIndex = i.Year - start.Year;
                        var content = i.Year + timelineBandDict[currentType];
                        item.TimelineLabelContent = content;
                        item.TimelineState = newState;
                        item.TimelineType = currentType;
                        item.TimelineDate = i;
                        items.Add(item);
                    }
                    return items;
                });
            });
            #endregion

            #region 初始化字典方法
            await Task.Factory.StartNew(() =>
            {
                #region 十年座標
                ChangeTimeLineBandBigFuncDict.Add(type => type.Equals(TimeLineEnum.TimeLineBandType.Decades),
                  async (start, end, controlItems, detail) =>
                  {
                      var currentType = TimeLineEnum.TimeLineBandType.Decades;
                      var items = new ObservableCollection<TimelineLabelItem>();
                      var newState = TimeLineEnum.TimelineLabelItemState.New;
                      var maxYear = end.Year - start.Year;
                      Thread.Sleep(500);
                      if ((null == decadesCache || decadesCache.Count == 0))
                      {
                          items = await Task.Run<ObservableCollection<TimelineLabelItem>>(() =>
                          {
                              for (DateTime i = start; i < end; i = i.AddYears(10))
                              {
                                  var item = new TimelineLabelItem();
                                  item.TimelineIndex = (i.Year - start.Year) / 10;
                                  var content = i.Year + timelineBandDict[currentType] +
                                      " 至 " + i.AddYears(9).Year + timelineBandDict[currentType];
                                  item.TimelineLabelContent = content;
                                  item.TimelineState = newState;
                                  item.TimelineType = currentType;
                                  item.TimelineDate = i.AddYears(9);
                                  items.Add(item);
                              }
                              return items;
                          });
                          Pollute.log("完畢:" + items.Count);
                          if (!detail)
                              saveCache(currentMode, new ObservableCollection<TimelineLabelItem>(items.OrderBy(item => item.TimelineIndex)));
                          else
                              return items;
                      }
                      return decadesCache;
                  });
                #endregion

                #region 年座標
                ChangeTimeLineBandBigFuncDict.Add(type => type.Equals(TimeLineEnum.TimeLineBandType.Years),
                  async (start, end, controlItems, detail) =>
                  {
                      var sonItems = new ObservableCollection<TimelineLabelItem>();
                      var currentType = TimeLineEnum.TimeLineBandType.Years;
                      var items = new ObservableCollection<TimelineLabelItem>();
                      var newState = TimeLineEnum.TimelineLabelItemState.New;
                      var maxYear = end.Year - start.Year;
                      Thread.Sleep(500);
                      if ((null == yearCache || yearCache.Count == 0))
                      {
                          Pollute.log("開始生成 type:" + currentType);
                          items = await GenericRootLabelItems(start, currentType, items, newState, end);
                          Pollute.log("完畢:" + items.Count);
                          if (!detail)
                              saveCache(currentMode, new ObservableCollection<TimelineLabelItem>(items.OrderBy(item => item.TimelineIndex)));
                          else
                              return items;
                      }
                      return yearCache;
                  });
                #endregion

                #region 月座標
                ChangeTimeLineBandBigFuncDict.Add(type => type.Equals(TimeLineEnum.TimeLineBandType.Months),
                   async (start, end, controlItems, detail) =>
                   {
                       var currentType = TimeLineEnum.TimeLineBandType.Months;
                       var newState = TimeLineEnum.TimelineLabelItemState.New;
                       var items = controlItems;
                       var maxYear = end.Year - start.Year;
                       var max = 12; //12代表12個月
                       Thread.Sleep(500);
                       if ((null == monthCache || monthCache.Count == 0))
                       {
                           Pollute.log("開始生成 type:" + currentType);
                           items = new ObservableCollection<TimelineLabelItem>();
                           items = await ExtendsTimeline(start, end, max, currentType, newState, items);
                           Pollute.log("完畢:" + items.Count);
                           if (!detail)
                               saveCache(currentMode, new ObservableCollection<TimelineLabelItem>(items.OrderBy(item => item.TimelineIndex)));
                           else
                               return items;
                       }
                       return monthCache;

                   });
                #endregion

                #region 日座標
                ChangeTimeLineBandBigFuncDict.Add(type => type.Equals(TimeLineEnum.TimeLineBandType.Days),
                   async (start, end, controlItems, detail) => //只負責生成日
                   {
                       var currentType = TimeLineEnum.TimeLineBandType.Days;
                       var newState = TimeLineEnum.TimelineLabelItemState.New;
                       var items = controlItems;
                       var maxYear = end.Year - start.Year;
                       var max = 12; //12代表12個月
                       Thread.Sleep(500);
                       if ((null == dayCache || dayCache.Count == 0))
                       {
                           Pollute.log("開始生成 type:" + currentType);
                           items = new ObservableCollection<TimelineLabelItem>();
                           items = await ExtendsTimeline(start, end, max, currentType, newState, items);
                           if (!detail)
                               saveCache(currentMode, new ObservableCollection<TimelineLabelItem>(items.OrderBy(item => item.TimelineDate)));
                           else
                               return items;
                       }
                       return dayCache;
                   });
                #endregion
            });
            #endregion
        }

        private async void TimelineControl_Loaded(object sender, RoutedEventArgs e)
        {
            await loadTimeline(StartDate, EndDate, (TimeLineEnum.TimeLineBandType)DefaultTimelineMode, false);
        }

        #endregion

        #region 加載時間軸
        static bool isBusyLoading = false;
        public async Task loadTimeline(DateTime start, DateTime end, TimeLineEnum.TimeLineBandType type, bool detail)
        {
            if (!isBusyLoading)
            {
                isBusyLoading = true;
                Console.WriteLine("開始加載");
                LoadingEventArgs args = new LoadingEventArgs();
                args.RoutedEvent = LoadingEvent;
                args.ok = true;
                RaiseEvent(args);
                var controlItems = timelineBandControl.TimelineLabels;
                var resultItems = await Task.Run<ObservableCollection<TimelineLabelItem>>(GetItemsAsync(start, end, type, controlItems, detail));
                timelineBandControl.CurrentTimelineMode = (int)type;
                timelineBandControl.TimelineLabels = resultItems;
                timelineBandControl.TimelineEventSource = TimelineEventSource;
                isBusyLoading = false;
                Console.WriteLine("加載完畢");
            }
        }

        private static Func<Task<ObservableCollection<TimelineLabelItem>>> GetItemsAsync(DateTime start, DateTime end,
            TimeLineEnum.TimeLineBandType type, ObservableCollection<TimelineLabelItem> controlItems, bool detail)
        {
            return async () =>
            { //根據設定類型加載時間軸               
                return await ChangeTimeLineBandBigFuncDict.Where(item => item.Key(type)).ForEach(async item =>
                {
                    Pollute.log("key:" + type + " 開始等待");
                    return await item.Value(start, end, controlItems, detail);
                })[0];
            };
        }
        #endregion

        #region 多點事件捕捉
        private async void gridTimeline_TouchDown(object sender, TouchEventArgs e)
        {
            await Task.Factory.StartNew(() =>
            {
                Console.WriteLine("ID:" + e.TouchDevice.Id + "位置:" + e.TouchDevice.GetTouchPoint(this).Position.X);
                e.TouchDevice.Synchronize();
                SavePosition(e, position);
            }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
        }

        /// <summary>
        /// 觸摸移開的時候記錄事件
        /// </summary>
        /// <param na me="sender"></param>
        /// <param name="e"></param>
        private async void gridTimeline_TouchLeave(object sender, TouchEventArgs e)
        {
            Pollute.log(e.TouchDevice.Id + ":開始等待放大縮小結果");
            var result = await Task.Factory.StartNew(() =>
            {
                SavePosition(e, leavePosition);
                if (leavePosition.Count < 2)
                    return -1;
                return TransScatterFunc(position, leavePosition);
            }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
            try
            {
                if (result == 0 && currentMode < TimeLineEnum.TimeLineBandType.Decades)
                {
                    position.Clear();
                    leavePosition.Clear();
                    if (await timelineBandControl.doAnimation(false))
                        await changeTimelineType(++currentMode);
                }
                else if (result == 1 && currentMode > TimeLineEnum.TimeLineBandType.Days)
                {
                    position.Clear();
                    leavePosition.Clear();
                    if (await timelineBandControl.doAnimation(true))
                        await changeTimelineType(--currentMode);
                }
                else return;
            }
            catch (Exception ex)
            {
                MessageBox.Show("放大縮小報錯:" + ex.ToString());
            }

        }

        #region  保存點
        private void SavePosition(TouchEventArgs e, List<TouchPoint> position)
        {
            if (position.Where(s => s.Id.Equals(e.TouchDevice.Id)).Count<TouchPoint>().Equals(0))
            {
                var point = new TouchPoint();
                point.Id = e.TouchDevice.Id;
                point.Position = e.TouchDevice.GetPosition(this).X;
                position.Add(point);
            }
            else
            {
                TouchPoint point = position.Where<TouchPoint>(s => s.Id.Equals(e.TouchDevice.Id)).First();
                point.Position = e.TouchDevice.GetPosition(this).X;
            }
            if (position.Count > 2)
            {
                try
                {
                    Console.WriteLine("超過3個點了");
                    position.RemoveAt(0);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("超過3個點了:" + ex.ToString());
                }
            }
        }
        #endregion

        #endregion

        #region 放大或縮小時間軸
        private async Task changeTimelineType(TimeLineEnum.TimeLineBandType type)
        {
            await loadTimeline(StartDate, EndDate, type, false);
            leavePosition.Clear();
        }
        #endregion

        #region 滾動翻頁
        private async void SurfaceScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            var ssv = sender as SurfaceScrollViewer;
            if ((e.HorizontalOffset > ssv.ScrollableWidth - 30)
                && ssv.ScrollableWidth != 0)
            {
                Pollute.log("翻下一頁");
                await timelineBandControl.ChangeBand(true);
            }
        }
        #endregion

        #region 時間軸數據緩存
        private static ObservableCollection<TimelineLabelItem> monthCache;
        private static ObservableCollection<TimelineLabelItem> dayCache;
        private static ObservableCollection<TimelineLabelItem> yearCache;
        private static ObservableCollection<TimelineLabelItem> decadesCache;
        private void saveCache(TimeLineEnum.TimeLineBandType type, ObservableCollection<TimelineLabelItem> data)
        {
            switch (type)
            {
                case TimeLineEnum.TimeLineBandType.Days:
                    dayCache = data;
                    break;
                case TimeLineEnum.TimeLineBandType.Months:
                    monthCache = data;
                    break;
                case TimeLineEnum.TimeLineBandType.Years:
                    yearCache = data;
                    break;
                case TimeLineEnum.TimeLineBandType.Decades:
                    decadesCache = data;
                    break;
                default:
                    break;
            }
        }

        private void clearCache()
        {
            dayCache = null;
            monthCache = null;
            yearCache = null;
            decadesCache = null;
        }
        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

    }
}


 

發佈了38 篇原創文章 · 獲贊 35 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章