Пример #1
0
        /// <summary>
        /// Arranges and sizes the
        /// <see cref="T:WinRTXamlToolkit.Controls.WrapPanel" /> control and its
        /// child elements.
        /// </summary>
        /// <param name="finalSize">
        /// The area within the parent that the
        /// <see cref="T:WinRTXamlToolkit.Controls.WrapPanel" /> should use
        /// arrange itself and its children.
        /// </param>
        /// <returns>
        /// The actual size used by the
        /// <see cref="T:WinRTXamlToolkit.Controls.WrapPanel" />.
        /// </returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // Variables tracking the size of the current line, and the maximum
            // size available to fill.  Note that the line might represent a row
            // or a column depending on the orientation.
            Orientation  o           = Orientation;
            OrientedSize lineSize    = new OrientedSize(o);
            OrientedSize maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height);

            // Determine the constraints for individual items
            double itemWidth      = ItemWidth;
            double itemHeight     = ItemHeight;
            bool   hasFixedWidth  = !itemWidth.IsNaN();
            bool   hasFixedHeight = !itemHeight.IsNaN();
            double indirectOffset = 0;
            double?directDelta    = (o == Orientation.Horizontal) ?
                                    (hasFixedWidth ? (double?)itemWidth : null) :
                                    (hasFixedHeight ? (double?)itemHeight : null);

            // Measure each of the Children.  We will process the elements one
            // line at a time, just like during measure, but we will wait until
            // we've completed an entire line of elements before arranging them.
            // The lineStart and lineEnd variables track the size of the
            // currently arranged line.
            UIElementCollection children = Children;
            int count     = children.Count;
            int lineStart = 0;

            for (int lineEnd = 0; lineEnd < count; lineEnd++)
            {
                UIElement element = children[lineEnd];

                // Get the size of the element
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height);

                // If this element falls of the edge of the line
                if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
                {
                    // Then we just completed a line and we should arrange it
                    ArrangeLine(lineStart, lineEnd, directDelta, indirectOffset, lineSize.Indirect);

                    // Move the current element to a new line
                    indirectOffset += lineSize.Indirect;
                    lineSize        = elementSize;

                    // If the current element is larger than the maximum size
                    if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
                    {
                        // Arrange the element as a single line
                        ArrangeLine(lineEnd, ++lineEnd, directDelta, indirectOffset, elementSize.Indirect);

                        // Move to a new line
                        indirectOffset += lineSize.Indirect;
                        lineSize        = new OrientedSize(o);
                    }

                    // Advance the start index to a new line after arranging
                    lineStart = lineEnd;
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct  += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            // Arrange any elements on the last line
            if (lineStart < count)
            {
                ArrangeLine(lineStart, count, directDelta, indirectOffset, lineSize.Indirect);
            }

            return(finalSize);
        }
Пример #2
0
        private bool HandleScrollByPage(bool up)
        {
            // NOTE: This implementation assumes that items are laid out
            // vertically and the Headers of the TreeViewItems appear above
            // their ItemsPresenter.  The same assumptions are made in WPF.

            ScrollViewer scrollHost = ItemsControlHelper.ScrollHost;

            if (scrollHost != null)
            {
                double viewportHeight = scrollHost.ViewportHeight;

                double top;
                double bottom;
                (SelectedContainer.HeaderElement ?? SelectedContainer).GetTopAndBottom(scrollHost, out top, out bottom);

                TreeViewItem selected = null;
                TreeViewItem next     = SelectedContainer;
                ItemsControl parent   = SelectedContainer.ParentItemsControl;

                if (parent != null)
                {
                    // We need to start at the root TreeViewItem if we're
                    // scrolling up, but can start at the SelectedItem if
                    // scrolling down.
                    if (up)
                    {
                        while (parent != this)
                        {
                            TreeViewItem parentItem = parent as TreeViewItem;
                            if (parentItem == null)
                            {
                                break;
                            }

                            ItemsControl grandparent = parentItem.ParentItemsControl;
                            if (grandparent == null)
                            {
                                break;
                            }

                            next   = parentItem;
                            parent = grandparent;
                        }
                    }

                    int index = parent.ItemContainerGenerator.IndexFromContainer(next);
                    int count = parent.Items.Count;
                    while (parent != null && next != null)
                    {
                        if (next.IsEnabled)
                        {
                            double delta;
                            if (next.HandleScrollByPage(up, scrollHost, viewportHeight, top, bottom, out delta))
                            {
                                // This item or one of its children was focused
                                return(true);
                            }
                            else if (NumericExtensions.IsGreaterThan(delta, viewportHeight))
                            {
                                // If the item doesn't fit on the page but it's
                                // already selected, we'll select the next item
                                // even though it doesn't completely fit into
                                // the current view
                                if (selected == SelectedContainer || selected == null)
                                {
                                    return(up ?
                                           SelectedContainer.HandleUpKey() :
                                           SelectedContainer.HandleDownKey());
                                }
                                break;
                            }
                            else
                            {
                                selected = next;
                            }
                        }

                        index += up ? -1 : 1;
                        if (0 <= index && index < count)
                        {
                            next = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                        }
                        else if (parent == this)
                        {
                            // We just finished with the last item in the
                            // TreeView
                            next = null;
                        }
                        else
                        {
                            // Move up the parent chain to the next item
                            while (parent != null)
                            {
                                TreeViewItem oldParent = parent as TreeViewItem;
                                parent = oldParent.ParentItemsControl;
                                if (parent != null)
                                {
                                    count = parent.Items.Count;
                                    index = parent.ItemContainerGenerator.IndexFromContainer(oldParent) + (up ? -1 : 1);
                                    if (0 <= index && index < count)
                                    {
                                        next = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                                        break;
                                    }
                                    else if (parent == this)
                                    {
                                        next   = null;
                                        parent = null;
                                    }
                                }
                            }
                        }
                    }
                }

                if (selected != null)
                {
                    if (up)
                    {
                        if (selected != SelectedContainer)
                        {
                            return(selected.Focus(FocusState.Programmatic));
                        }
                    }
                    else
                    {
                        selected.FocusInto();
                    }
                }
            }

            return(false);
        }
