Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

decouple UI

0 views
Skip to first unread message

mp

unread,
Dec 23, 2010, 8:12:34 PM12/23/10
to
I'm playing with a little app to show some values from a spreadsheet(excel)

First i had some code in the form to open and read the excel files

Then I was thinking about the idea of the form being coupled as little as
possible to the rest of the code

So I took the excel stuff out of the form and created an excelReader class
to do all that stuff...

now if i want to show some results in the form, is the following an "ok" way
to do it or is there a better pattern i should be using?

it's clunky but at some point the form has to know what control it want to
display what info in...so there's some inevitable coupling at some point,
no???

thanks
mark

ps i tried to get rid of the switch statement below by using foreach but
found a lable control isn't a control apparently
foreach (Control ctl in this.Controls)
{
//label is not a control!!!
Debug.Print("Control " + ctl.Name);
if (ctl.Name == "lbl" + rangeName)
{
ctl.Text = rangeName + ": " + String.Format("{0:
###,###.00}", rng1.Value2);
}
}
(no label names are output)

code snip follows:

...in the form (show value of certain ranges in a lable in the form)
private void btnReadExcel_Click(object sender, EventArgs e)
{
string filename = @"Path to file.xls";

//open excel file and get reference to specific worksheet
ExcelReader xlReader=new ExcelReader(filename, sheetname);

//range names i want to view
string [] rangeNames = new string[] {"Cash","Stocks", "Bonds" ,
"RealEstate", "Total"};

//show values in lables(or other control later )
for (int i = 0; i < rangeNames.Length; i++)
{
this.ShowRangeLabel(xlReader, rangeNames[i]);
}
xlReader.Close();
}

private void ShowRangeLabel( ExcelReader xlReader,string rangeName)
{
Excel.Range rng1;

try
{
rng1 = xlReader.GetRange(rangeName);
}
catch
{
MessageBox.Show("Range not found " + rangeName);
return;
}
switch (rangeName)
{
case "Cash":
this.lblCash.Text = "Cash: " + String.Format("{0:
###,###.00}", rng1.Value2);
break;
case "Stocks":
this.lblStocks.Text = "Stocks: " + String.Format("{0:
###,###.00}", rng1.Value2);
break;
case "Bonds":
this.lblBonds.Text = "Bonds: " + String.Format("{0:
###,###.00}", rng1.Value2);
break;
case "RealEstate":
this.lblRealEstate.Text = "Real Estate: " +
String.Format("{0: ###,###.00}", rng1.Value2);
break;
case "Total":
this.lblTotal.Text = "Total: " + String.Format("{0:
###,###.00}", rng1.Value2);
break;
default:
MessageBox.Show("Unrecognized range name <" + rangeName
+ ">");
break;
}
}


Steel

unread,
Dec 23, 2010, 11:35:26 PM12/23/10
to
On 12/23/2010 8:12 PM, mp wrote:
> I'm playing with a little app to show some values from a spreadsheet(excel)
>
> First i had some code in the form to open and read the excel files
>
> Then I was thinking about the idea of the form being coupled as little as
> possible to the rest of the code
>
> So I took the excel stuff out of the form and created an excelReader class
> to do all that stuff...
>
> now if i want to show some results in the form, is the following an "ok" way
> to do it or is there a better pattern i should be using?
>
> it's clunky but at some point the form has to know what control it want to
> display what info in...so there's some inevitable coupling at some point,
> no???
>

No, not really if you use MVP and IView with the interface get/set of
the control on the form in the Interface.

Any events in the form, you pass control to a like event in the
presenter for the control.

private button1_click()

{
presenter.button1_click() // passing what parms and objects form
the signature of the button click

}


What is Model –View- Controller?

(MVC) is an architectural pattern used in software engineering.
Successful use of the pattern isolates business logic from user
interface considerations, resulting in an application where it is easier
to modify either the visual appearance of the application or the
underlying business rules without affecting the other. In MVC, the model
represents the information (the data) of the application; the view
corresponds to elements of the user interface such as text, checkbox
items, and so forth; and the controller manages the communication of
data and the business rules used to manipulate the data to and from the
model.

http://en.wikipedia.org/wiki/Model-view-controller

What is Model –View- Presenter?

MVP is a software pattern considered a derivative of the
Model-view-controller, which can be used in a Web form or Windows form
based application.

http://en.wikipedia.org/wiki/Model_View_Presenter


The below tutorials will show you how to do it with Windows. In one of
the tutorials, it will show you how to do the object injection of the
IView and the service, which will show how to directly call methods on
the presenter. Most of the examples in the tutorials show an event
driven MVP where you don't directly call a method on the presenter, but
one will show how to call a method on the presenter directly.

The code example in the MVP link above is making a direct call to a
method on the presenter, instead of using events to make the call.


MODEL-VIEW-PRESENTER

http://www.polymorphicpodcast.com/

click 'Shows'

click 'Design Patterns Bootcamp: Model View * Patterns*

view parts 1-5

The controls are objects that you can control on the interface, which
makes things loosely coupled, keeping the UI a dumb UI controlled by the
presenter.

Peter Duniho

unread,
Dec 24, 2010, 12:15:41 AM12/24/10
to
On 12/23/10 5:12 PM, mp wrote:
> I'm playing with a little app to show some values from a spreadsheet(excel)
>
> First i had some code in the form to open and read the excel files
>
> Then I was thinking about the idea of the form being coupled as little as
> possible to the rest of the code
>
> So I took the excel stuff out of the form and created an excelReader class
> to do all that stuff...
>
> now if i want to show some results in the form, is the following an "ok" way
> to do it or is there a better pattern i should be using?
>
> it's clunky but at some point the form has to know what control it want to
> display what info in...so there's some inevitable coupling at some point,
> no???

The Form sub-class absolutely should know what control it's using to
display the info. But only the Form sub-class should know.

On the other hand, it's not clear the Form sub-class should know
anything at all about the Excel data. In a true "decoupled" approach
such as found in the MVC pattern, the Form sub-class would expose
properties that correspond to specific data, and a controller class
would handle setting the properties appropriately based on the Excel
data (from the reader).

In some cases, it is reasonable to combine the Form and your controller,
in which case you very well may find logic within the Form that connects
the Excel data to specific controls. This becomes less feasible the
more complicated the Form and controller logic get, but for simple UIs
it can work fine.

Other comments:

> ps i tried to get rid of the switch statement below by using foreach but
> found a lable control isn't a control apparently

System.Windows.Forms.Label definitely is a sub-class of
System.Windows.Forms.Control. You can see that clearly by looking at
the documentation for the Label class.

> foreach (Control ctl in this.Controls)
> {
> //label is not a control!!!
> Debug.Print("Control " + ctl.Name);
> if (ctl.Name == "lbl" + rangeName)
> {
> ctl.Text = rangeName + ": " + String.Format("{0:
> ###,###.00}", rng1.Value2);
> }
> }
> (no label names are output)

Without a concise-but-complete code example, it's not possible to say
for sure what's wrong. But the most likely cause is that your Label
instances are not direct children of the Form instance. Instead, they
are children of some other container child within the Form.

> code snip follows:
>
> ...in the form (show value of certain ranges in a lable in the form)
> private void btnReadExcel_Click(object sender, EventArgs e)
> {
> string filename = @"Path to file.xls";
>
> //open excel file and get reference to specific worksheet
> ExcelReader xlReader=new ExcelReader(filename, sheetname);
>
> //range names i want to view
> string [] rangeNames = new string[] {"Cash","Stocks", "Bonds" ,
> "RealEstate", "Total"};
>
> //show values in lables(or other control later )
> for (int i = 0; i< rangeNames.Length; i++)
> {
> this.ShowRangeLabel(xlReader, rangeNames[i]);
> }
> xlReader.Close();
> }

It would make more sense to declare your "rangeNames" variable as a
static class member:

private static string[] rangeNames = …;

That way, it's instantiated only once.

> private void ShowRangeLabel( ExcelReader xlReader,string rangeName)
> {
> Excel.Range rng1;
>
> try
> {
> rng1 = xlReader.GetRange(rangeName);
> }
> catch
> {
> MessageBox.Show("Range not found " + rangeName);
> return;
> }
> switch (rangeName)
> {
> case "Cash":
> this.lblCash.Text = "Cash: " + String.Format("{0:
> ###,###.00}", rng1.Value2);
> break;
> case "Stocks":
> this.lblStocks.Text = "Stocks: " + String.Format("{0:
> ###,###.00}", rng1.Value2);
> break;

> [...]
> }
> }

Another alternative would be to not have the array of names at all.
Instead, associate each Label instance with a name in some easy to use
way. I would not recommend using the name of the control itself, but if
you do then at the very least you should just extract the particular
substring from the control's name, rather than keeping a separate list
of names and searching a list of controls for each name.

In the Designer, you can set the Tag property of a control, which can be
used to store a string such as the name for your reader. IMHO, that's a
somewhat better approach than using the control's name.

If you really do want a collection of range names, then IMHO it makes
more sense to make that a dictionary, with the key being the range name,
and the value being a delegate instance, or perhaps a custom type
containing more than one delegate instance if you have more than one
operation to associate with the name (e.g. setting a value and
retrieving a value). Then you simply look up the delegate and invoke it
based on the name. You can enumerate the dictionary members for
situations where you want to handle all members, and use the individual
keys to get specific data (for example, if you have an indexer on the
Form class to extract values for specific range names).

Pete

mp

unread,
Dec 24, 2010, 1:40:27 AM12/24/10
to

"Peter Duniho" <NpOeS...@NnOwSlPiAnMk.com> wrote in message
news:BMqdnVKw_djisYnQ...@posted.palinacquisition...

> On 12/23/10 5:12 PM, mp wrote:
>> I'm playing with a little app to show some values from a
>> spreadsheet(excel)
[]

> Without a concise-but-complete code example, it's not possible to say for
> sure what's wrong. But the most likely cause is that your Label instances
> are not direct children of the Form instance. Instead, they are children
> of some other container child within the Form.

ahh! they're on a frame(groupbox), I didn't realize the foreach would not
get all the controls, thanks'


>
[]


>
> It would make more sense to declare your "rangeNames" variable as a static
> class member:
>

> private static string[] rangeNames = .;
>

of course, i always forget about static :-|

> That way, it's instantiated only once.
>

>> [...]


>> }
>> }
>
> Another alternative would be to not have the array of names at all.
> Instead, associate each Label instance with a name in some easy to use
> way. I would not recommend using the name of the control itself, but if
> you do then at the very least you should just extract the particular
> substring from the control's name, rather than keeping a separate list of
> names and searching a list of controls for each name.
>
> In the Designer, you can set the Tag property of a control, which can be
> used to store a string such as the name for your reader. IMHO, that's a
> somewhat better approach than using the control's name.
>
> If you really do want a collection of range names, then IMHO it makes more
> sense to make that a dictionary, with the key being the range name, and
> the value being a delegate instance, or perhaps a custom type containing
> more than one delegate instance if you have more than one operation to
> associate with the name (e.g. setting a value and retrieving a value).
> Then you simply look up the delegate and invoke it based on the name. You
> can enumerate the dictionary members for situations where you want to
> handle all members, and use the individual keys to get specific data (for
> example, if you have an indexer on the Form class to extract values for
> specific range names).
>
> Pete

thanks for all the ideas, i'll chew on them for awhile
mark


mp

unread,
Dec 24, 2010, 1:25:14 PM12/24/10
to

"Steel" <""Fake99XX1199999fake\"@(Big)(Steel)theXfactor.com"> wrote in
message news:OuednYw8JcKKvonQ...@earthlink.com...

> On 12/23/2010 8:12 PM, mp wrote:
>>[...]

but at some point the form has to know what control it want to
>> display what info in...so there's some inevitable coupling at some point,
>> no???
>>
>
> No, not really if you use MVP and IView with the interface get/set of the
> control on the form in the Interface.
> [...]

> The controls are objects that you can control on the interface, which
> makes things loosely coupled, keeping the UI a dumb UI controlled by the
> presenter.
>

Steel,
thank you very much for that presentation. i've read about mv patterns but
obviously not adequately digested.
I will spend some time reviewing those sites and your explanations...thank
you very much
mark


mp

unread,
Dec 24, 2010, 3:41:28 PM12/24/10
to

"Steel" <""Fake99XX1199999fake\"@(Big)(Steel)theXfactor.com"> wrote in
message news:OuednYw8JcKKvonQ...@earthlink.com...
> On 12/23/2010 8:12 PM, mp wrote:
>> I'm playing with a little app to show some values from a
>> spreadsheet(excel)
[]

>
> http://www.polymorphicpodcast.com/
>

Steel,
Wow thanks again for that link
That's the most understandable presentation i've seen yet...the video is
great compared to all the text i've read in the past
really helps it sink in
Thanks
Mark


Steel

unread,
Dec 24, 2010, 8:10:51 PM12/24/10
to

Well, I start a new contract on 1/3/2011 where I have to come in running
converting over old asp.net solutions over to MVP and n-tier, teaching
the junior developers (10 of them) how to do things right, along with
other things I am hired to do to drag this section of the programming
department to n-tier, OOP, TDD, DDD, ORM, and WCF. It will be a lot of fun.

mp

unread,
Dec 24, 2010, 8:16:38 PM12/24/10
to

"Steel" <""Fake99XX1199999fake\"@(Big)(Steel)theXfactor.com"> wrote in
message news:6YqdnbKdiMk52YjQ...@earthlink.com...

congratulations! Great way to start the New Year!!
was that your podcast?


Steel

unread,
Dec 24, 2010, 8:38:02 PM12/24/10
to
On 12/24/2010 8:16 PM, mp wrote:
> "Steel"<""Fake99XX1199999fake\"@(Big)(Steel)theXfactor.com"> wrote in
> message news:6YqdnbKdiMk52YjQ...@earthlink.com...
>> On 12/24/2010 3:41 PM, mp wrote:
>>> "Steel"<""Fake99XX1199999fake\"@(Big)(Steel)theXfactor.com"> wrote in
>>> message news:OuednYw8JcKKvonQ...@earthlink.com...
>>>> On 12/23/2010 8:12 PM, mp wrote:
>>>>> I'm playing with a little app to show some values from a
>>>>> spreadsheet(excel)
>>> []
>>>
>>>>
>>>> http://www.polymorphicpodcast.com/
>>>>
>>>
>>> Steel,
>>> Wow thanks again for that link
>>> That's the most understandable presentation i've seen yet...the video is
>>> great compared to all the text i've read in the past
>>> really helps it sink in
>>> Thanks
>>> Mark
>>>
>>>
>>
>> Well, I start a new contract on 1/3/2011 where I have to come in running
>> converting over old asp.net solutions over to MVP and n-tier, teaching the
>> junior developers (10 of them) how to do things right, along with other
>> things I am hired to do to drag this section of the programming department
>> to n-tier, OOP, TDD, DDD, ORM, and WCF. It will be a lot of fun.
>
> congratulations! Great way to start the New Year!!
> was that your podcast?
>
>

No, MVP was part of the podcast, which there are some other things there
too to learn.

I know a great deal about some of it I have implemented a lot of it, and
they don't know it (junior developers), so I am going to take them to
the promise land of milk and honey and get paid. :)

http://www.dofactory.com/Patterns/Patterns.aspx
http://www.dofactory.com/Framework/Framework.aspx

I have the 3.5 version I have used to implement things on contracts
using VS2008.

They have VS2010 with .Net Framework 4.0, so I'll purchase 4.0 and use
it to implement and teach them. Maybe some of them will purchase it too
when I start implementing and architecting things in their infrastructure.

It's kind of my dream contract.


0 new messages