Esempio n. 1
0
        public void GetDescendantsDepthFirst()
        {
            var controlA = new UIControl();
              var controlB = new UIControl();
              var controlC = new UIControl();
              var controlD = new UIControl();
              var controlE = new UIControl();
              var controlF = new UIControl();
              var controlG = new UIControl();
              controlA.VisualChildren.Add(controlB);
              controlA.VisualChildren.Add(controlC);
              controlA.VisualChildren.Add(controlD);
              controlD.VisualChildren.Add(controlE);
              controlD.VisualChildren.Add(controlF);
              controlE.VisualChildren.Add(controlG);

              Assert.That(() => UIHelper.GetDescendants(null), Throws.TypeOf<ArgumentNullException>());

              var descendants = controlA.GetDescendants().ToArray();
              Assert.AreEqual(6, descendants.Length);
              Assert.AreEqual(controlB, descendants[0]);
              Assert.AreEqual(controlC, descendants[1]);
              Assert.AreEqual(controlD, descendants[2]);
              Assert.AreEqual(controlE, descendants[3]);
              Assert.AreEqual(controlG, descendants[4]);
              Assert.AreEqual(controlF, descendants[5]);
        }
Esempio n. 2
0
    public void RenderTreeViewItem(UIControl control, UIRenderContext context)
    {
      var treeViewItem = control as TreeViewItem;
      if (treeViewItem != null && treeViewItem.IsSelected && treeViewItem.Header != null)
      {
        // Draw a blue rectangle behind selected tree view items.
        context.RenderTransform.Draw(
          SpriteBatch,
          WhiteTexture,
          treeViewItem.Header.ActualBounds,
          null,
          Color.CornflowerBlue);
      }

      // Call the default render callback to draw all the rest.
      RenderCallbacks["UIControl"](control, context);
    }
Esempio n. 3
0
        /// <summary>
        /// Called when the <see cref="Content"/> was exchanged.
        /// </summary>
        /// <param name="newContent">The new content.</param>
        /// <param name="oldContent">The old content.</param>
        protected virtual void OnContentChanged(UIControl newContent, UIControl oldContent)
        {
            if (oldContent != null)
            {
                VisualChildren.Remove(oldContent);
            }

            if (newContent != null)
            {
                // Apply ContentStyle to Content.
                if (IsLoaded && !string.IsNullOrEmpty(ContentStyle))
                {
                    newContent.Style = ContentStyle;
                }

                VisualChildren.Add(newContent);
            }

            InvalidateMeasure();
        }
Esempio n. 4
0
        public void GetAncestors()
        {
            var controlA = new UIControl();
              var controlB = new UIControl();
              var controlC = new UIControl();
              var controlD = new UIControl();
              var controlE = new UIControl();
              var controlF = new UIControl();
              var controlG = new UIControl();
              controlA.VisualChildren.Add(controlB);
              controlA.VisualChildren.Add(controlC);
              controlA.VisualChildren.Add(controlD);
              controlD.VisualChildren.Add(controlE);
              controlD.VisualChildren.Add(controlF);
              controlE.VisualChildren.Add(controlG);

              Assert.That(() => UIHelper.GetAncestors(null), Throws.TypeOf<ArgumentNullException>());

              var ancestors = controlE.GetAncestors().ToArray();
              Assert.AreEqual(2, ancestors.Length);
              Assert.AreEqual(controlD, ancestors[0]);
              Assert.AreEqual(controlA, ancestors[1]);
        }
