views:

117

answers:

3

Hi,

I've got some entities which have decimal properties on them. These entities' properties are displayed in multiple places throughout my UI.

Currently I'm finding myself doing:

litWeight.Text = person.Weight.ToString("0.00");

all over the place. Now I know for a fact that in several instances, and am suspicious of many others that the client is likely to want the values to 3d.p. in the future.

Is there some pattern I can employ to handle the formatting of this Weight property (and other properties; not just decimals, perhaps dates etc.) so that I can have this formatting in a single place?

I know could use a formatstring in the webconfig, or write some extension methods in the UI but these don't seem very elegant solutions.

It would be nice to have some formatting objects which are tied to my entities, so its inherently obvious which formatter to use.

Thanks,

Andrew

+2  A: 

The simplest solution would be to make a utility class with static methods that appropriately format different types of values and call them. For example:

litWeight.Text = Utility.FormatWeight(person.Weight);
Toni Ruža
+1  A: 

Can you not add a method to the entities for formatting themeslves? Then each object can delegate to a 'strategy' object to do the actual formatting.

A reason for this is both to be able to change the decimal places etc, but also to allow things like internationalisation - decimal formatting is locale-dependent; some countries use decimal commas instead of points, or group digits in sets other than threes etc.

EDIT: The comment was this puts presentation code in the domain layer. True, so apply the standard fix for all design problems; add one more layer of indirection :)

You may not want to have the full MVC, but the concept of View and Model still seem appropriate. Perhaps, for each entity, define a View class, so PersonView which keeps a reference to a Person object and has properties called format_weight etc for each property of Person that is of interest? It should still use a Strategy pattern for the actual formatting.

So your example would be

PersonView pv = new PersonView(person)

litWeight.Text = pv.format_weight();

(please excuse syntactical errors, I don't speak C#)

If you want, you could make PersonView drop in replacement for Person, either by reimplementing the methods/properties and delgating to the referenced Person, or by inheriting from Person when making PersonView?

Paul
Yes, but then I'm putting presentation layer code into the domain layer which isn't very nice
Andrew Bullock
Yeah i had considered a decorator, but i'd rather not have to delegate everything, and inheritance isnt really an option. Also, I dont want to have to wrap every entity just to be able to render it. Maybe i'll end up doing it that way, I just cant help feeling theres a nicer solution out there...
Andrew Bullock
If Weight (for example) isn't a concept worth modelling itself as a class, then ultimately it seems to me you only have two options - augment the Person class in somw way to know how to format Weights, or provide a static set of formatting functions that know how to. There's nowhere else to put it?
Paul
+1  A: 

You could create a very basic user control - deriving from label or similar - that is responsible purely for displaying a weight string so you then have:

weightValue.DisplayValue(person.Weight);

and the setter formats the decimal as required. If this is used whenever you display a weight then you only have to alter the user control to change all displays of weight.

A basic version could be:

public void DisplayValue(decimal weight)
{
    this.Text = weight.ToString("0.00");
}
Garry Shutler
I do like this idea. I think I would extend WebControl, give it a decimal weight property and put the formatting in the OnRender(). I always use a literal in all the places i was referring to it being used, so a UC is a feasible soltuion :)
Andrew Bullock