RadTabControl parse exception, RadTabItem cannot create instance, breaks VS + Blend designer

5 posts, 1 answers
  1. Stephen
    Stephen avatar
    43 posts
    Member since:
    Apr 2012

    Posted 23 Jul 2012 Link to this post

    Scenario:
    I have looked through the forums and the TabControl documentation and could not find anything that addressed this issue.  I have a Xaml with a RadTabControl in it.  Each RadTabItem is added in this Xaml.  The code for the Xaml is located in a separate Xaml file, in the same project, under the same namespace.  I coded it to basically follow the example First Look in the GridView control Demo.  Design view does work for each of the Xamls I am using for Tabs.  I am guessing that the issue is that the designer doesn't have an object for "StephensPlayground", so it doesn't know that it has a button in it, or anything else for that matter.


    Problem:
    The problem is that the main page's Xaml cannot parse those RabTabItems, so I get a null reference exception.  This breaks the designer in Visual Studio and Blend.  It happens on any tab I try to add and it only affects when you are looking at the code.  Despite the error, compile and runtime are fine.

    Error:
    What I get in VS is "NullReferenceException was thrown on "StephensPlayground": Cannot create instance of "StephensPlayground".   

    Here is my main page's Xaml:
    <mica:MICAContent x:Class="TestingCenter.TestingCenterForm"
                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                      xmlns:local="clr-namespace:TestingCenter"
                      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                      xmlns:mica="clr-namespace:NS_MICAContent;assembly=MICAContent"
                      xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                      d:DesignHeight="800"
                      d:DesignWidth="1000"
                      mc:Ignorable="d">
     
        <Grid x:Name="LayoutRoot"
              Background="Transparent">
            <StackPanel x:Name="MainForm">
                <telerik:RadTabControl x:Name="rtcMainTabControl"
                                       Margin="10"
                                       HorizontalAlignment="Left"
                                       VerticalAlignment="Center"
                                       AllowDragReorder="True"
                                       IsContentPreserved="True">
                    <telerik:RadTabItem Header="Stephen's Playground">
                        <local:StephensPlayground />
                    </telerik:RadTabItem>
                </telerik:RadTabControl>
            </StackPanel>
        </Grid>
    </mica:MICAContent>

    Here is the Xaml from StephensPlayground:
    <UserControl x:Class="TestingCenter.StephensPlayground"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:baseclass="clr-namespace:Controls;assembly=Controls_BaseClass"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:darxaml="clr-namespace:DAR;assembly=DAR_BaseXaml"
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 d:DesignHeight="800"
                 d:DesignWidth="1100"
                 mc:Ignorable="d">
     
        <Grid x:Name="LayoutRoot"
              Background="Transparent">
            <Grid Margin="10">
                <StackPanel>
                    <telerik:RadButton x:Name="rbtnPlacement"
                                       Width="100"
                                       Height="25"
                                       Margin="10,0,0,0"
                                       HorizontalAlignment="Left"
                                       Content="Test" />
                </StackPanel>
            </Grid>
        </Grid>
    </UserControl>
  2. Stephen
    Stephen avatar
    43 posts
    Member since:
    Apr 2012

    Posted 23 Jul 2012 Link to this post

    It is funny how once you decide to post a problem, you figure it out shortly after... regardless of how many days you tried to resolve it before posting.

    The issue I had was being caused because of things that I had inside of my constructor for the different Tabs.  Once I removed everything from the constructor, other than InitializeComponent(), the problem went away.

    Basically, it looks like you cannot instantiate another object from a class outside your project inside your constructor.  This may not be the best way to state the limitation, but it is the best way I can word it, based on what I found.

    So, to work around this, I created events in my main page that would execute, based on the tab that was selected.  Each page that is being used for a RadTabItem subscribes to the event that signifies that their tab was clicked.  I also added a boolean to determine whether it has been initialized or not.  This is because I want to keep state, so I don't want the tab item to go through it's setup a second time.

    There may be a way more slick to do this.  If someone has a suggestion of something easier that I missed, please post it.
  3. DevCraft banner
  4. Stefan
    Admin
    Stefan avatar
    89 posts

    Posted 26 Jul 2012 Link to this post

    Hello Stephen,

    We are not aware of the error you have described and unfortunately from the code you have posted we can't be sure what is the cause of the issue. It may be something in our controls or something in your constructors. In order to provide you with further assistance, we will needb a sample project that reproduces your scenario - especially the code-behind logic? Also it would be useful if you can send your workaround.

    Best regards,
    Stefan
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  5. Stephen
    Stephen avatar
    43 posts
    Member since:
    Apr 2012

    Posted 26 Jul 2012 Link to this post

    I have the main page, which houses a RadTabControl.  Then, there is a separate xaml for the content of each tab items, which is like your FirstLook demo.  The main page is called TestingCenter, which has a RadTabControl named rtcMainTabControl.  In that, there is a RabTabItem whose content is called TelerikControls.

    I decided I didn't want the content of the tabs to be generated until someone clicked on that tab.  So, in the main page, I created an event for each of the Tabs that I have specified in the main page's xaml.  I have a bool to make sure that when the user clicks on another tab and then goes back to TelerikControls, it doesn't trigger the event a second time.  I have keep state enabled on the tab control.

    In the TestingCenter Class, I have these things:
    // Globals
    public static EventHandler InitializeTelerikControls { get; set; }
    private bool SetupTelerikControls = true;
     
    // Event Handler in TestingCenter Class
    private void rtcMainTabControl_SelectionChanged(object sender, RadSelectionChangedEventArgs e)
    {
         var _Tab = e.AddedItems[0] as RadTabItem;
     
         if (_Tab != null)
         {
              var _Name = _Tab.Header.ToString();
     
              switch (_Name)
                    {
                        case "Telerik Controls":
                            if (SetupTelerikControls)
                            {
                                InitializeTelerikControls.Invoke(this, null);
                                SetupTelerikControls = false;
                            }
                            break;
                        default:
                            break;
                   }
         }
    }

    Then, in my TelerikControls class, I subscribe to the event and do the stuff that used to be in my constructor, when the event is triggered.

    This is what I used to have in my constructor:

    public TelerikControls()
    {
        StyleManager.ApplicationTheme = new Office_BlueTheme();
     
        InitializeComponent(); 
        LoadTitleNameDropDown();
        LoadActivityHistory();
        SelectHoursTypes();
    }

    Now this is what I have:

    public TelerikControls()
    {
         StyleManager.ApplicationTheme = new Office_BlueTheme(); 
         InitializeComponent(); 
         TestingCenterForm.InitializeTelerikControls += InitScreen;
    }
     
    private void InitScreen(object sender, EventArgs e)
    {
         LoadTitleNameDropDown();
         LoadActivityHistory();
         SelectHoursTypes();
    }

    This preserves my visual studio designer, because it doesn't have to try and create anything when it reads this:
    <telerik:RadTabControl x:Name="rtcMainTabControl"
                                       Margin="10"
                                       HorizontalAlignment="Left"
                                       VerticalAlignment="Center"
                                       AllowDragReorder="True"
                                       IsContentPreserved="True"
                                       SelectionChanged="rtcMainTabControl_SelectionChanged">
         <telerik:RadTabItem Header="Telerik Controls">
              <local:TelerikControls />
         </telerik:RadTabItem>
    </telerik:RadTabControl>

    Hope this explanation is clear enough....
  6. Answer
    Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 31 Jul 2012 Link to this post

    Hello Stephen,

    Thank you for getting back to us and elaborating on your scenario. Based on the info you sent us, I just want to let you know that the RadTabControl by default adds all its Tabs and their Content in the logical tree of the application as soon as it's loaded. However, the content of the tabs will be added in the VisualTree of the application only after the tab is selected. This is why you don't have to take care of this case - the TabControl on its own makes sure that the content of each tab is initialized only after it is selected. Also, if you need to keep the state of the TabItems' Content when they are deselected, you can just set the RadTabControl.IsContentPreserved property to True. This will ensure that the content of each RadTabItem will be loaded for the first time when the tab is selected, but it won't be recreated with every new selection of the tab. This behavior is described in our documentation if you want to have a look at it.

    I'm sharing this information in case you decide to use the RadTabControl behavior and not implement your custom logic that loads the content of the tabs. 

    Greetings,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
DevCraft banner