Esempio n. 5
0
        /// <summary>
        /// Opens this <see cref="ContextMenu"/> (adds it to the <see cref="UIScreen"/>).
        /// </summary>
        /// <param name="owner">The control that opened this context menu.</param>
        /// <param name="position">
        /// The position of the mouse cursor - or where the context menu should be opened.
        /// (<see cref="Offset"/> will be applied to this position.)
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="owner"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="owner"/> is not loaded. The owner needs to be a visible control.
        /// </exception>
        public void Open(UIControl owner, Vector2F position)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }

            var screen = owner.Screen;

            if (screen == null)
            {
                throw new ArgumentException("Invalid owner. The owner must be loaded.", "owner");
            }

            if (!IsEnabled)
            {
                return;
            }

            // Close if already opened.
            Close();

            Owner = owner;

            // Make visible and add to screen.
            IsVisible = true;
            screen.Children.Add(this);

            // Choose position near the given position.
            // The context menu is positioned so that it fits onto the screen.
            Measure(new Vector2F(float.PositiveInfinity));
            float x = position.X;

            if (x + DesiredWidth > screen.ActualWidth)
            {
                // Show context menu on the left.
                x = x - DesiredWidth;
            }

            float offset = Offset;
            float y      = position.Y + offset;

            if (y + DesiredHeight > screen.ActualHeight)
            {
                // Show context menu on top.
                // (We use 0.5 * offset if context menu is above cursor. This assumes that the cursor
                // is similar to the typical arrow where the hot spot is at the top. If the cursor is a
                // different shape we might need to adjust the offset.)
                y = y - DesiredHeight - 1.5f * offset;
            }

            X = x;
            Y = y;

#if WP7 || PORTABLE
#if PORTABLE
            if (GlobalSettings.PlatformID == PlatformID.WindowsPhone8)
#endif
            {
                // Imitate position of Silverlight WP7 context menus.
                if (screen.ActualHeight >= screen.ActualWidth)
                {
                    // Portrait mode.
                    X = 0;
                    HorizontalAlignment = HorizontalAlignment.Stretch;
                    VerticalAlignment   = VerticalAlignment.Top;
                }
                else
                {
                    // Landscape mode.
                    Y     = 0;
                    Width = screen.ActualWidth / 2;
                    HorizontalAlignment = HorizontalAlignment.Left;
                    VerticalAlignment   = VerticalAlignment.Stretch;
                    if (position.X <= screen.ActualWidth / 2)
                    {
                        // Show context menu on right half of the screen.
                        X = screen.ActualWidth / 2;
                    }
                    else
                    {
                        // Show context menu on the left half of the screen.
                        X = 0;
                    }
                }
            }
#endif

            screen.FocusManager.Focus(this);
            IsOpen = true;
        }
Esempio n. 6
0
    /// <summary>
    /// Opens this <see cref="ContextMenu"/> (adds it to the <see cref="UIScreen"/>).
    /// </summary>
    /// <param name="owner">The control that opened this context menu.</param>
    /// <param name="position">
    /// The position of the mouse cursor - or where the context menu should be opened.
    /// (<see cref="Offset"/> will be applied to this position.)
    /// </param>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="owner"/> is <see langword="null"/>.
    /// </exception>
    /// <exception cref="ArgumentException">
    /// <paramref name="owner"/> is not loaded. The owner needs to be a visible control.
    /// </exception>
    public void Open(UIControl owner, Vector2F position)
    {
      if (owner == null)
        throw new ArgumentNullException("owner");

      var screen = owner.Screen;
      if (screen == null)
        throw new ArgumentException("Invalid owner. The owner must be loaded.", "owner");

      if (!IsEnabled)
        return;

      // Close if already opened.
      Close();

      Owner = owner;

      // Make visible and add to screen.
      IsVisible = true;
      screen.Children.Add(this);

      // Choose position near the given position. 
      // The context menu is positioned so that it fits onto the screen.
      Measure(new Vector2F(float.PositiveInfinity));
      float x = position.X;
      if (x + DesiredWidth > screen.ActualWidth)
      {
        // Show context menu on the left.
        x = x - DesiredWidth;
      }

      float offset = Offset;
      float y = position.Y + offset;
      if (y + DesiredHeight > screen.ActualHeight)
      {
        // Show context menu on top.
        // (We use 0.5 * offset if context menu is above cursor. This assumes that the cursor 
        // is similar to the typical arrow where the hot spot is at the top. If the cursor is a 
        // different shape we might need to adjust the offset.)
        y = y - DesiredHeight - 1.5f * offset;
      }

      X = x;
      Y = y;

#if WP7 || PORTABLE
#if PORTABLE
      if (GlobalSettings.PlatformID == PlatformID.WindowsPhone8)
#endif
      {
        // Imitate position of Silverlight WP7 context menus.
        if (screen.ActualHeight >= screen.ActualWidth)
        {
          // Portrait mode.
          X = 0;
          HorizontalAlignment = HorizontalAlignment.Stretch;
          VerticalAlignment = VerticalAlignment.Top;
        }
        else
        {
          // Landscape mode.
          Y = 0;
          Width = screen.ActualWidth / 2;
          HorizontalAlignment = HorizontalAlignment.Left;
          VerticalAlignment = VerticalAlignment.Stretch;
          if (position.X <= screen.ActualWidth / 2)
          {
            // Show context menu on right half of the screen.
            X = screen.ActualWidth / 2;
          }
          else
          {
            // Show context menu on the left half of the screen.
            X = 0;
          }
        }
      }
#endif

      screen.FocusManager.Focus(this);
      IsOpen = true;
    }
