views:

93

answers:

3

Hi guys,

I don't know how to use the "T" and I never understood it quite well, but I'm sure that the answer will reside in anything around it ...

I have a huge switch that all it does is apply an Attribute to an object and add the control to a collection, kind of Extract > Apply Attribute > Add, like:

1st switch

foreach (AdwizaControl control in form.AdwizaControls)
{
    Panel panel = new Panel();
    int x = 0, y = 0;
    switch (control.Type)
    {

        case ControlType.CheckBox:
            AdwizaCheckBox checkbox = (AdwizaCheckBox)control.AdwizaWebControl;
            x = checkbox.X;
            y = checkbox.Y;
            panel.Controls.Add(checkbox);
            break;
        case ControlType.Bevel:
            AdwizaBevel bevel = (AdwizaBevel)control.AdwizaWebControl;
            bevel.Width = bevel.W;
            bevel.Height = bevel.H;
            panel.Controls.Add(bevel);
            break;

checkbox.X and checkbox.Y are properties from a Definition XML and here we are setting the control to that size

...

2nd switch (to loop through controls that are inside a RadPageView (Telerik component)

foreach (RadPageView pageView in multiPage.PageViews)
{
    int controlCount = pageView.Controls.Count;

    for (int i = 0; i < controlCount; i++)
    {
        if (pageView.Controls[i].GetType() == typeof(AdwizaControl))
        {
            switch (((AdwizaControl)pageView.Controls[i]).Type)
            {

...

case ControlType.Grid:
    AdwizaGrid pageViewGrid = (AdwizaGrid)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    pageViewGrid.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewGrid.Y + increaseY, pageViewGrid.X + increaseX));
    pageView.Controls.Add(pageViewGrid);
    break;
case ControlType.Hyperlink:
    AdwizaHyperlink pageViewHyperlink = (AdwizaHyperlink)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    pageViewHyperlink.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewHyperlink.Y + increaseY, pageViewHyperlink.X + increaseX));
    pageView.Controls.Add(pageViewHyperlink);
    break;
case ControlType.ImageBox:
    AdwizaImageBox pageViewImageBox = (AdwizaImageBox)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    pageViewImageBox.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewImageBox.Y + increaseY, pageViewImageBox.X + increaseX));
    pageView.Controls.Add(pageViewImageBox);
    break;
case ControlType.Label:
    AdwizaLabel pageViewlabel = (AdwizaLabel)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    pageViewlabel.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewlabel.Y + increaseY, pageViewlabel.X + increaseX));
    pageView.Controls.Add(pageViewlabel);
    break;
case ControlType.Slavebox:
    AdwizaSlavebox pageViewSlavebox = (AdwizaSlavebox)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    pageViewSlavebox.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewSlavebox.Y + increaseY, pageViewSlavebox.X + increaseX));

    pageView.Controls.Add(pageViewSlavebox);
    break;
case ControlType.Repeatbox:
    AdwizaRepeatBox pageViewrepeatbox = (AdwizaRepeatBox)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    pageViewrepeatbox.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewrepeatbox.Y + increaseY, pageViewrepeatbox.X + increaseX));
    pageView.Controls.Add(pageViewrepeatbox);
    break;

it is bigger as it has to cover all objects I'm using...

How can I to this in a simple call? Kind like:

ApplyPositionAttribute(
    ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl);

Is there a way to simplify this?


Added The switch statement

A: 

I understand that all the classes AdwizaGrid, AdwizaHyperlink etc. have AdwizaControl as common base class. I also assume that Attributes is defined in the base class. In this case you can remove a large part of the duplication like this:

AdwizaControl control;

case ControlType.Grid:
    control = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    break;
case ControlType.Hyperlink:
    control = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    break;
...

then after the case:

control.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;",
        control.Y + increaseY, control.X + increaseX));
pageView.Controls.Add(control);

After this, you could replace the big switch with some sort of a mapping from control types to attributes (I am not familiar with C# so I can't give you an exact tip, but e.g. in C++ you could use functors or pointers to members).

Péter Török
A: 

If AdwizaRepeatBox, AdwizaRepeatBox, AdwizaSlavebox and other don't extend single class that has property Attributes than you better search reflection namespace for an answer or rewrite your code so that they would extend single class

If they extend single class than the code you are looking for should look like this:

private void ApplyPositionAttribute<T>(AdwizaWebControl webControl) where T : InheritedClass
{
    /* ... */

    T adwizalControl = (T)webControl;
    pageViewrepeatbox.Attributes.Add(
        "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewrepeatbox.Y + increaseY, pageViewrepeatbox.X + increaseX));
    pageView.Controls.Add(pageViewrepeatbox);
}

Edit

Use this if all adwizaControl extend single class which has Attributes property. If X and Y properties are extended use virtual keyword to override base class declaration

AdwizaWebControl webControl = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
webControl.Attributes.Add("style", string.Format("position:absolute;top:{0}px;left:{1}px;", webControl.Y + increaseY, webControl.X + increaseX));
pageView.Controls.Add(webControl);
Sergej Andrejev
Also it would help to see switch statement.
Sergej Andrejev
added the switch start code :) - dang ... I will never get how magical T is and does :-/
balexandre
Is Attributes property part of AdwizaWebControl? If that's true I don't know why you need to cast to implementation (AdwizaLabel, AdwizalSlavebox etc) at all. Check modified answer for code
Sergej Andrejev
A: 

In this case you don't have to use generics. If all your controls inherit from AdvizaWebControl you could just write sth like this:

AdwizaWebControl webControl = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
webControl.Attributes.Add("style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewGrid.Y + increaseY, pageViewGrid.X + increaseX));
pageView.Controls.Add(webControl);

However, if your classes don't inherit from AdwizaWebControl generics won't help.

empi