Ejemplo n.º 1
0
        private void Rectangle_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (sender is Rectangle rectangle)
            {
                var stackPanel = VisualTreeTraverseHelper.FindParent <StackPanel>(rectangle);
                if (stackPanel != null)
                {
                    // we've got this!
                }

                var grid = VisualTreeTraverseHelper.FindParent <Grid>(rectangle);
                if (grid != null)
                {
                    // we've got this!
                }

                var lazyStackPanel = VisualTreeTraverseHelper.FindVisualParentByName(rectangle, "LazyStackPanel") as StackPanel;
                if (lazyStackPanel != null)
                {
                    // cool
                }
            }
        }
Ejemplo n.º 2
0
        // Control authors who want to customize the arrange pass of layout processing should
        // override this method. The implementation pattern should call Arrange(Rect) on each visible child element,
        // and pass the final desired size for each child element as the finalRect parameter. Parent elements should
        // call Arrange(Rect) on each child, otherwise the child elements will not be rendered.
        protected override Size ArrangeOverride(Size finalSize)
        {
            this._numberOfChildren = 0;
            var listOfWidths = new List <double>();
            var location     = new Point();

            var listView = VisualTreeTraverseHelper.FindParent <ListView>(this.TemplatedParent);

            if (listView != null)
            {
                // get all of the desired widths in order
                // to pick up the greatest width of all children
                for (int i = 0; i < listView.Items.Count; i++)
                {
                    var listViewItem = (ListViewItem)listView.ItemContainerGenerator.ContainerFromIndex(i);
                    if (listViewItem != null)
                    {
                        var rootStackPanel = VisualTreeTraverseHelper.FindDescendant <StackPanel>(listViewItem);
                        if (rootStackPanel != null)
                        {
                            foreach (var child in rootStackPanel.Children)
                            {
                                var frameworkElement = child as FrameworkElement;
                                if (frameworkElement != null)
                                {
                                    listOfWidths.Add(frameworkElement.DesiredSize.Width);
                                }
                            }
                        }
                    }
                }

                // first pass won't have any desired sizes
                // second pass should have.
                if (listOfWidths.Count > 0)
                {
                    double maxValue = listOfWidths.Max <double>();

                    // iterate through children again, but this time
                    // let's set our desired width to each of them
                    for (int i = 0; i < listView.Items.Count; i++)
                    {
                        var listViewItem = (ListViewItem)listView.ItemContainerGenerator.ContainerFromIndex(i);
                        if (listViewItem != null)
                        {
                            var rootStackPanel = VisualTreeTraverseHelper.FindDescendant <StackPanel>(listViewItem);
                            if (rootStackPanel != null)
                            {
                                foreach (var child in rootStackPanel.Children)
                                {
                                    var frameworkElement = child as FrameworkElement;
                                    if (frameworkElement != null)
                                    {
                                        frameworkElement.Width = maxValue;
                                        _numberOfChildren++;
                                    }
                                }
                            }
                        }
                    }

                    // calculates width of whole item
                    _totalChildWidth = Math.Round(((maxValue * _numberOfChildren) + ADDITIONAL_SPACE), DECIMAL_PLACES);

                    // this must be called in order to re-calculate
                    // each child size that it's needed to display
                    foreach (UIElement child in InternalChildren)
                    {
                        child.Measure(new Size(_totalChildWidth, child.DesiredSize.Height));
                    }
                }
            }

            // final screen positioning
            foreach (UIElement child in InternalChildren)
            {
                // set child position on the screen
                // since location.Y has been incremented
                // each child will stack vertically
                child.Arrange(new Rect(location, child.DesiredSize));
                location.Y += child.DesiredSize.Height;
            }
            return(finalSize);
        }