Esempio n. 7
0
        /// <summary>
        /// Moves focus to a control.
        /// </summary>
        /// <param name="control">
        /// The control that should get the focus. (If <paramref name="control"/> is 
        /// <see langword="null"/>, this method does nothing. Use <see cref="ClearFocus"/> to remove the
        /// focus from a control.)
        /// </param>
        /// <returns>
        /// <see langword="true"/> if the focus was moved; otherwise <see langword="false"/>.
        /// </returns>
        /// <remarks>
        /// Disabled or invisible controls cannot be focused. If the <paramref name="control"/> is not
        /// itself <see cref="UIControl.Focusable"/>, the method tries to focus a child control.
        /// </remarks>
        public bool Focus(UIControl control)
        {
            if (control == null)
            return false;

              // Cannot focus a disabled or invisible control.
              if (!control.ActualIsEnabled || !control.ActualIsVisible)
            return false;

              if (!control.Focusable)
              {
            if (control.IsFocusScope)
            {
              // Try to move focus to the last focused control.
              var lastFocusedControl = control.GetValue<UIControl>(LastFocusedControlPropertyId);
              if (Focus(lastFocusedControl) && control.IsFocusWithin)
            return true;
            }

            // Control is not focusable. --> Try to focus a child.
            foreach (var child in control.VisualChildren)
            {
              if (Focus(child))
            return true;
            }

            return false;
              }

            #if !WP7
            #if PORTABLE
              if (GlobalSettings.PlatformID != PlatformID.WindowsPhone8)
            #endif
              {
            // Move control to visible area. On phone this is typically not done to avoid non-smooth
            // scrolling.
            control.BringIntoView();
              }
            #endif

              // Abort if control is already focused.
              // (Note: We do the check here and not at the beginning of the method because we still want
              // to do the things above to bring the control into the view, even if the control already has
              // focus.)
              if (control.IsFocused)
            return true;

              // First, clear the current IsFocused and IsFocusWithin flags.
              ClearFocus();

              // Set IsFocused and IsFocusWithin flags in FocusedControl and all ancestors.
              FocusedControl = control;
              FocusedControl.IsFocused = true;
              FocusScope = null;
              while (control != null)
              {
            if (control.IsFocusScope)
            {
              // Remember the first focus scope that we find.
              if (FocusScope == null)
            FocusScope = control;

              // Focus scope remembers last focused control.
              control.SetValue(LastFocusedControlPropertyId, FocusedControl);
            }

            control.IsFocusWithin = true;
            control = control.VisualParent;
              }

              return true;
        }
Esempio n. 8
0
    /// <inheritdoc/>
    protected override bool HitTest(UIControl control, Vector2F position)
    {
      // If control is the child and ClipContent is enabled, then the mouse must be within the
      // ContentBounds. (The child part that is outside the ContentBounds is invisible and cannot
      // be clicked.)
      if (control != null && control == Content && ClipContent)
      {
        return ContentBounds.Contains(position);
      }

      return base.HitTest(control, position);
    }
