private static void OnIsExpandedChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            LoopingSelector picker = (LoopingSelector)sender;

            picker.UpdateItemState();
            if (!picker.IsExpanded)
            {
                picker.SelectAndSnapToClosest();
            }

            if (picker._state == State.Normal || picker._state == State.Expanded)
            {
                picker._state = picker.IsExpanded ? State.Expanded : State.Normal;
            }

            var listeners = picker.IsExpandedChanged;

            if (listeners != null)
            {
                listeners(picker, e);
            }
        }
        private static void OnDataModelChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            LoopingSelector picker = (LoopingSelector)obj;

            picker.UpdateData();
        }
        /// <summary>
        /// Initializes the ValuePickerPageBase class; must be called from the subclass's constructor.
        /// </summary>
        /// <param name="primarySelector">Primary selector.</param>
        /// <param name="secondarySelector">Secondary selector.</param>
        /// <param name="tertiarySelector">Tertiary selector.</param>
        protected void InitializeValuePickerPage(LoopingSelector primarySelector, LoopingSelector secondarySelector, LoopingSelector tertiarySelector)
        {
            if (null == primarySelector)
            {
                throw new ArgumentNullException("primarySelector");
            }
            if (null == secondarySelector)
            {
                throw new ArgumentNullException("secondarySelector");
            }
            if (null == tertiarySelector)
            {
                throw new ArgumentNullException("tertiarySelector");
            }

            _primarySelectorPart   = primarySelector;
            _secondarySelectorPart = secondarySelector;
            _tertiarySelectorPart  = tertiarySelector;

            // Hook up to interesting events
            _primarySelectorPart.DataSource.SelectionChanged   += OnDataSourceSelectionChanged;
            _secondarySelectorPart.DataSource.SelectionChanged += OnDataSourceSelectionChanged;
            _tertiarySelectorPart.DataSource.SelectionChanged  += OnDataSourceSelectionChanged;
            _primarySelectorPart.IsExpandedChanged             += OnSelectorIsExpandedChanged;
            _secondarySelectorPart.IsExpandedChanged           += OnSelectorIsExpandedChanged;
            _tertiarySelectorPart.IsExpandedChanged            += OnSelectorIsExpandedChanged;

            // Hide all selectors
            _primarySelectorPart.Visibility   = Visibility.Collapsed;
            _secondarySelectorPart.Visibility = Visibility.Collapsed;
            _tertiarySelectorPart.Visibility  = Visibility.Collapsed;

            // Position and reveal the culture-relevant selectors
            int column = 0;

            foreach (LoopingSelector selector in GetSelectorsOrderedByCulturePattern())
            {
                Grid.SetColumn(selector, column);
                selector.Visibility = Visibility.Visible;
                column++;
            }

            // Hook up to storyboard(s)
            var templateRoot = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;

            if (null != templateRoot)
            {
                foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(templateRoot))
                {
                    if (VisibilityGroupName == group.Name)
                    {
                        foreach (VisualState state in group.States)
                        {
                            if ((ClosedVisibilityStateName == state.Name) && (null != state.Storyboard))
                            {
                                _closedStoryboard            = state.Storyboard;
                                _closedStoryboard.Completed += OnClosedStoryboardCompleted;
                            }
                        }
                    }
                }
            }

            // Customize the ApplicationBar Buttons by providing the right text
            if (null != ApplicationBar)
            {
                foreach (var obj in ApplicationBar.Buttons)
                {
                    var button = obj as IApplicationBarIconButton;

                    if (null != button)
                    {
                        switch (button.Text)
                        {
                        case "DONE":
                            button.Text   = Properties.Resources.DoneText;
                            button.Click += OnDoneButtonClick;
                            break;

                        case "CANCEL":
                            button.Text   = Properties.Resources.CancelText;
                            button.Click += OnCancelButtonClick;
                            break;
                        }
                    }
                }
            }

            // Play the Open state
            VisualStateManager.GoToState(this, OpenVisibilityStateName, true);
        }