Ejemplo n.º 3
0
        // Control authors who want to customize the arrange pass of layout processing should
        // override this method. The implementation pattern should call Arrange(Rect) on each visible child element,
        // and pass the final desired size for each child element as the finalRect parameter. Parent elements should
        // call Arrange(Rect) on each child, otherwise the child elements will not be rendered.
        protected override Size ArrangeOverride(Size finalSize)
        {
            var location = new Point();
            var listOfNotStretchedItemsWidth = new List <double>();
            var numberOfHorizontalStretched  = 0;
            var lengthOfItemsControlItems    = 0;
            var totalParentWidth             = 0.0;
            var widthOfStretchedItem         = 0.0;

            // iterate through itemscontrol children in order
            // to check how many of these children have horizontalaligmnent
            // set to stretched. These calculations are needed to split available
            // width into equal parts among stretched children
            var listView = VisualTreeTraverseHelper.FindParent <ListView>(this.TemplatedParent);

            if (listView != null && listView.Items != null)
            {
                for (int i = 0; i < listView.Items.Count; i++)
                {
                    // generate container from particular index
                    // to check if it's stretched or not
                    var childContainer = listView.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
                    if (childContainer != null)
                    {
                        // change thickness depending on thickness
                        // that was given by us through dependency
                        // property called 'Spacing'
                        if (this.Orientation != Orientation.Vertical)
                        {
                            if ((Spacing.Right > 0 || Spacing.Left > 0) && i < listView.Items.Count)
                            {
                                childContainer.Margin = new Thickness(Spacing.Left, 0, Spacing.Right, 0);
                            }
                        }
                        else
                        {
                            if ((Spacing.Top > 0 || Spacing.Bottom > 0) && i < listView.Items.Count - 1)
                            {
                                childContainer.Margin = new Thickness(0, Spacing.Top, 0, Spacing.Bottom);
                            }
                        }

                        // if container has stretched alignment then
                        // increment given value for further calculations
                        if (childContainer.HorizontalAlignment == HorizontalAlignment.Stretch)
                        {
                            numberOfHorizontalStretched++;
                        }
                        else
                        {
                            // store width of non-stretched items
                            // to calculate a proper logic for
                            // the stretched once.
                            listOfNotStretchedItemsWidth.Add(childContainer.DesiredSize.Width);
                        }
                    }
                }

                // get number of stretched children
                lengthOfItemsControlItems = numberOfHorizontalStretched;
            }

            // setting up HorizontalAlighment on the control itself to stretch
            // will make sure that the finalSize.Width is equal to the maximum
            // available size. It will fit it's parent.
            totalParentWidth = finalSize.Width;

            // if there's children with different state
            // of horizontalalignment then remove previously
            // stored widths from the totalParentWidths
            // in order to split stretched children into equal parts.
            if (listOfNotStretchedItemsWidth.Count > 0)
            {
                foreach (var element in listOfNotStretchedItemsWidth)
                {
                    totalParentWidth -= element;
                }
            }

            // divide width for stretched child into
            // equal parts among each stretched item.
            widthOfStretchedItem = totalParentWidth / lengthOfItemsControlItems;

            // iterate through internal children to
            // set desired size and to call Arrange() method.
            foreach (UIElement child in InternalChildren)
            {
                // change the location (placement) of an item
                // depending of the orientation dependency property
                if (Orientation != Orientation.Vertical)
                {
                    // set the rectangle that will be a direct container
                    // for our child and add same width to the location
                    child.Arrange(new Rect(location, new Size(widthOfStretchedItem, child.DesiredSize.Height)));
                    if (Spacing.Right > 0 || Spacing.Left > 0)
                    {
                        location.X += widthOfStretchedItem + Math.Max(Spacing.Right, Spacing.Left);
                    }
                    else
                    {
                        location.X += widthOfStretchedItem;
                    }
                }
                else
                {
                    child.Arrange(new Rect(location, child.DesiredSize));
                    if (Spacing.Top > 0 || Spacing.Bottom > 0)
                    {
                        location.X += widthOfStretchedItem + Math.Max(Spacing.Top, Spacing.Bottom);
                    }
                    else
                    {
                        location.Y += child.DesiredSize.Height;
                    }
                }
            }
            return(finalSize);
        }