Esempio n. 9
0
        //--------------------------------------------------------------
        private void OnScreenInputProcessed(object sender, InputEventArgs eventArgs)
        {
            // Automatically hide the ToolTip if the Screen does not process input (because then
              // we would not see mouse movement, so we close it immediately).
              // Or close it if another UIControl was added on top that could hide the ToolTip.
              if (IsToolTipOpen)
              {
            if (!Screen.InputEnabled                                              // Screen does not handle input.
            || Screen.Children[Screen.Children.Count - 1] != ToolTipControl)  // Another window was opened.
            {
              // ----- Screen was disabled, or another control was shown on top.
              CloseToolTip();
              return;
            }
              }

              var context = eventArgs.Context;
              if (context.MousePositionDelta == Vector2F.Zero)
              {
            // ----- No mouse movement --> Increase counter.
            _noMouseMoveDuration += context.DeltaTime;
              }
              else
              {
            // ----- Mouse moved --> Close tool tip if mouse is no longer over control. Reset counter.
            if (_control == null || !_control.IsMouseOver)
              CloseToolTip();

            _noMouseMoveDuration = TimeSpan.Zero;
            return;
              }

              if (_noMouseMoveDuration >= ToolTipDelay)
              {
            // ----- Mouse was not moving for ToolTipDelay seconds --> Show tool tip.

            // Get control under the mouse cursor. Search up the control hierarchy until we
            // find a control with a tool tip string.
            var control = Screen.ControlUnderMouse;
            while (control != null && control.ToolTip == null)
              control = control.VisualParent;

            if (control != null)
            {
              // Show or update tool tip.
              ShowToolTip(control.ToolTip, context.MousePosition);
              _control = control;
            }

            // We do not want to check on the same position again in the next frame, so we set
            // an extreme value that will be automatically reset when the mouse moves in the future.
            _noMouseMoveDuration = TimeSpan.MinValue;
              }
        }
Esempio n. 10
0
 /// <summary>
 /// Hides the tool tip or does nothing if no tool tip is visible.
 /// </summary>
 public void CloseToolTip()
 {
     ToolTipControl.Content = null;
       ToolTipControl.IsVisible = false;
       _control = null;
 }
Esempio n. 11
0
    /// <summary>
    /// Opens a window and returns without waiting for the newly opened window to close.
    /// </summary>
    /// <param name="owner">
    /// The owner of this window. If this window is closed, the focus moves back to the owner. Must
    /// not be <see langword="null"/>.
    /// </param>
    /// <remarks>
    /// The window is added to the <see cref="UIScreen"/> of the <paramref name="owner"/> 
    /// (unless it was already added to a screen) and activated (see <see cref="Activate"/>).
    /// <see cref="DialogResult"/> is reset to <see langword="null"/>.
    /// </remarks>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="owner"/> is <see langword="null"/>.
    /// </exception>
    /// <exception cref="ArgumentException">
    /// <paramref name="owner"/> is not loaded. The owner needs to be a visible control.
    /// </exception>
    public void Show(UIControl owner)
    {
      if (owner == null)
        throw new ArgumentNullException("owner");

      var screen = owner.Screen;
      if (screen == null)
        throw new ArgumentException("Invalid owner. Owner must be loaded.", "owner");

      Owner = owner;

      // Make visible and add to screen.
      IsVisible = true;
      if (VisualParent == null)
        screen.Children.Add(this);

      Activate();
#if !WINDOWS_UWP
      DialogResult = null;
#else
      DialogResult = false;
#endif
    }
Esempio n. 12
0
    /// <summary>
    /// Gets the window that contains the given <paramref name="control"/>.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <returns>
    /// The window that contains the <paramref name="control"/>, or <see langword="null"/> if
    /// the control is not part of a window (controls can be direct children of the screen, no 
    /// intermediate window is required).
    /// </returns>
    public static Window GetWindow(UIControl control)
    {
      while (control != null)
      {
        var window = control as Window;
        if (window != null)
          return window;

        control = control.VisualParent;
      }

      return null;
    }
Esempio n. 13
0
        /// <summary>
        /// Recursively collects all focusable controls of the same focus scope.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <remarks>
        /// The focusable controls are stored in _focusableControls. <see cref="FocusedControl"/> will 
        /// be excluded from the list.
        /// </remarks>
        private void GetFocusableControls(UIControl control)
        {
            if (control == FocusedControl)
            return;

              if (control.Focusable && control.IsEnabled && control.IsVisible)
              {
            _focusableControls.Add(control);
              }
              else
              {
            foreach (var child in control.VisualChildren)
              if (child.IsEnabled && child.IsVisible)
            GetFocusableControls(child);
              }
        }
