Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • rasb 162 posts 218 karma points
    Jul 28, 2009 @ 13:15
    rasb
    1

    umbraco.uicontrols.TabView

    Hi guys,

    Has anyone in here worked with the TabView control?

    I would like to create a layout that has two tabs. On the first tab I have a list of items, and on the second tab I would like to display some information on the item selected on the first tab. 

    Even better, I would like to create new tabs dynamically for every item I choose to view details for.

    Any ideas on how to do that using the umbraco.uicontrols.TabView?

    /RasB

    umbraco v. 4.0.2.1

  • Tim 225 posts 690 karma points
    Jul 28, 2009 @ 15:36
    Tim
    4

    Hi,

    I'm in the middle of doing a complex integration of a legacy app into Umbraco, with extensive use of TabView etc.

    As far as I have learnt so far tab creation needs to be done programatically, so generating them dynamically is probably the way to go.

    To generate a tab you'll need to do this:

    In the code behind of the control or page which implements the TabView declare the new tab which will be called "Details":

    TabPage detailsTab = PropertyTabs.NewTabPage("Details");

    You can enable or disable the grey menu ribbon nav by setting this property:

    detailsTab.HasMenu = false;

    To add an item to the tab menu you do something like this:

    MenuImageButton saveButton = detailsTab.Menu.NewImageButton();
    saveButton.Click += new ImageClickEventHandler(saveButton_Click);
    saveButton.ImageUrl = GlobalSettings.Path + "/images/editor/SaveToPublish.gif";
    detailsTab.Menu.Controls.Add(saveButton);

    Then finally load in a user control or add controls to the tab which contain the content to be displayed or edited:

    Control detailsTabContent = LoadControl("/usercontrols/dashboard/cogProperty/Commercial/detailsTabs/detailsTabContent.ascx");
    detailsTab.Controls.Add(detailsTabContent);

    Personally I contained all my code in a user control which I the load in (as above) to make it easier to maintain, but you can just build up the controls yourself if you wish.

    Hope this helps!

    T

  • Tim 225 posts 690 karma points
    Jul 28, 2009 @ 15:38
    Tim
    0

    I also extensive use events so that the loaded in user controls can subscribe to various events, such as save and perform actions based on this.

    T

  • rasb 162 posts 218 karma points
    Jul 28, 2009 @ 16:36
    rasb
    0

    Hi Tim,

    That was exactly what I needed!

    Now I just need to send a parameter to the user control. I also try to contain all my content to user controls, and the loaded tab should know what row id I have chosen. 

    Thanks a lot!

    /RasB

  • Tim 225 posts 690 karma points
    Jul 28, 2009 @ 16:45
    Tim
    0

    Don't forget to accept the answer if it's everything needed, so others will know that it's the solution!

    T

  • rasb 162 posts 218 karma points
    Jul 28, 2009 @ 16:48
    rasb
    0

    I just remembered that many of the controls I use on the public site make use of properties.

    So I decided to try that out... and it worked!

    TabPage detailsTab = PropertyTabs.NewTabPage("Details");
    detailsTab.HasMenu = false;
    
    ItemDetails detailsTabContent = (ItemDetails)LoadControl("ItemDetails.ascx");
    detailsTabContent.ItemId = "5";
    detailsTab.Controls.Add(detailsTabContent);

    I have just created the string property ItemId on the user control and cast the control to the corresponding class before I add it to the tab.

    Easy way to pass parameters to the control!

    /RasB

  • Tim 225 posts 690 karma points
    Jul 28, 2009 @ 16:57
    Tim
    100

    Yes I use the same approach in my app (as well as events). It makes everything very flexible. The only issue I had was the lack of documentation on all this stuff, so it took quite a bit of reverse engineering to get this far!

    T

  • rasb 162 posts 218 karma points
    Jul 28, 2009 @ 17:01
    rasb
    0

    Hi Tim,

    I have already marked your reply as the answer. Is that not visible to you?

    /RasB

  • Tim 225 posts 690 karma points
    Jul 28, 2009 @ 17:56
    Tim
    1

    Weirdness! no I can't, it normally puts a Green border round the answer in question....

    T

  • rasb 162 posts 218 karma points
    Jul 28, 2009 @ 23:28
    rasb
    0

    Hi Tim,

    I think I see what the problem is. I first marked it as "Thumbs up" when I read it (because I really like answers with code in them), and then after I had tried out your suggestions I went back and wrote a reply that this was the solution and tried to mark it as a solution. When I mark it, it is marked as green here, and you are awarded more karma as far as I can see.

    But when I leave the thread and return again, then there is no solution marked in the thread. I have tried to mark it again, but with no success. 

    This must be a bug in the system.

    I will report it in the appropriate forum and also try to mark one of your later posts in this thread as being the solution, so you can be awarded the karma that you deserve!

    /RasB

  • Peter Dijksterhuis 1442 posts 1722 karma points
    Jul 28, 2009 @ 23:31
    Peter Dijksterhuis
    0

    That's a known bug in this forum. I think they're allready on that ;)

  • rasb 162 posts 218 karma points
    Jul 28, 2009 @ 23:40
    rasb
    0

    OK... I tried to search for a bug but didn't find anything. So I have reposted this I am afraid.

    /RasB

  • rasb 162 posts 218 karma points
    Jul 29, 2009 @ 15:37
    rasb
    0

    Hi guys,

    I am experiencing some strange behaviour when trying to create tabs programatically.

    I have created an ASPX page that has a TabView control on it. On this page I instantiate the Tabs by adding my first tabpage containing the log I want to view. The TabView control has the ID DetailsTab. I have created a property on my User Control called TabViewContainer, which I use to keep a reference to the TabView control. That way I can add TabPages from the embedded control easily:

    protected void Page_Load(object sender, EventArgs e)
            {
                TabPage logTab = DetailsTabs.NewTabPage("LogView");
                detailsTab.HasMenu = false;
    
                DataLog logTabContent = (DataLog)LoadControl("DataLog.ascx");
    logTabContent.TabViewContainer = DetailsTabs;
    logTab.Controls.Add(logTabContent);
    }

    This works fine. Then in my DataLog control I have a GridView with a RowCommand event handler.

    protected void logGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
    {
        // If multiple ButtonField column fields are used, use the
        // CommandName property to determine which button was clicked.
        if (e.CommandName == "viewDetails")
        {
            // Convert the row index stored in the CommandArgument
            // property to an Integer.
            int index = Convert.ToInt32(e.CommandArgument);
    
            if (this.TabViewContainer != null)
            {
                TabPage detailsTab = this.TabViewContainer.NewTabPage("Log item");
                detailsTab.HasMenu = false;
    
                ItemDetails detailsTabContent = ItemDetails)LoadControl("ItemDetails.ascx");
                detailsTabContent.TabViewContainer = TabViewContainer;
                detailsTabContent.IdText = index.ToString();
    detailsTab.Controls.Add(detailsTabContent); } } }

    So when a row is selected I create a new TabPage.

    This is where the trouble starts. When I reach this line 

     

    TabPage detailsTab = this.TabViewContainer.NewTabPage("Log item");

    an exception is thrown. This exception is:

     

    Width must be non negative.
    Parameter name: value

    [ArgumentOutOfRangeException: Width must be non negative.
    Parameter name: value]
       System.Web.UI.WebControls.Style.set_Width(Unit value) +11005092
    
    System.Web.UI.WebControls.WebControl.set_Width(Unit value) +46
    umbraco.uicontrols.TabPage.OnLoad(EventArgs e) +149
    System.Web.UI.Control.LoadRecursive() +66
    System.Web.UI.Control.AddedControl(Control control, Int32 index) +350
    umbraco.uicontrols.TabView.NewTabPage(String text) +331
    logGridView_RowCommand(Object sender, GridViewCommandEventArgs e) in DataLog.ascx.cs:88 System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +149
    System.Web.UI.WebControls.GridView.RaisePostBackEvent(String eventArgument) +215
    System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +29
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2981

    When follow the stack trace to find what might be causing the problem. I first find this line:

    umbraco.uicontrols.TabPage.OnLoad(EventArgs e) +149 

    This leads me to this:

    protected override void OnLoad(EventArgs e) 
    {
       if (this.HasMenu) {
        Menu.Width = System.Web.UI.WebControls.Unit.Pixel((int)this.Width.Value - 12);
        _Menu.ID = this.ID + "_menu";
            this.Controls.Add(_Menu);
       }
    }

    I haven't been able to set the HasMenu property at this time. So I am not sure what is happening.

    Any input on this?

    /RasB

  • Simon Justesen 436 posts 203 karma points
    Jul 29, 2009 @ 15:43
    Simon Justesen
    0

    Have you tried to debug this line?

    Menu.Width = System.Web.UI.WebControls.Unit.Pixel((int)this.Width.Value - 12);
    I suspect that either Menu.Width or this.Width.Value is 0 so you end up with a negative result

  • rasb 162 posts 218 karma points
    Jul 29, 2009 @ 15:53
    rasb
    0

    Nope I haven't tried to debug that line. I have just downloaded the source in order to be able to try and figure out what happened.

    I haven't been able to run the umbraco server in debug mode. I have only succeded in doing that for my own user controls.

    But I suspect that you are right in your assumption. I just don't know what to do about the knowledge that the width is 0. I would rather not have to change any code in the Umbraco distribution.

    /RasB

  • rasb 162 posts 218 karma points
    Jul 29, 2009 @ 15:57
    rasb
    0

    I tried setting the with of the 

    DetailsTabs.Width = System.Web.UI.WebControls.Unit.Pixel(200);

    That seems to do the trick... just not sure why?

    /RasB

  • rasb 162 posts 218 karma points
    Jul 29, 2009 @ 20:13
    rasb
    0

    I have now run into another problem using the TabView. I have tried all day to solve this problem, but haven't been able to.

    I try to create multiple new tabs, but they just seem to take each others place, and I think it might have something to do with the postback event, that I am not quite taking into consideration.

    The setup is as described above

    - ASPX page with a TabView control
    - User Control with Gridview loaded into the TabView control in the ASPX Page_Load event
    - User Control with detailed information loaded into the TabView in the GridView RowCommand event.

    This works, I can load the User Control based on the GridView RowCommand. But the problem occurs when I try to load a second Details Tab. When I do that the first Tab dissapears and I just have the new tab and the GridView tab.

    I think what is happening is that the Page_Load event created the first tab with the GridView when I do the postback, but the existing control isn't recreated because that old RowCommand event isn't triggered again (and it shouldn't), and then it just creates the new tab.

    How do I get it to preserve the existing tabs and not have to recreate them on every postback?

    Thanks,
    RasB

  • Tim 225 posts 690 karma points
    Jul 29, 2009 @ 22:33
    Tim
    0

    Hi,

    You'll have to recreate the tabs on each postback. This is not an Umbraco issue but just how .NET works with controls. Basically a rule of thnumb with controls is that if you create it, you are then responsible for it. So on a postback you'll need to recreate it.

    If you let me know what you are trying to achieve I might be able to give you some further insight to how you can structure the code to make it a bit less painless.

    T

     

  • rasb 162 posts 218 karma points
    Jul 30, 2009 @ 00:12
    rasb
    0

    Hi Tim,

    Yes, that's what I thought. I was just hoping there would be some sort of trick I didn't know about. 

    It is not that big of a problem, so I'll leave it for now and focus on the other more pressing issues :-)

    Later I might give it an overhaul. I am planning on releasing this tool on codeplex when I am done. A client I have, has a need for auditing all  mails sent from the website, so I have created a windows service that handles all sending of mails and also maintains a log of all errors and warnings on each mail.

    So I have created a plugin for the umbraco admin interface that can interact with that log and view detailed error information on each message not sent, as well as when specific mails were created and when they were processed. 

    In order to send a mail from the website, all you have to do is insert a record in a mailqueue table in the database. 

    But as I said, I plan to release it as a package to be downloaded here, and then make the source available on codeplex. But that probably isn't going to be before the end of august or early september. I don't think I am going to have time to package it before then. I haven't created packages before, and this needs both a windows service installed as well as a new database created, and in certain installations also better SMTP server than the one that comes with IIS.

    /RasB

Please Sign in or register to post replies

Write your reply to:

Draft