| File: System\Windows\Navigation\JournalEntryListConverter.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // // Description: Implements the Converter to limit journal views to 9 items. // // // using System.Collections; using System.Collections.Specialized; using System.Globalization; using System.Windows.Data; namespace System.Windows.Navigation { /// <summary> /// This class returns an IEnumerable that is limited in length - it is used by the NavigationWindow /// style to limit how many entries are shown in the back and forward drop down buttons. Not /// intended to be used in any other situations. /// </summary> public sealed class JournalEntryListConverter : IValueConverter { /// <summary> /// This method from IValueConverter returns an IEnumerable which in turn will yield the /// ViewLimit limited collection of journal back and forward stack entries. /// </summary> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (value != null) ? ((JournalEntryStack)value).GetLimitedJournalEntryStackEnumerable() : null; } /// <summary> /// This method from IValueConverter returns an IEnumerable which was originally passed to Convert /// </summary> public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return Binding.DoNothing; } } /// <summary> /// Describes the position of the journal entry relative to the current page. /// </summary> public enum JournalEntryPosition { /// <summary> /// The entry is on the BackStack /// </summary> Back, /// <summary> /// The current page /// </summary> Current, /// <summary> /// The entry on the ForwardStack /// </summary> Forward, } /// <summary> /// Puts all of the journal entries into a single list, for an IE7-style menu. /// </summary> public sealed class JournalEntryUnifiedViewConverter : IMultiValueConverter { /// <summary> /// The DependencyProperty for the JournalEntryPosition property. /// </summary> public static readonly DependencyProperty JournalEntryPositionProperty = DependencyProperty.RegisterAttached( "JournalEntryPosition", typeof(JournalEntryPosition), typeof(JournalEntryUnifiedViewConverter), new PropertyMetadata(JournalEntryPosition.Current)); /// <summary> /// Helper for reading the JournalEntryPosition property. /// </summary> public static JournalEntryPosition GetJournalEntryPosition(DependencyObject element) { ArgumentNullException.ThrowIfNull(element); return ((JournalEntryPosition)element.GetValue(JournalEntryPositionProperty)); } /// <summary> /// Helper for setting the JournalEntryPosition property. /// </summary> public static void SetJournalEntryPosition(DependencyObject element, JournalEntryPosition position) { ArgumentNullException.ThrowIfNull(element); element.SetValue(JournalEntryPositionProperty, position); } /// <summary> /// This method from IValueConverter returns an IEnumerable which in turn will yield the /// single list containing all of the menu items. /// </summary> public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (values != null && values.Length == 2) { JournalEntryStack backStack = values[0] as JournalEntryStack; JournalEntryStack forwardStack = values[1] as JournalEntryStack; if (backStack != null && forwardStack != null) { LimitedJournalEntryStackEnumerable limitedBackStack = (LimitedJournalEntryStackEnumerable)backStack.GetLimitedJournalEntryStackEnumerable(); LimitedJournalEntryStackEnumerable limitedForwardStack = (LimitedJournalEntryStackEnumerable)forwardStack.GetLimitedJournalEntryStackEnumerable(); return new UnifiedJournalEntryStackEnumerable(limitedBackStack, limitedForwardStack); } } return null; } /// <summary> /// This method is unused. /// </summary> public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { return new object[] { Binding.DoNothing }; } } // Merges LimitedBack and Forward Stack into one list and internal class UnifiedJournalEntryStackEnumerable : IEnumerable, INotifyCollectionChanged { internal UnifiedJournalEntryStackEnumerable(LimitedJournalEntryStackEnumerable backStack, LimitedJournalEntryStackEnumerable forwardStack) { _backStack = backStack; _backStack.CollectionChanged += new NotifyCollectionChangedEventHandler(StacksChanged); _forwardStack = forwardStack; _forwardStack.CollectionChanged += new NotifyCollectionChangedEventHandler(StacksChanged); } public IEnumerator GetEnumerator() { if (_items == null) { // Reserve space so this will not have to reallocate. The most it will ever be is // 9 for the forward stack, 9 for the back stack, 1 for the title bar _items = new ArrayList(19); // Add ForwardStack in reverse order foreach (JournalEntry o in _forwardStack) { _items.Insert(0, o); JournalEntryUnifiedViewConverter.SetJournalEntryPosition(o, JournalEntryPosition.Forward); } DependencyObject current = new DependencyObject(); current.SetValue(JournalEntry.NameProperty, SR.NavWindowMenuCurrentPage); // "Current Page" _items.Add(current); foreach (JournalEntry o in _backStack) { _items.Add(o); JournalEntryUnifiedViewConverter.SetJournalEntryPosition(o, JournalEntryPosition.Back); } } return _items.GetEnumerator(); } internal void StacksChanged(object sender, NotifyCollectionChangedEventArgs e) { _items = null; if (CollectionChanged != null) { CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } public event NotifyCollectionChangedEventHandler CollectionChanged; private LimitedJournalEntryStackEnumerable _backStack, _forwardStack; private ArrayList _items; } }