Esempio n. 14
0
        internal void MoveFocus(UIControl control, LogicalPlayerIndex allowedPlayer)
        {
            // Called by the UIControl after UIControl.OnHandleInput.

              if (control == null)
            return;

              var inputService = InputService;

              // Handle AutoUnfocus.
              if (control.AutoUnfocus && FocusedControl != null)
              {
            if (inputService.IsPressed(MouseButtons.Left, false) || inputService.IsPressed(MouseButtons.Right, false))
            {
              if (control == FocusScope && !FocusedControl.IsMouseOver                     // E.g. a window and not the focused control is clicked.
              || control.IsMouseDirectlyOver && !inputService.IsMouseOrTouchHandled)   // E.g. a screen and no child UIControl is clicked.
              {
            ClearFocus();
              }
            }
              }

              // Only focus scopes handle focus movement.
              // And only the current focus scope (which means the first focus scope in the hierarchy).
              if (!control.IsFocusScope || FocusScope != null && control != FocusScope)
            return;

              bool moveLeft = false;
              bool moveRight = false;
              bool moveUp = false;
              bool moveDown = false;

              // Check arrow keys.
              if (!inputService.IsKeyboardHandled)
              {
            // This focus scope "absorbs" arrow keys.
            if (inputService.IsDown(Keys.Left)
            || inputService.IsDown(Keys.Right)
            || inputService.IsDown(Keys.Up)
            || inputService.IsDown(Keys.Down))
            {
              inputService.IsKeyboardHandled = true;

            if (inputService.IsPressed(Keys.Left, true))
              moveLeft = true;
            else if (inputService.IsPressed(Keys.Right, true))
              moveRight = true;
            else if (inputService.IsPressed(Keys.Up, true))
              moveUp = true;
            else if (inputService.IsPressed(Keys.Down, true))
              moveDown = true;
            }
              }

            #if !SILVERLIGHT
              // Check left thumb stick and d-pad.
              if (!moveLeft && !moveRight && !moveUp && !moveDown && !inputService.IsGamePadHandled(allowedPlayer))
              {
            if (inputService.IsDown(Buttons.LeftThumbstickLeft, allowedPlayer)
            || inputService.IsDown(Buttons.LeftThumbstickRight, allowedPlayer)
            || inputService.IsDown(Buttons.LeftThumbstickUp, allowedPlayer)
            || inputService.IsDown(Buttons.LeftThumbstickDown, allowedPlayer)
            || inputService.IsDown(Buttons.DPadLeft, allowedPlayer)
            || inputService.IsDown(Buttons.DPadRight, allowedPlayer)
            || inputService.IsDown(Buttons.DPadUp, allowedPlayer)
            || inputService.IsDown(Buttons.DPadDown, allowedPlayer))
            {
              inputService.SetGamePadHandled(allowedPlayer, true);

            if (inputService.IsPressed(Buttons.LeftThumbstickLeft, true, allowedPlayer) || inputService.IsPressed(Buttons.DPadLeft, true, allowedPlayer))
              moveLeft = true;
            else if (inputService.IsPressed(Buttons.LeftThumbstickRight, true, allowedPlayer) || inputService.IsPressed(Buttons.DPadRight, true, allowedPlayer))
              moveRight = true;
            else if (inputService.IsPressed(Buttons.LeftThumbstickUp, true, allowedPlayer) || inputService.IsPressed(Buttons.DPadUp, true, allowedPlayer))
              moveUp = true;
            else if (inputService.IsPressed(Buttons.LeftThumbstickDown, true, allowedPlayer) || inputService.IsPressed(Buttons.DPadDown, true, allowedPlayer))
              moveDown = true;
            }
              }
            #endif

              // Now, we know in which direction the focus should move.

              if (!moveLeft && !moveRight && !moveUp && !moveDown)
            return;

              // Collect all focusable controls.
              _focusableControls.Clear();
              GetFocusableControls(control);
              if (_focusableControls.Count == 0)
            return;

              // Call virtual method that does the job.
              var target = OnMoveFocus(moveLeft, moveRight, moveUp, moveDown, _focusableControls);

              Focus(target);

              _focusableControls.Clear();
        }
