/// <summary> /// Sets an anchor AND a margin preset. This is most likely the method you want. /// /// </summary> /// <remarks> /// Note that the current size and minimum size of the control affects how /// each of the margins will be set, so if your control needs to shrink beyond its /// current size / min size, you should either not call this method or only call it when your /// control has a size of (0, 0). Otherwise your control's size will never be able /// to go below the size implied by the margins set in this method. /// </remarks> public static void SetAnchorAndMarginPreset(Control control, LayoutPreset preset, LayoutPresetMode mode = LayoutPresetMode.MinSize, int margin = 0) { SetAnchorPreset(control, preset); SetMarginsPreset(control, preset, mode, margin); }
/// <summary> /// Changes all the margins of a control at once to common presets. /// The result is that the control is laid out as specified by the preset. /// /// Note that the current size and minimum size of the control affects how /// each of the margins will be set, so if your control needs to shrink beyond its /// current size / min size, you should either not call this method or only call it when your /// control has a size of (0, 0). Otherwise your control's size will never be able /// to go below the size implied by the margins set in this method. /// </summary> /// <param name="preset"></param> /// <param name="resizeMode"></param> /// <param name="margin">Some extra margin to add depending on the preset chosen.</param> public static void SetMarginsPreset(Control control, LayoutPreset preset, LayoutPresetMode resizeMode = LayoutPresetMode.MinSize, int margin = 0) { control.Measure(Vector2.Infinity); var newSize = control.Size; var minSize = control.DesiredSize; if ((resizeMode & LayoutPresetMode.KeepWidth) == 0) { newSize = new Vector2(minSize.X, newSize.Y); } if ((resizeMode & LayoutPresetMode.KeepHeight) == 0) { newSize = new Vector2(newSize.X, minSize.Y); } var parentSize = control.Parent?.Size ?? Vector2.Zero; var anchorLeft = control.GetValue <float>(AnchorLeftProperty); var anchorTop = control.GetValue <float>(AnchorBottomProperty); var anchorRight = control.GetValue <float>(AnchorRightProperty); var anchorBottom = control.GetValue <float>(AnchorBottomProperty); float marginLeft; float marginTop; float marginRight; float marginBottom; // Left Margin. switch (preset) { case LayoutPreset.TopLeft: case LayoutPreset.BottomLeft: case LayoutPreset.CenterLeft: case LayoutPreset.LeftWide: case LayoutPreset.HorizontalCenterWide: case LayoutPreset.Wide: case LayoutPreset.TopWide: case LayoutPreset.BottomWide: // The AnchorLeft bit is to reverse the effect of anchors, // So that the preset result is the same no matter what margins are set. marginLeft = parentSize.X * (0 - anchorLeft) + margin; break; case LayoutPreset.CenterTop: case LayoutPreset.CenterBottom: case LayoutPreset.Center: case LayoutPreset.VerticalCenterWide: marginLeft = parentSize.X * (0.5f - anchorLeft) - newSize.X / 2; break; case LayoutPreset.TopRight: case LayoutPreset.BottomRight: case LayoutPreset.CenterRight: case LayoutPreset.RightWide: marginLeft = parentSize.X * (1 - anchorLeft) - newSize.X - margin; break; default: throw new ArgumentOutOfRangeException(nameof(preset), preset, null); } // Top Anchor. switch (preset) { case LayoutPreset.TopLeft: case LayoutPreset.TopRight: case LayoutPreset.LeftWide: case LayoutPreset.TopWide: case LayoutPreset.Wide: case LayoutPreset.RightWide: case LayoutPreset.CenterTop: case LayoutPreset.VerticalCenterWide: marginTop = parentSize.Y * (0 - anchorTop) + margin; break; case LayoutPreset.CenterLeft: case LayoutPreset.CenterRight: case LayoutPreset.HorizontalCenterWide: case LayoutPreset.Center: marginTop = parentSize.Y * (0.5f - anchorTop) - newSize.Y / 2; break; case LayoutPreset.CenterBottom: case LayoutPreset.BottomLeft: case LayoutPreset.BottomRight: case LayoutPreset.BottomWide: marginTop = parentSize.Y * (1 - anchorTop) - newSize.Y - margin; break; default: throw new ArgumentOutOfRangeException(nameof(preset), preset, null); } // Right Anchor. switch (preset) { case LayoutPreset.TopLeft: case LayoutPreset.CenterLeft: case LayoutPreset.BottomLeft: case LayoutPreset.LeftWide: marginRight = parentSize.X * (0 - anchorRight) + newSize.X + margin; break; case LayoutPreset.CenterTop: case LayoutPreset.CenterBottom: case LayoutPreset.Center: case LayoutPreset.VerticalCenterWide: marginRight = parentSize.X * (0.5f - anchorRight) + newSize.X; break; case LayoutPreset.CenterRight: case LayoutPreset.TopRight: case LayoutPreset.Wide: case LayoutPreset.HorizontalCenterWide: case LayoutPreset.TopWide: case LayoutPreset.BottomWide: case LayoutPreset.RightWide: case LayoutPreset.BottomRight: marginRight = parentSize.X * (1 - anchorRight) - margin; break; default: throw new ArgumentOutOfRangeException(nameof(preset), preset, null); } // Bottom Anchor. switch (preset) { case LayoutPreset.TopWide: case LayoutPreset.TopLeft: case LayoutPreset.TopRight: case LayoutPreset.CenterTop: marginBottom = parentSize.Y * (0 - anchorBottom) + newSize.Y + margin; break; case LayoutPreset.CenterLeft: case LayoutPreset.CenterRight: case LayoutPreset.Center: case LayoutPreset.HorizontalCenterWide: marginBottom = parentSize.Y * (0.5f - anchorBottom) + newSize.Y; break; case LayoutPreset.CenterBottom: case LayoutPreset.BottomLeft: case LayoutPreset.BottomRight: case LayoutPreset.LeftWide: case LayoutPreset.Wide: case LayoutPreset.RightWide: case LayoutPreset.VerticalCenterWide: case LayoutPreset.BottomWide: marginBottom = parentSize.Y * (1 - anchorBottom) - margin; break; default: throw new ArgumentOutOfRangeException(nameof(preset), preset, null); } control.SetValue(MarginLeftProperty, marginLeft); control.SetValue(MarginTopProperty, marginTop); control.SetValue(MarginRightProperty, marginRight); control.SetValue(MarginBottomProperty, marginBottom); }