예제 #1
0
        /// <summary>
        /// Draws the content of a <see cref="T:System.Windows.Media.DrawingContext" /> object during the render pass of a <see cref="T:System.Windows.Controls.Panel" /> element.
        /// </summary>
        /// <param name="dc">The <see cref="T:System.Windows.Media.DrawingContext" /> object to draw.</param>
        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            if (!ShowGroupHeaders || GroupHeaderRenderer == null)
            {
                return;
            }

            var offsetTop = 0d;

            if (_scrollVertical.Visibility == Visibility.Visible)
            {
                offsetTop = _scrollVertical.Value * -1;
            }

            var currentTop             = offsetTop + Padding.Top;
            var currentGroupIsExpanded = true;

            foreach (var control in _lastControls)
            {
                var lineHeight = 0d;
                if (control.Label != null)
                {
                    lineHeight = control.Label.DesiredSize.Height;
                }
                if (control.Edit != null)
                {
                    lineHeight = Math.Max(lineHeight, control.Edit.DesiredSize.Height);
                }
                lineHeight = SnapToPixel(lineHeight);

                if (control.Label != null && SimpleView.GetGroupBreak(control.Label))
                {
                    var groupTitle = SimpleView.GetGroupTitle(control.Label);
                    if (_renderedGroups.ContainsKey(groupTitle))
                    {
                        currentGroupIsExpanded = _renderedGroups[groupTitle].IsExpanded;

                        var group = _renderedGroups[groupTitle];
                        var width = ActualWidth - Padding.Left - Padding.Right;
                        if (_scrollVertical.Visibility == Visibility.Visible)
                        {
                            width -= SystemParameters.VerticalScrollBarWidth;
                        }
                        dc.PushTransform(new TranslateTransform(Padding.Left, currentTop));
                        GroupHeaderRenderer.RenderHeader(dc, currentTop, width, groupTitle, group.IsExpanded);
                        dc.Pop();
                        group.LastRenderTopPosition = currentTop;

                        currentTop += _renderedGroups[groupTitle].Height;
                    }
                }

                if (currentGroupIsExpanded)
                {
                    currentTop += lineHeight + VerticalElementSpacing;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Invoked when an unhandled MouseDown attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> that contains the event data. This event data reports details about the mouse button that was pressed and the handled state.</param>
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && e.ClickCount == 1)
            {
                foreach (var control in _lastControls)
                {
                    if (control.Label != null && SimpleView.GetGroupBreak(control.Label))
                    {
                        var groupTitle = SimpleView.GetGroupTitle(control.Label);
                        if (_renderedGroups.ContainsKey(groupTitle))
                        {
                            var group     = _renderedGroups[groupTitle];
                            var y         = group.LastRenderTopPosition;
                            var positionY = e.GetPosition(this).Y;
                            if (positionY >= y && positionY <= y + group.Height)
                            {
                                e.Handled        = true;
                                group.IsExpanded = !group.IsExpanded;
                                InvalidateMeasure();
                                InvalidateArrange();
                                InvalidateVisual();
                                return;
                            }
                        }
                    }
                }
            }

            base.OnMouseDown(e);
        }
