Exemple #1
0
        private void OnSelectedSourceChanged(Uri oldValue, Uri newValue)
        {
            // Uri "Page1.xaml#111" and "Page1#222" points to the same page, but with a different fragment
            // Must remove the fragment to avoid believing we are on different pages.
            Uri oldValueNoFragment = NavigationHelper.RemoveFragment(oldValue);
            Uri newValueNoFragment = NavigationHelper.RemoveFragment(newValue);

            if (!this.isSelecting)
            {
                // if old and new are equal, don't do anything
                if (newValueNoFragment != null && newValueNoFragment.Equals(oldValueNoFragment))
                {
                    return;
                }

                UpdateSelection();
            }

            // raise SelectedSourceChanged event
            var handler = this.SelectedSourceChanged;

            if (handler != null)
            {
                handler(this, new SourceEventArgs(newValue));
            }
        }
Exemple #2
0
        private void OnSourceChanged(Uri oldValue, Uri newValue)
        {
            // if resetting source or old source equals new, don't do anything
            if (this.isResetSource || newValue != null && newValue.Equals(oldValue))
            {
                return;
            }

            // handle fragment navigation
            string newFragment        = null;
            var    oldValueNoFragment = NavigationHelper.RemoveFragment(oldValue);
            var    newValueNoFragment = NavigationHelper.RemoveFragment(newValue, out newFragment);

            if (newValueNoFragment != null && newValueNoFragment.Equals(oldValueNoFragment))
            {
                // fragment navigation
                var args = new FragmentNavigationEventArgs {
                    Fragment = newFragment
                };

                OnFragmentNavigation(this.Content as IContent, args);
            }
            else
            {
                var navType = this.isNavigatingHistory ? NavigationType.Back : NavigationType.New;

                // only invoke CanNavigate for new navigation
                if (!this.isNavigatingHistory && !CanNavigate(oldValue, newValue, navType))
                {
                    return;
                }

                Navigate(oldValue, newValue, navType);
            }
        }
Exemple #3
0
        private void UpdateSelection()
        {
            LinkGroup selectedGroup = null;
            Link      selectedLink  = null;

            Uri sourceNoFragment = NavigationHelper.RemoveFragment(this.SelectedSource);

            if (this.LinkGroups != null)
            {
                // find the current select group and link based on the selected source
                var linkInfo = (from g in this.LinkGroups
                                from l in g.Links
                                where l.Source == sourceNoFragment
                                select new {
                    Group = g,
                    Link = l
                }).FirstOrDefault();

                if (linkInfo != null)
                {
                    selectedGroup = linkInfo.Group;
                    selectedLink  = linkInfo.Link;
                }
                else
                {
                    // could not find link and group based on selected source, fall back to selected link group
                    selectedGroup = this.SelectedLinkGroup;

                    // if selected group doesn't exist in available groups, select first group
                    if (!this.LinkGroups.Any(g => g == selectedGroup))
                    {
                        selectedGroup = this.LinkGroups.FirstOrDefault();
                    }
                }
            }

            ReadOnlyLinkGroupCollection groups = null;

            if (selectedGroup != null)
            {
                // ensure group itself maintains the selected link
                selectedGroup.SelectedLink = selectedLink;

                // find the collection this group belongs to
                var groupKey = GetGroupKey(selectedGroup);
                this.groupMap.TryGetValue(groupKey, out groups);
            }

            this.isSelecting = true;
            // update selection
            SetValue(VisibleLinkGroupsPropertyKey, groups);
            SetCurrentValue(SelectedLinkGroupProperty, selectedGroup);
            SetCurrentValue(SelectedLinkProperty, selectedLink);
            this.isSelecting = false;
        }
Exemple #4
0
        private void SetContent(Uri newSource, NavigationType navigationType, object newContent, bool contentIsError)
        {
            var oldContent = this.Content as IContent;

            // assign content
            this.Content = newContent;

            // do not raise navigated event when error
            if (!contentIsError)
            {
                var args = new NavigationEventArgs {
                    Frame          = this,
                    Source         = newSource,
                    Content        = newContent,
                    NavigationType = navigationType
                };

                OnNavigated(oldContent, newContent as IContent, args);
            }

            // set IsLoadingContent to false
            SetValue(IsLoadingContentPropertyKey, false);

            if (!contentIsError)
            {
                // and raise optional fragment navigation events
                string fragment;
                NavigationHelper.RemoveFragment(newSource, out fragment);
                if (fragment != null)
                {
                    // fragment navigation
                    var fragmentArgs = new FragmentNavigationEventArgs {
                        Fragment = fragment
                    };

                    OnFragmentNavigation(newContent as IContent, fragmentArgs);
                }
            }
        }
Exemple #5
0
        private void Navigate(Uri oldValue, Uri newValue, NavigationType navigationType)
        {
            Debug.WriteLine("Navigating from '{0}' to '{1}'", oldValue, newValue);

            // set IsLoadingContent state
            SetValue(IsLoadingContentPropertyKey, true);

            // cancel previous load content task (if any)
            // note: no need for thread synchronization, this code always executes on the UI thread
            if (this.tokenSource != null)
            {
                this.tokenSource.Cancel();
                this.tokenSource = null;
            }

            // push previous source onto the history stack (only for new navigation types)
            if (oldValue != null && navigationType == NavigationType.New)
            {
                this.history.Push(oldValue);
            }

            object newContent = null;

            if (newValue != null)
            {
                // content is cached on uri without fragment
                var newValueNoFragment = NavigationHelper.RemoveFragment(newValue);

                if (navigationType == NavigationType.Refresh || !this.contentCache.TryGetValue(newValueNoFragment, out newContent))
                {
                    var localTokenSource = new CancellationTokenSource();
                    this.tokenSource = localTokenSource;
                    // load the content (asynchronous!)
                    var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
                    var task      = this.ContentLoader.LoadContentAsync(newValue, this.tokenSource.Token);

                    task.ContinueWith(t => {
                        try {
                            if (t.IsCanceled || localTokenSource.IsCancellationRequested)
                            {
                                Debug.WriteLine("Cancelled navigation to '{0}'", newValue);
                            }
                            else if (t.IsFaulted)
                            {
                                // raise failed event
                                var failedArgs = new NavigationFailedEventArgs {
                                    Frame   = this,
                                    Source  = newValue,
                                    Error   = t.Exception.InnerException,
                                    Handled = false
                                };

                                OnNavigationFailed(failedArgs);

                                // if not handled, show error as content
                                newContent = failedArgs.Handled ? null : failedArgs.Error;

                                SetContent(newValue, navigationType, newContent, true);
                            }
                            else
                            {
                                newContent = t.Result;
                                if (ShouldKeepContentAlive(newContent))
                                {
                                    // keep the new content in memory
                                    this.contentCache[newValueNoFragment] = newContent;
                                }

                                SetContent(newValue, navigationType, newContent, false);
                            }
                        }
                        finally {
                            // clear global tokenSource to avoid a Cancel on a disposed object
                            if (this.tokenSource == localTokenSource)
                            {
                                this.tokenSource = null;
                            }

                            // and dispose of the local tokensource
                            localTokenSource.Dispose();
                        }
                    }, scheduler);
                    return;
                }
            }

            // newValue is null or newContent was found in the cache
            SetContent(newValue, navigationType, newContent, false);
        }