Clearest code challenge

Published 20 March 04 10:22 AM

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

# Derek LaZard said on March 20, 2004 12:47 PM:
The following info will be needed in the equation:

1) FormDimensions
2) ButtonDimensions
# DarthPedro said on March 20, 2004 1:37 PM:
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;
# Panos Theofanopoulos said on March 20, 2004 2:26 PM:
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 :)
# RichB said on March 20, 2004 5:01 PM:
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.
# Jay Bazuzi [MS] said on March 20, 2004 7:49 PM:
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*.
# Jay Bazuzi [MS] said on March 20, 2004 8:09 PM:
Panos: In Whidbey we've implemented a powerful & flexible formatting engine. There is an option for this exact case. (At one point we had 90 options!)

It turns out that any time you say "No one formats there code like XXX", you'll hear from someone who does. For example, *I* like a space between the method name and the open paren.
# Thomas Eyde said on March 20, 2004 10:24 PM:
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);
}
}

# pin17931 said on March 21, 2004 9:24 AM:
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)
# Tene said on March 21, 2004 10:22 AM:
// put the Cancel button in the lower right corner

// put the Ok button at the left of the Cancel button

From that, no matter how crap the code is, if the developer can read a comment, he'll be able to get the idea beyond the code. And unless the dev made the exact opposite challenge anyone should be even able to find the code clear.


By the way: I won't put the code in OnSizeChanged, I'll simply use what winforms give us: anchoring.
# jaybaz_MS's WebLog said on March 22, 2004 3:37 PM:
# jaybaz_MS's WebLog said on March 22, 2004 3:37 PM:
# Louis Zelus said on March 24, 2004 11:59 AM:
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
# Alfred Gary Myers Jr. said on March 24, 2004 3:12 PM:
_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;
# Alfred Gary Myers Jr. said on March 24, 2004 3:16 PM:
_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);
# Michal Chaniewski said on March 25, 2004 9:41 AM:
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;
}
# the1's WebLog said on March 26, 2004 9:22 PM:
# the1's WebLog said on March 27, 2004 1:41 AM:
# jaybaz MS WebLog Clearest code challenge | Green Tea Fat Burner said on June 9, 2009 3:32 PM:

PingBack from http://greenteafatburner.info/story.php?id=3736

New Comments to this post are disabled

This Blog

Syndication

Page view tracker