예제 #3
0
        /// <summary>
        /// When overridden in a derived class, positions child elements and determines a size for a <see cref="T:System.Windows.FrameworkElement" /> derived class.
        /// </summary>
        /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
        /// <returns>The actual size used.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            var finalSizeInternal = finalSize;

            if (Padding.Top > 0 || Padding.Bottom > 0 || Padding.Right > 0 || Padding.Left > 0)
            {
                var availableHeight = finalSize.Height - Padding.Top - Padding.Bottom;
                if (availableHeight < 0d)
                {
                    availableHeight = 0d;
                }
                var availableWidth = finalSize.Width - Padding.Left - Padding.Right;
                if (availableWidth < 0d)
                {
                    availableWidth = 0d;
                }
                finalSizeInternal = GeometryHelper.NewSize(availableWidth, availableHeight);
            }

            if (_lastControls == null)
            {
                return(base.ArrangeOverride(finalSize));
            }

            var finalWidth = finalSizeInternal.Width;

            if (_scrollVertical.Visibility == Visibility.Visible)
            {
                finalWidth = Math.Max(finalWidth - SystemParameters.VerticalScrollBarWidth, 1);
            }

            var offsetTop = 0d;

            if (_scrollVertical.Visibility == Visibility.Visible)
            {
                offsetTop = _scrollVertical.Value * -1;
            }

            var currentTop = offsetTop + Padding.Top;

            if (!ShowGroupHeaders || GroupHeaderRenderer == null)
            {
                foreach (var control in _lastControls)
                {
                    var lineHeight = 0d;
                    if (control.Label != null)
                    {
                        lineHeight = control.Label.DesiredSize.Height;
                    }
                    if (control.Edit != null)
                    {
                        lineHeight = Math.Max(lineHeight, control.Edit.DesiredSize.Height);
                    }
                    lineHeight = SnapToPixel(lineHeight);

                    if (control.Label != null)
                    {
                        if (!control.LabelSpansFullWidth)
                        {
                            control.Label.Arrange(GeometryHelper.NewRect(Padding.Left, currentTop, _labelWidth, lineHeight));
                        }
                        else
                        {
                            control.Label.Arrange(GeometryHelper.NewRect(Padding.Left, currentTop, SnapToPixel(finalWidth), lineHeight));
                        }
                    }
                    if (control.Edit != null && !control.LabelSpansFullWidth)
                    {
                        var editLeft  = SnapToPixel(_labelWidth + HorizontalElementSpacing + Padding.Left);
                        var editWidth = Math.Max(SnapToPixel(finalWidth - editLeft + Padding.Left), 0);

                        for (var flowControlCounter = control.AdditionalEditControls.Count - 1; flowControlCounter >= 0; flowControlCounter--)
                        {
                            var flowControl = control.AdditionalEditControls[flowControlCounter];
                            var flowWidth   = Math.Min(flowControl.DesiredSize.Width, editWidth);
                            flowControl.Arrange(GeometryHelper.NewRect(editLeft + editWidth - flowWidth, currentTop, flowWidth, lineHeight));
                            editWidth -= (flowWidth + AdditionalFlowElementSpacing);
                            if (editWidth < 0.1)
                            {
                                editWidth = 0d;
                            }
                        }

                        control.Edit.Arrange(GeometryHelper.NewRect(editLeft, currentTop, editWidth, lineHeight));
                    }
                    currentTop += lineHeight + VerticalElementSpacing;
                }
            }
            else
            {
                var itemIndent             = GroupHeaderRenderer.GetHeaderPaddingUsedForRendering("X").Left;
                var currentGroupIsExpanded = true;
                foreach (var control in _lastControls)
                {
                    var lineHeight = 0d;
                    if (control.Label != null)
                    {
                        lineHeight = control.Label.DesiredSize.Height;
                    }
                    if (control.Edit != null)
                    {
                        lineHeight = Math.Max(lineHeight, control.Edit.DesiredSize.Height);
                    }
                    lineHeight = SnapToPixel(lineHeight);

                    if (control.Label != null && SimpleView.GetGroupBreak(control.Label))
                    {
                        var groupTitle = SimpleView.GetGroupTitle(control.Label);
                        if (_renderedGroups.ContainsKey(groupTitle))
                        {
                            currentGroupIsExpanded = _renderedGroups[groupTitle].IsExpanded;
                            currentTop            += _renderedGroups[groupTitle].Height;
                        }
                    }

                    if (currentGroupIsExpanded)
                    {
                        if (control.Label != null)
                        {
                            control.Label.Visibility = Visibility.Visible;
                            if (!control.LabelSpansFullWidth)
                            {
                                control.Label.Arrange(GeometryHelper.NewRect(Padding.Left + itemIndent, currentTop, _labelWidth, lineHeight));
                            }
                            else
                            {
                                control.Label.Arrange(GeometryHelper.NewRect(Padding.Left + itemIndent, currentTop, SnapToPixel(finalWidth - itemIndent), lineHeight));
                            }
                        }
                        if (control.Edit != null)
                        {
                            control.Edit.Visibility = Visibility.Visible;
                            var editLeft  = SnapToPixel(_labelWidth + HorizontalElementSpacing + Padding.Left + itemIndent);
                            var editWidth = Math.Max(SnapToPixel(finalWidth - editLeft + Padding.Left), 0);

                            for (var flowControlCounter = control.AdditionalEditControls.Count - 1; flowControlCounter >= 0; flowControlCounter--)
                            {
                                var flowControl = control.AdditionalEditControls[flowControlCounter];
                                var flowWidth   = Math.Min(flowControl.DesiredSize.Width, editWidth);
                                flowControl.Visibility = Visibility.Visible;
                                flowControl.Arrange(GeometryHelper.NewRect(editLeft + editWidth - flowWidth, currentTop, flowWidth, lineHeight));
                                editWidth -= (flowWidth + AdditionalFlowElementSpacing);
                                if (editWidth < 0.1)
                                {
                                    editWidth = 0d;
                                }
                            }

                            control.Edit.Arrange(GeometryHelper.NewRect(editLeft, currentTop, editWidth, lineHeight));
                        }
                        currentTop += lineHeight + VerticalElementSpacing;
                    }
                    else
                    {
                        if (control.Label != null)
                        {
                            control.Label.Visibility = Visibility.Collapsed;
                        }
                        if (control.Edit != null)
                        {
                            control.Edit.Visibility = Visibility.Collapsed;
                        }
                        foreach (var flowControl in control.AdditionalEditControls)
                        {
                            flowControl.Visibility = Visibility.Collapsed;
                        }
                    }
                }
            }

            return(base.ArrangeOverride(finalSize));
        }
