Share via


Clearest code challenge

This is a real problem I had recently.

Suppose you have a form with OK and Cancel buttons. You want the buttons to be placed in the bottom-right corner of the form. Normally you'd place them where they go, then set their Anchor properties to Bottom, Right.

However, today I'm going to place an arbitrary limitation. You can't set the positions of the button controls in the designer, you have to write it in code.

            Button _buttonCancel;

            Button _buttonOK;

            void PlaceButtons()

            {

                  this._buttonCancel.Location = ???;

                  this._buttonOK.Location = ???;

            }

I think the Cancel button should be 12 pixels from the bottom right corner. The OK button should be 12 pixels to the left of the Cancel button.

But here’s the real challenge: write the clearest code possible.

I know my solution. It’s clearer than what I would have written a few years ago, but I wonder if I could have done better. I’ll post mine in a few days, I guess.

Comments

  • Anonymous
    March 20, 2004
    The following info will be needed in the equation:

    1) FormDimensions
    2) ButtonDimensions
  • Anonymous
    March 20, 2004
    Assuming that this is the Form and button sizes have already been set...

    private const int Size buttonMargin = new Size(12, 12);

    this._buttonCancel.Location.X = this.ClientRectangle.Right - buttonMargin.Width - this._buttonCancel.Width;
    this._buttonCancel.Location.Y =
    this.ClientRectangle.Bottom - buttonMargin.Height - this._buttonCancel.Height;

    this._buttonOK.Location.X = this._buttonCancel.Location.X - buttonMargin.Width - this._buttonOK.Width;
    this._buttonOK.Location.Y = this.ClientRectangle.Bottom - buttonMargin.Height - this._buttonOK.Height;
  • Anonymous
    March 20, 2004
    protected override void OnSizeChanged(EventArgs e) {
    base.OnSizeChanged (e);
    //instead of ctor put your code with layout logic here
    }

    btw why the heck VS auto completes using base.OnSizeChanged (e);
    with a space after the method ?
    nobody writes this way, not even MS :)
  • Anonymous
    March 20, 2004
    Isn't the Location X and Y immutable? I thought you had to create a new Point() class every time. Apart from that, my code would take the same form as DarthPedro's code.
  • Anonymous
    March 20, 2004
    Rich is right that the Location property is immutable, so you can't modify X & Y directly & must create a new object to replace it.

    I'm assuming that correctness isn't the hard part here. I assume that most developers can solve the problem of placing the controls correctly. The challenge is clarity.
  • Anonymous
    March 20, 2004
    The comment has been removed
  • Anonymous
    March 20, 2004
    int margin = 12;

    ControlMover okMover = new ControlMover(_buttonOK, this.ClientSize, margin);
    okMover.MoveLeft();
    okMover.MoveUp();

    ControlMover cancelMover = new ControlMover(_buttonCancel, _buttonOK.Location, margin);
    cancelMover.MoveLeft();

    class ControlMover
    {
    Control _control;
    int _margin;

    public ControlMover(Control c, Point location, int margin)
    {
    _margin = margin;
    _control = c;
    _control.Location = location;
    }

    public ControlMover(Control c, Size location, int margin)
    : this (c, new Point(location), margin)
    {
    }

    public void MoveLeft(int delta)
    {
    _control.Location = Offset(- delta - _margin, 0);
    }

    Point Offset(int deltaX, int deltaY)
    {
    Point location = _control.Location;
    location.Offset(deltaX, deltaY);
    return location;
    }

    public void MoveLeft()
    {
    MoveLeft(_control.Width);
    }

    public void MoveUp(int delta)
    {
    _control.Location = Offset(0, - delta - _margin);
    }

    public void MoveUp()
    {
    MoveUp(_control.Height);
    }
    }

  • Anonymous
    March 21, 2004
    private const int Margin = 12;

    int x = ClientRectangle.Right - Margin;
    int y = ClientRectangle.Bottom + Margin + _buttonCancel.Height;

    this._buttonCancel = New Point(x,y)

    x -= buttonCancel.Width - Margin;
    this._buttonOK = new Point(x,y)
  • Anonymous
    March 21, 2004
    The comment has been removed
  • Anonymous
    March 24, 2004
    Private Sub JayBazExample_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    _buttonCancel.PositionBottomRight(12, 12)
    _buttonOK.PositionLeftOf(_buttonCancel, 12)
    End Sub
    End Class

    Public Class PositionalButton
    Inherits Button

    Public Sub PositionBottomRight(ByVal VerticalPadding As Int32, ByVal HorizontalPadding As Int32)
    Top = Me.Parent.ClientSize.Height - Me.Height - VerticalPadding
    Left = Me.Parent.ClientSize.Width - Me.Width - HorizontalPadding
    End Sub

    Public Sub PositionLeftOf(ByVal Target As Button, ByVal VerticalPadding As Int32)
    Top = Target.Top
    Left = Target.Left - Me.Width - VerticalPadding
    End Sub

    End Class
  • Anonymous
    March 24, 2004
    _buttonCancel.Top = ClientSize.Height - _buttonCancel.Height - 12;
    _buttonCancel.Left = ClientSize.Width - _buttonCancel.Width - 12;

    _buttonOK.Top = _buttonCancel.Top;
    _buttonOK.Left = _buttonCancel.Left - _buttonOK.Width - 12;
  • Anonymous
    March 24, 2004
    _buttonCancel.Location = new Point(ClientSize.Width - _buttonCancel.Width - 12, ClientSize.Height - _buttonCancel.Height - 12);
    _buttonOK.Location = new Point(_buttonCancel.Left - _buttonOK.Width - 12, _buttonCancel.Top);
  • Anonymous
    March 25, 2004
    For me the clearest solution is simple

    private void PlaceButtons()
    {
    const int BUTTON_MARGIN = 12;

    _buttonCancel.Location = new System.Drawing.Point(
    this.ClientRectangle.Width - _buttonCancel.Width - BUTTON_MARGIN,
    this.ClientRectangle.Height - _buttonCancel.Height - BUTTON_MARGIN);
    _buttonOK.Location = new System.Drawing.Point(
    this.ClientRectangle.Width - _buttonCancel.Width - _buttonOK.Width - 2*BUTTON_MARGIN,
    this.ClientRectangle.Height - _buttonOK.Height - BUTTON_MARGIN);

    _buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
    _buttonOK.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
    }
  • Anonymous
    June 09, 2009
    PingBack from http://greenteafatburner.info/story.php?id=3736