protected override void OnManipulationCompleted(ManipulationCompletedRoutedEventArgs e) { LoopItemsPickerPanel itemsPanel = e.Container as LoopItemsPickerPanel; if (itemsPanel == null) { return; } PickerSelectorItem selectorItem = itemsPanel.GetMiddleItem(); if (selectorItem == null) { return; } DateTimeWrapper dateTimeWrapper = selectorItem.DataContext as DateTimeWrapper; if (dateTimeWrapper == null) { return; } this.Value = dateTimeWrapper.DateTime; }
/// <summary> /// Scroll to a selected index (with animation or not) /// </summary> internal void ScrollToSelectedIndex(PickerSelectorItem selectedItem, TimeSpan duration) { if (!templateApplied) { return; } var centerTopOffset = (this.ActualHeight / 2d) - (itemHeight) / 2d; var deltaOffset = centerTopOffset - selectedItem.GetVerticalPosition(); if (Double.IsInfinity(deltaOffset) || Double.IsNaN(deltaOffset)) { return; } if (duration == TimeSpan.Zero) { this.sliderVertical.Value += deltaOffset; } else { this.UpdatePositionsWithAnimationAsync(selectedItem, deltaOffset, duration); } }
/// <summary> /// Maybe this method is Obsolet : TODO : Test obsoletence /// </summary> /// <param name="e"></param> protected override void OnManipulationCompleted(ManipulationCompletedRoutedEventArgs e) { PickerSelectorItem middleItem = this.itemsPanel.GetMiddleItem(); if (middleItem == null) { return; } this.SelectedItem = middleItem.DataContext as DateTimeWrapper; base.OnManipulationCompleted(e); }
/// <summary> /// When manipulation is completed, go to the closest item /// </summary> private void OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e) { PickerSelectorItem middleItem = GetMiddleItem(); // get rect if (middleItem == null) { return; } // animate and scroll to this.ScrollToSelectedIndex(middleItem, animationDuration); }
/// <summary> /// Translate items to a new offset /// </summary> private void UpdatePosition(Int32 startIndex, Int32 endIndex, Double offset) { for (Int32 i = startIndex; i < endIndex; i++) { PickerSelectorItem loopListItem = this.Children[i] as PickerSelectorItem; if (loopListItem == null) { continue; } TranslateTransform translateTransform = loopListItem.GetTranslateTransform(); translateTransform.Y = offset; } }
/// <summary> /// Updating with an animation (after a tap) /// </summary> private void UpdatePositionsWithAnimationAsync(PickerSelectorItem selectedItem, Double delta, TimeSpan duration) { animationSnap.From = selectedItem.GetTranslateTransform().Y; animationSnap.To = selectedItem.GetTranslateTransform().Y + delta; animationSnap.Duration = duration; animationSnap.EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseInOut }; sliderVertical.ValueChanged -= OnVerticalOffsetChanged; sliderVertical.Value = selectedItem.GetTranslateTransform().Y; sliderVertical.ValueChanged += OnVerticalOffsetChanged; this.storyboard.Completed += (sender, o) => { if (SelectedItemChanged != null) { SelectedItemChanged(this, selectedItem); } }; this.storyboard.RunAsync(); }
/// <summary> /// Prepares the specified element to display the specified item. /// </summary> protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { if (DesignMode.DesignModeEnabled) { return; } itemsPanel = this.GetVisualDescendent <LoopItemsPickerPanel>(); // get the item PickerSelectorItem loopListItem = element as PickerSelectorItem; DateTimeWrapper dateTimeWrapper = item as DateTimeWrapper; if (loopListItem == null || dateTimeWrapper == null) { return; } if (this.ItemTemplate == null) { return; } // load data templated var contentElement = this.ItemTemplate.LoadContent() as FrameworkElement; if (contentElement == null) { return; } // attach DataContext and Context to the item loopListItem.Style = ItemContainerStyle; loopListItem.DataContext = item; loopListItem.Content = contentElement; loopListItem.IsSelected = dateTimeWrapper == this.SelectedItem; loopListItem.IsFocused = this.IsFocused; }
/// <summary> /// Update Items. Used for days /// </summary> internal void CreateOrUpdateItems(DateTime dateTime) { if (this.Items == null) { return; } DateTimeWrapper selectedDateTimeWrapper = null; int newMax; DateTime firstAvailableDate = GetFirstAvailable(dateTime, out newMax); // Make a copy without any minutes / seconds ... DateTimeWrapper newData = new DateTimeWrapper(new DateTime(firstAvailableDate.Year, firstAvailableDate.Month, firstAvailableDate.Day)); // One item is deleted but was selected.. // Don't forget to reactivate a selected item Boolean oneItemMustBeDeletedAndIsSelected = false; // If new month have less day than last month if (newMax < this.Items.Count) { int numberOfLastDaysToDelete = this.Items.Count - newMax; for (int cpt = 0; cpt < numberOfLastDaysToDelete; cpt++) { PickerSelectorItem item = this.ItemContainerGenerator.ContainerFromItem(this.Items[this.Items.Count - 1]) as PickerSelectorItem; if (item == null) { continue; } if (item.IsSelected) { oneItemMustBeDeletedAndIsSelected = true; } this.Items.RemoveAt(this.Items.Count - 1); } } for (int i = 0; i < newMax; i++) { // ----------------------------------------------------------------------------- // Add or Update Items // ----------------------------------------------------------------------------- if (this.Items.Count <= i) { this.Items.Add(newData); } else { // Verify the item already exists var itemDate = ((DateTimeWrapper)this.Items[i]).DateTime; if (itemDate != newData.DateTime) { this.Items[i] = newData; } } // ----------------------------------------------------------------------------- // Get the good selected itm // ----------------------------------------------------------------------------- if (newData.DateTime == dateTime) { selectedDateTimeWrapper = newData; } // ----------------------------------------------------------------------------- // Get the next data, relative to original wrapper, then relative to firstWrapper // ----------------------------------------------------------------------------- DateTime?nextData = null; // Get nex date switch (this.DataSourceType) { case DataSourceType.Year: nextData = this.YearDataSource.GetNext(dateTime, firstAvailableDate, i + 1); break; case DataSourceType.Month: nextData = this.MonthDataSource.GetNext(dateTime, firstAvailableDate, i + 1); break; case DataSourceType.Day: nextData = this.DayDataSource.GetNext(dateTime, firstAvailableDate, i + 1); break; } if (nextData == null) { break; } newData = nextData.Value.ToDateTimeWrapper(); } // Set the correct Selected Item if (selectedDateTimeWrapper != null) { this.SelectedItem = selectedDateTimeWrapper; } else if (oneItemMustBeDeletedAndIsSelected) // When 31 was selected and we are on a Month < 31 days (February, April ...) { this.SelectedItem = (DateTimeWrapper)this.Items[this.Items.Count - 1]; } else { this.SelectedItem = (DateTimeWrapper)this.Items[0]; } }
/// <summary> /// Arrange all items /// </summary> protected override Size ArrangeOverride(Size finalSize) { // Clip to ensure items dont override container this.Clip = new RectangleGeometry { Rect = new Rect(0, 0, finalSize.Width, finalSize.Height) }; if (this.Children == null || this.Children.Count == 0) { var size = base.ArrangeOverride(finalSize); var width = double.IsInfinity(size.Width) ? 400 : size.Width; var height = double.IsInfinity(size.Height) ? 800 : size.Height; return(new Size(width, height)); } Double positionTop = 0d; Double positionLeft = 0d; PickerSelectorItem selectedItem = null; // Must Create looping items count foreach (PickerSelectorItem item in this.Children) { if (item == null) { continue; } Size desiredSize = item.DesiredSize; if (double.IsNaN(desiredSize.Width) || double.IsNaN(desiredSize.Height)) { continue; } item.RectPosition = new Rect(positionLeft, positionTop, desiredSize.Width, desiredSize.Height); item.Arrange(item.RectPosition); if (item.IsSelected) { selectedItem = item; } positionTop += desiredSize.Height; } templateApplied = true; if (selectedItem != null) { this.UpdatePositions(sliderVertical.Value); this.ScrollToSelectedIndex(selectedItem, TimeSpan.Zero); //if (!isFirstLayoutPassed) //{ // this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, // () => this.ScrollToSelectedIndex(selectedItem, TimeSpan.Zero)); //} //else //{ //} } return(finalSize); }
private static void IsSelectedChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) { PickerSelectorItem pickerSelectorItem = (PickerSelectorItem)dependencyObject; pickerSelectorItem.ManageVisualStates(); }