Пример #3
0
        protected override Size MeasureOverride(Size constraint)
        {
            // Variables tracking the size of the current line, the total size
            // measured so far, and the maximum size available to fill.  Note
            // that the line might represent a row or a column depending on the
            // orientation.
            Orientation  o           = Orientation;
            OrientedSize lineSize    = new OrientedSize(o);
            OrientedSize totalSize   = new OrientedSize(o);
            OrientedSize maximumSize = new OrientedSize(o, constraint.Width, constraint.Height);

            // Determine the constraints for individual items
            double itemWidth      = ItemWidth;
            double itemHeight     = ItemHeight;
            bool   hasFixedWidth  = !double.IsNaN(itemWidth);
            bool   hasFixedHeight = !double.IsNaN(itemHeight);
            Size   itemSize       = new Size(
                hasFixedWidth ? itemWidth : constraint.Width,
                hasFixedHeight ? itemHeight : constraint.Height);

            // Measure each of the Children
            foreach (UIElement element in Children)
            {
                // Determine the size of the element
                element.Measure(itemSize);
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height);

                // If this element falls of the edge of the line
                if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
                {
                    // Update the total size with the direct and indirect growth
                    // for the current line
                    totalSize.Direct    = Math.Max(lineSize.Direct, totalSize.Direct);
                    totalSize.Indirect += lineSize.Indirect;

                    // Move the element to a new line
                    lineSize = elementSize;

                    // If the current element is larger than the maximum size,
                    // place it on a line by itself
                    if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
                    {
                        // Update the total size for the line occupied by this
                        // single element
                        totalSize.Direct    = Math.Max(elementSize.Direct, totalSize.Direct);
                        totalSize.Indirect += elementSize.Indirect;

                        // Move to a new line
                        lineSize = new OrientedSize(o);
                    }
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct  += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            // Update the total size with the elements on the last line
            totalSize.Direct    = Math.Max(lineSize.Direct, totalSize.Direct);
            totalSize.Indirect += lineSize.Indirect;

            // Return the total size required as an un-oriented quantity
            return(new Size(totalSize.Width, totalSize.Height));
        }
Пример #4
0
        /// <summary>
        /// Handle keys related to scrolling.
        /// </summary>
        /// <param name="key">The key to handle.</param>
        /// <returns>A value indicating whether the key was handled.</returns>
        private bool HandleScrollKeys(VirtualKey key)
        {
            ScrollViewer scrollHost = ItemsControlHelper.ScrollHost;

            if (scrollHost != null)
            {
                // Some keys (e.g. Left/Right) need to be translated in RightToLeft mode
                VirtualKey invariantKey = InteractionHelper.GetLogicalKey(FlowDirection, key);

                switch (invariantKey)
                {
                case VirtualKey.PageUp:
                    // Move horizontally if we've run out of room vertically
                    if (!NumericExtensions.IsGreaterThan(scrollHost.ExtentHeight, scrollHost.ViewportHeight))
                    {
                        scrollHost.PageLeft();
                    }
                    else
                    {
                        scrollHost.PageUp();
                    }
                    return(true);

                case VirtualKey.PageDown:
                    // Move horizontally if we've run out of room vertically
                    if (!NumericExtensions.IsGreaterThan(scrollHost.ExtentHeight, scrollHost.ViewportHeight))
                    {
                        scrollHost.PageRight();
                    }
                    else
                    {
                        scrollHost.PageDown();
                    }
                    return(true);

                case VirtualKey.Home:
                    scrollHost.ScrollToTop();
                    return(true);

                case VirtualKey.End:
                    scrollHost.ScrollToBottom();
                    return(true);

                case VirtualKey.Left:
                    scrollHost.LineLeft();
                    return(true);

                case VirtualKey.Right:
                    scrollHost.LineRight();
                    return(true);

                case VirtualKey.Up:
                    scrollHost.LineUp();
                    return(true);

                case VirtualKey.Down:
                    scrollHost.LineDown();
                    return(true);
                }
            }
            return(false);
        }