private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(Size popupSize, Size targetSize,
                                                                            Point offset)
        {
            var locationFromScreen = this.PlacementTarget.PointToScreen(new Point(0, 0));

            var mainVisual = PlacementTarget.GetVisualAncestry().OfType <System.Windows.Media.Visual>().LastOrDefault();

            if (mainVisual == null)
            {
                return(new CustomPopupPlacement[0]);
            }

            var screenWidth  = (int)DpiHelper.TransformToDeviceX(mainVisual, SystemParameters.PrimaryScreenWidth);
            var screenHeight = (int)DpiHelper.TransformToDeviceY(mainVisual, SystemParameters.PrimaryScreenHeight);

            var locationX = (int)locationFromScreen.X % screenWidth;
            var locationY = (int)locationFromScreen.Y % screenHeight;

            var realOffsetX = (popupSize.Width - targetSize.Width) / 2.0;
            var offsetX     = DpiHelper.TransformToDeviceX(mainVisual, offset.X);
            var defaultVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DefaultVerticalOffset);
            var upVerticalOffsetIndepent      = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
            var downVerticalOffsetIndepent    = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);

            if (locationX + popupSize.Width - realOffsetX > screenWidth ||
                locationX + realOffsetX < 0)
            {
                SetChildTemplateIfNeed(DefaultContentTemplate);

                var newY = locationY + popupSize.Height > screenHeight
                    ? -(defaultVerticalOffsetIndepent + popupSize.Height)
                    : defaultVerticalOffsetIndepent + targetSize.Height;

                return(new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.Horizontal) });
            }
            if (locationY + popupSize.Height > screenHeight)
            {
                SetChildTemplateIfNeed(UpContentTemplate);

                var newY = upVerticalOffsetIndepent - popupSize.Height + targetSize.Height;

                return(new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) });
            }
            else
            {
                SetChildTemplateIfNeed(DownContentTemplate);

                var newY = downVerticalOffsetIndepent;

                return(new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) });
            }
        }
Exemple #2
0
        private PositioningData GetPositioningData(IEnumerable <DependencyObject> visualAncestry, Size popupSize, Size targetSize, Point offset)
        {
            var locationFromScreen = PlacementTarget.PointToScreen(new Point(0, 0));

            var mainVisual = visualAncestry.OfType <Visual>().LastOrDefault();

            if (mainVisual == null)
            {
                throw new ArgumentException($"{nameof(visualAncestry)} must contains unless one {nameof(Visual)} control inside.");
            }

            var screen       = Screen.FromPoint(locationFromScreen);
            var screenWidth  = (int)DpiHelper.TransformToDeviceX(mainVisual, (int)screen.Bounds.Width);
            var screenHeight = (int)DpiHelper.TransformToDeviceY(mainVisual, (int)screen.Bounds.Height);

            //Adjust the location to be in terms of the current screen
            var locationX = (int)(locationFromScreen.X - screen.Bounds.X) % screenWidth;
            var locationY = (int)(locationFromScreen.Y - screen.Bounds.Y) % screenHeight;

            var upVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
            var newUpY   = upVerticalOffsetIndepent - popupSize.Height + targetSize.Height;
            var newDownY = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);

            double    offsetX;
            const int rtlHorizontalOffset = 20;

            if (FlowDirection == FlowDirection.LeftToRight)
            {
                offsetX = DpiHelper.TransformToDeviceX(mainVisual, offset.X);
            }
            else
            {
                offsetX = DpiHelper.TransformToDeviceX(mainVisual,
                                                       offset.X - targetSize.Width - rtlHorizontalOffset);
            }

            return(new PositioningData(
                       mainVisual, offsetX,
                       newUpY, newDownY,
                       popupSize, targetSize,
                       locationX, locationY,
                       screenHeight, screenWidth));
        }
        private PositioningData GetPositioningData(IEnumerable <DependencyObject> visualAncestry, Size popupSize, Size targetSize, Point offset)
        {
            var locationFromScreen = PlacementTarget.PointToScreen(new Point(0, 0));

            var mainVisual = visualAncestry.OfType <Visual>().LastOrDefault();

            if (mainVisual == null)
            {
                throw new ArgumentException($"{nameof(visualAncestry)} must contains unless one {nameof(Visual)} control inside.");
            }

            var screenWidth  = (int)DpiHelper.TransformToDeviceX(mainVisual, SystemParameters.PrimaryScreenWidth);
            var screenHeight = (int)DpiHelper.TransformToDeviceY(mainVisual, SystemParameters.PrimaryScreenHeight);

            var locationX = (int)locationFromScreen.X % screenWidth;
            var locationY = (int)locationFromScreen.Y % screenHeight;

            double    offsetX;
            const int rtlHorizontalOffset = 20;

            if (FlowDirection == FlowDirection.LeftToRight)
            {
                offsetX = DpiHelper.TransformToDeviceX(mainVisual, offset.X);
            }
            else
            {
                offsetX = DpiHelper.TransformToDeviceX(mainVisual,
                                                       offset.X - targetSize.Width - rtlHorizontalOffset);
            }

            return(new PositioningData(
                       mainVisual, offsetX,
                       popupSize, targetSize,
                       locationX, locationY,
                       screenHeight, screenWidth));
        }
        private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
            Size popupSize, Size targetSize, Point offset)
        {
            var visualAncestry = PlacementTarget.GetVisualAncestry().ToList();

            SetupBackground(visualAncestry);

            SetupVisiblePlacementWidth(visualAncestry);

            var locationFromScreen = PlacementTarget.PointToScreen(new Point(0, 0));

            var mainVisual = visualAncestry.OfType <Visual>().LastOrDefault();

            if (mainVisual == null)
            {
                return(new CustomPopupPlacement[0]);
            }

            var screenWidth  = (int)DpiHelper.TransformToDeviceX(mainVisual, SystemParameters.PrimaryScreenWidth);
            var screenHeight = (int)DpiHelper.TransformToDeviceY(mainVisual, SystemParameters.PrimaryScreenHeight);

            var locationX = (int)locationFromScreen.X % screenWidth;
            var locationY = (int)locationFromScreen.Y % screenHeight;

            var realOffsetX = (popupSize.Width - targetSize.Width) / 2.0;

            double    offsetX;
            const int rtlHorizontalOffset = 20;

            if (FlowDirection == FlowDirection.LeftToRight)
            {
                offsetX = DpiHelper.TransformToDeviceX(mainVisual, offset.X);
            }
            else
            {
                offsetX = DpiHelper.TransformToDeviceX(mainVisual,
                                                       offset.X - targetSize.Width - rtlHorizontalOffset);
            }


            if (locationX + popupSize.Width - realOffsetX > screenWidth ||
                locationX - realOffsetX < 0)
            {
                SetChildTemplateIfNeed(DefaultContentTemplate);

                var defaultVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DefaultVerticalOffset);
                var newY = locationY + popupSize.Height > screenHeight
                    ? -(defaultVerticalOffsetIndepent + popupSize.Height)
                    : defaultVerticalOffsetIndepent + targetSize.Height;

                return(new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.Horizontal) });
            }

            if (locationY + popupSize.Height > screenHeight)
            {
                SetChildTemplateIfNeed(UpContentTemplate);

                var upVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
                var newY = upVerticalOffsetIndepent - popupSize.Height + targetSize.Height;

                return(new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) });
            }
            else
            {
                SetChildTemplateIfNeed(DownContentTemplate);

                var downVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);
                var newY = downVerticalOffsetIndepent;

                return(new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) });
            }
        }