Esempio n. 15
0
    /// <summary>
    /// Brings a control to the front of the z-order.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="control"/> is <see langword="null"/>.
    /// </exception>
    /// <exception cref="ArgumentException">
    /// <paramref name="control"/> is not a child of this UI screen.
    /// </exception>
    public void BringToFront(UIControl control)
    {
      if (control == null)
        throw new ArgumentNullException("control");

      int index = Children.IndexOf(control);
      if (index == -1)
        throw new ArgumentException("control is not a child of this UI screen.");

      Children.Move(index, Children.Count - 1);
    }
Esempio n. 16
0
    /// <summary>
    /// Called when the <see cref="Content"/> was exchanged.
    /// </summary>
    /// <param name="newContent">The new content.</param>
    /// <param name="oldContent">The old content.</param>
    protected virtual void OnContentChanged(UIControl newContent, UIControl oldContent)
    {
      if (oldContent != null)
        VisualChildren.Remove(oldContent);

      if (newContent != null)
      {
        // Apply ContentStyle to Content.
        if (IsLoaded && !string.IsNullOrEmpty(ContentStyle))
          newContent.Style = ContentStyle;

        VisualChildren.Add(newContent);
      }

      InvalidateMeasure();
    }
Esempio n. 17
0
    /// <summary>
    /// Changes <see cref="HorizontalOffset"/> and <see cref="VerticalOffset"/> such that the
    /// <paramref name="control"/> is visible in the viewport.
    /// </summary>
    /// <param name="control">The control.</param>
    internal void BringIntoView(UIControl control)
    {
      if (!control.IsArrangeValid)
        control.UpdateLayout();

      BringIntoView(control.ActualBounds);
    }
Esempio n. 18
0
        public void GetRoot()
        {
            var controlA = new UIControl();
              var controlB = new UIControl();
              var controlC = new UIControl();
              var controlD = new UIControl();
              var controlE = new UIControl();
              var controlF = new UIControl();
              var controlG = new UIControl();
              controlA.VisualChildren.Add(controlB);
              controlA.VisualChildren.Add(controlC);
              controlA.VisualChildren.Add(controlD);
              controlD.VisualChildren.Add(controlE);
              controlD.VisualChildren.Add(controlF);
              controlE.VisualChildren.Add(controlG);

              Assert.That(() => UIHelper.GetRoot(null), Throws.TypeOf<ArgumentNullException>());

              Assert.AreEqual(controlA, controlA.GetRoot());
              Assert.AreEqual(controlA, controlG.GetRoot());
        }
Esempio n. 19
0
        /// <summary>
        /// Arranges the specified control considering the horizontal and vertical alignment of the
        /// given control.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="position">The position.</param>
        /// <param name="constraintSize">The constraint size.</param>
        internal static void Arrange(UIControl control, Vector2F position, Vector2F constraintSize)
        {
            if (control == null)
            return;

              Vector2F childPosition = position;
              Vector2F childSize = constraintSize;
              switch (control.HorizontalAlignment)
              {
            case HorizontalAlignment.Left:
              childPosition.X = position.X + control.X;
              childSize.X = control.DesiredWidth;
              break;
            case HorizontalAlignment.Center:
              childPosition.X = position.X + constraintSize.X / 2 - control.DesiredWidth / 2;
              childSize.X = control.DesiredWidth;
              break;
            case HorizontalAlignment.Right:
              childPosition.X = position.X + constraintSize.X - control.DesiredWidth;
              childSize.X = control.DesiredWidth;
              break;
            default: // HorizontalAlignment.Stretch
              break;
              }

              switch (control.VerticalAlignment)
              {
            case VerticalAlignment.Top:
              childPosition.Y = position.Y + control.Y;
              childSize.Y = control.DesiredHeight;
              break;
            case VerticalAlignment.Center:
              childPosition.Y = position.Y + constraintSize.Y / 2 - control.DesiredHeight / 2;
              childSize.Y = control.DesiredHeight;
              break;
            case VerticalAlignment.Bottom:
              childPosition.Y = position.Y + constraintSize.Y - control.DesiredHeight;
              childSize.Y = control.DesiredHeight;
              break;
            default: // VerticalAlignment.Stretch
              break;
              }

              control.Arrange(childPosition, childSize);
        }