예제 #4
0
        /// <summary>
        /// When overridden in a derived class, measures the size in layout required for child elements and determines a size for the <see cref="T:System.Windows.FrameworkElement" />-derived class.
        /// </summary>
        /// <param name="availableSize">The available size that this element can give to child elements. Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param>
        /// <returns>The size that this element determines it needs during layout, based on its calculations of child element sizes.</returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            var availableSizeInternal = availableSize;

            if (Padding.Top > 0 || Padding.Bottom > 0 || Padding.Right > 0 || Padding.Left > 0)
            {
                var availableHeight = availableSize.Height - Padding.Top - Padding.Bottom;
                if (availableHeight < 0d)
                {
                    availableHeight = 0d;
                }
                var availableWidth = availableSize.Width - Padding.Left - Padding.Right;
                if (availableWidth < 0d)
                {
                    availableWidth = 0d;
                }
                availableSizeInternal = GeometryHelper.NewSize(availableWidth, availableHeight);
            }

            _lastControls = GetControls();
            InvalidateVisual();

            var widestLabel = 0d;
            var totalHeight = 0d;

            var foundGroupHeader = false;
            var groupPadding     = new Thickness();

            if (ShowGroupHeaders && GroupHeaderRenderer != null)
            {
                foundGroupHeader = _lastControls.Where(c => c.Label != null).Any(control => !string.IsNullOrEmpty(SimpleView.GetGroupTitle(control.Label)));
            }
            if (foundGroupHeader)
            {
                groupPadding          = GroupHeaderRenderer.GetHeaderPaddingUsedForRendering("X");
                availableSizeInternal = GeometryHelper.NewSize(Math.Max(availableSizeInternal.Width - groupPadding.Left, 0), Math.Max(availableSizeInternal.Height, 0));
            }

            foreach (var control in _lastControls.Where(c => c.Label != null))
            {
                control.Label.Measure(availableSizeInternal);
                if (!control.LabelSpansFullWidth) // For widest-label measurements, we do not consider span labels, since they always use the full width
                {
                    widestLabel = Math.Max(control.Label.DesiredSize.Width, widestLabel);
                }
            }
            foreach (var control in _lastControls.Where(c => !c.LabelSpansFullWidth && c.Edit != null))
            {
                var currentMaxWidth = SnapToPixel(availableSizeInternal.Width - widestLabel - HorizontalElementSpacing - groupPadding.Left);
                for (var flowControlCounter = control.AdditionalEditControls.Count - 1; flowControlCounter >= 0; flowControlCounter--)
                {
                    var flowControl       = control.AdditionalEditControls[flowControlCounter];
                    var availableEditSize = GeometryHelper.NewSize(currentMaxWidth, availableSize.Height);
                    flowControl.Measure(availableEditSize);
                    currentMaxWidth = Math.Max(SnapToPixel(currentMaxWidth - flowControl.DesiredSize.Width), 0);
                }
                control.Edit.Measure(GeometryHelper.NewSize(currentMaxWidth, availableSize.Height));
            }

            var currentGroupIsExpanded = true;

            foreach (var control in _lastControls)
            {
                var itemHeight = 0d;
                if (control.Label != null)
                {
                    itemHeight = control.Label.DesiredSize.Height;
                }
                if (control.Edit != null && !control.LabelSpansFullWidth)
                {
                    itemHeight = Math.Max(itemHeight, control.Edit.DesiredSize.Height);
                    foreach (var flowControl in control.AdditionalEditControls)
                    {
                        itemHeight = Math.Max(itemHeight, flowControl.DesiredSize.Height);
                    }
                }

                itemHeight = SnapToPixel(itemHeight);

                if (ShowGroupHeaders && control.Label != null && GroupHeaderRenderer != null && SimpleView.GetGroupBreak(control.Label))
                {
                    var groupHeader = SimpleView.GetGroupTitle(control.Label) ?? string.Empty;
                    if (!_renderedGroups.ContainsKey(groupHeader))
                    {
                        _renderedGroups.Add(groupHeader, new PropertySheetGroupHeaderInfo {
                            IsExpanded = true
                        });
                    }
                    currentGroupIsExpanded = _renderedGroups[groupHeader].IsExpanded;
                    var currentPadding = GroupHeaderRenderer.GetHeaderPaddingUsedForRendering(string.IsNullOrEmpty(groupHeader) ? "X" : groupHeader);
                    _renderedGroups[groupHeader].Height = currentPadding.Top;
                    totalHeight += SnapToPixel(currentPadding.Top);
                }

                if (currentGroupIsExpanded)
                {
                    totalHeight += itemHeight + VerticalElementSpacing;
                }
            }

            _labelWidth      = widestLabel;
            totalHeight     += Padding.Top + Padding.Bottom;
            _lastTotalHeight = totalHeight;

            HandleScrollBarVisibility(totalHeight, availableSize);

            if (_scrollVertical.Visibility == Visibility.Visible)
            {
                foreach (var control in _lastControls.Where(c => !c.LabelSpansFullWidth && c.Edit != null))
                {
                    var currentMaxWidth = SnapToPixel(SnapToPixel(availableSizeInternal.Width - widestLabel - HorizontalElementSpacing - SystemParameters.VerticalScrollBarWidth - 1));
                    for (var flowControlCounter = control.AdditionalEditControls.Count - 1; flowControlCounter >= 0; flowControlCounter--)
                    {
                        var flowControl       = control.AdditionalEditControls[flowControlCounter];
                        var availableEditSize = GeometryHelper.NewSize(currentMaxWidth, availableSize.Height);
                        flowControl.Measure(availableEditSize);
                        currentMaxWidth = Math.Max(SnapToPixel(currentMaxWidth - flowControl.DesiredSize.Width), 0);
                    }
                    control.Edit.Measure(GeometryHelper.NewSize(currentMaxWidth, availableSize.Height));
                }
            }

            return(GeometryHelper.NewSize(availableSize.Width, Math.Min(totalHeight, availableSize.Height)));
        }