This is a migrated thread and some comments may be shown as answers.

UserControl inside RadPanelBarItem

11 Answers 135 Views
PanelBar
This is a migrated thread and some comments may be shown as answers.
Carlos
Top achievements
Rank 1
Carlos asked on 17 Feb 2011, 04:44 PM
Hey there,
I'm trying to databind a usercontrol that has a RadPanelBarControl, with two RadPanelBarItems, and these two PanelBarItems have other usercontrols inside.

When i databind the datacontext of the main usercontrol for the first time, the RadPanelBar shows the content correctly, but when i change the datacontext, it doesnt refresh its layout...

I've tried to reproduce exactly the same but with RadTabControls, and it works perfectly.


This is how i change the datacontext of the usercontrol in my host page.xml:

CategoryViewModel vm = new CategoryViewModel(c.DataObject.idCategory);
categoryDetailControl.LayoutRoot.DataContext = vm;


The usercontrol XAML:

<UserControl x:Class="CTI2.Client.Silverlight.Controls.CategoryDetail"
    xmlns:viewModels="clr-namespace:CTI2.Client.Silverlight.ViewModels"
    xmlns:local="clr-namespace:CTI2.Client.Silverlight.Controls"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="800">
      
    <Grid x:Name="LayoutRoot" Background="White">
        <telerik:RadPanelBar ExpandMode="Multiple" Orientation="Vertical" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                             VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"
                             HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
            <telerik:RadPanelBarItem Header="Sub-Categorias (Capas agregadoras)">
                <TextBlock Text="Ainda não disponível nesta versão..." FontWeight="Bold" FontSize="12" FontStyle="Italic" />
            </telerik:RadPanelBarItem>
            <telerik:RadPanelBarItem Header="Titulos na Categoria" >
                <local:CategorySushi x:Name="categorySushiControl" />
            </telerik:RadPanelBarItem>
        </telerik:RadPanelBar>
    </Grid>
</UserControl>

11 Answers, 1 is accepted

Sort by
0
Tina Stancheva
Telerik team
answered on 22 Feb 2011, 03:29 PM
Hi Carlos,

From the code snippet you sent I am not sure how should the changed DataContext reflect the UserControl's layout since I cannot see any Bindings in the xaml. Perhaps I am missing something, so could you please elaborate a bit more or send us the code-behind and the ViewModels as well.

Also, you can have a look at this or this article illustrating how to data bind the RadPaneBar.

Best wishes,
Tina Stancheva
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Carlos
Top achievements
Rank 1
answered on 22 Feb 2011, 04:42 PM
Thanks for the response,
I'll try to elaborate.

Suppose you have a master-detail type page, where in the left side you have a treeview and on the right side, you have the detail of the item you select in the treeview.

The usercontrol i posted above is the detail part.

When i click on an item in the treeview, I create an instance of the ViewModel and set some properties on it. Then i assign it.
I use the Telerik's treeview OnSelected eventhandler to do it:

void tvCategories_Selected(object sender, Telerik.Windows.RadRoutedEventArgs e)
        {
            RadTreeViewItem item = e.OriginalSource as RadTreeViewItem;
            currentItem = item;
 
            CategoriesModel c = currentItem.Item as CategoriesModel;
 
            CategoryViewModel vm = new CategoryViewModel(c.DataObject.idCategory);
            categoryDetailControl.DataContext = vm;
        }

(categoryDetailControl is the UserControl i posted above)

The CategoryViewModel class begins a load operation when i create it with constructor parameters. What it does is to fetch detailed category information based on the CategoryId.

Now the problem is that the RadPanelBar doesnt show anything at all. The binding simply doesnt happen. Most of my bindings are setted up on the usercontrol that is inside of the 2nd RadPanelBarItem. That usercontrol (local:categorySushi) it is just a simple EditForm with some textboxes on it, and nothing is done via codebehind.

I know that my EditForm is OK because if use a RadExpander instead of the RadPanelBar everything works OK.

Maybe the RadPanelBar is not the best control for this particular case, i just want to use it as a accordion container (like a StackPanel that has cool background and a colapse/expand ability). I dont want to create RadPanelBarItems dynamically nor databind it. I just want to databind the items that it contains.

Thanks,
Carlos
0
Tina Stancheva
Telerik team
answered on 25 Feb 2011, 06:54 PM
Hello Carlos,

Unfortunately the RadPanelBar cannot be used in this scenario, since in order to databind its content you need to databind its/its items ItemsSource, which won't work in your case.

Therefore it is better to use the RadExpander instead. You can even handle the RadExpander's Collapsed() and Expanded() events to create a composite UserControl, containing multiple Expanders that behave like an accordion. You can even edit the ControlTemplate of the RadExpander in order to modify it style to look more like the RadPanelBar style for example.

I attached a sample project illustrating similar scenario. I hope it helps.

Regards,
Tina Stancheva
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Bala
Top achievements
Rank 1
answered on 30 Jan 2013, 12:04 PM
Hello Tina Stancheva,
   
        How will you retrieve the user control    inside the Expander?

Regards,
bala
0
Tina Stancheva
Telerik team
answered on 31 Jan 2013, 05:17 PM
Hi Bala,

The RadExpander.Content property can give you access to all UIElements hosted in the content part of the control. Let me know if that helps.

Regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Bala
Top achievements
Rank 1
answered on 16 Feb 2013, 11:11 AM
Hello Tina Stancheva,
 
Yes, I got resolved. Thank you for your kind information. But is there any option with RadPanelBar 
  to access the user Control placed in  RadPanelBarItems.?

With regards,
Bala 
0
Tina Stancheva
Telerik team
answered on 18 Feb 2013, 09:16 AM
Hello Bala,

The RadPanelBar control displays hierarchical data. This means that the RadPanelBarItem control exposes both Items and ItemsSource properties which you can use to get the collection of children displayed inside each RadPanelBarItem.

You can examine this tutorial that demonstrates how to bind the RadPanelBar to a hierarchical data as it can give you better understanding of the PanelBarItems structure.

Regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Graeme
Top achievements
Rank 2
answered on 05 Mar 2014, 04:11 PM
I was looking for a similar solution as I need to dynamically add Panels to the RadPanelBar control with each Panel having a different UserControl injected. I've found that MEF makes it possible. Here's how I did it:

1. Create a UIProvider class to point to the control:

01.<ExportUIFilterViewProvider("PanelBar.UIProvider")>
02.Public Class UIProvider : Inherits UIProviderBase
03. 
04.    Public Overrides ReadOnly Property Title() As String
05.        Get
06.            Return "Panel Header goes here"
07.        End Get
08.    End Property
09. 
10.    <Import(UsercontrolView)>
11.    Public Overrides Property EntryPage() As ExportFactory(Of IUIPanelProviderView)
12. 
13.End Class

2. Implement the IUIPanelProviderView interface on the Usercontrol and Export the UsercontrolView to match the import.

3. Now in your viewmodel (behind the PanelBar control) import all the "PanelBar.UIProvider" wrappers and wrap them in a HierarchicalData class:

01.#Region "Plug-in Management"
02. 
03.    <ImportMany("PanelBar.UIProvider", AllowRecomposition:=True)>
04.    Public Property Plugins() As UIProviderBase()
05. 
06.    Public Sub OnImportsSatisfied() Implements System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
07. 
08.        For Each plugin As UIProviderBase In Plugins
09.            Items.Add(New PanelItemData With {.Header = plugin.Title, .Contents = New ObservableCollection(Of UIFilterViewProviderBase) From {plugin}})
10.        Next
11. 
12.    End Sub
13. 
14.#End Region

1.Friend Class PanelItemData
2.    Property Header As String
3.    Property Contents As ObservableCollection(Of UIFilterViewProviderBase)
4.End Class

4. Here's the Xaml for the PanelBar control:

01.<UserControl.Resources>
02.    <converters:UIProviderToFilterControlConverter x:Key="UIProviderToFilterControlConverter"/>
03.     
04.    <DataTemplate x:Key="ContentTemplate">
05.        <ContentControl Content="{Binding EntryPage, Converter={StaticResource UIProviderToFilterControlConverter}}" />
06.    </DataTemplate>
07.</UserControl.Resources>
08. 
09.<Grid x:Name="LayoutRoot">
10.    <telerik:RadPanelBar ItemsSource="{Binding Items}">
11.        <telerik:RadPanelBar.ItemTemplate>
12.            <telerik:HierarchicalDataTemplate ItemsSource="{Binding Contents}" ItemTemplate="{StaticResource ContentTemplate}">
13.                <Grid VerticalAlignment="Center" >
14.                    <TextBlock Text="{Binding Header}" />
15.                </Grid>
16.            </telerik:HierarchicalDataTemplate>
17.        </telerik:RadPanelBar.ItemTemplate>
18.    </telerik:RadPanelBar>
19.</Grid>

5. Finally, the Converter class to inject the control:
 
01.Public Class UIProviderToFilterControlConverter : Implements IValueConverter
02. 
03.    Public Function Convertvalue As Object,
04.                            targetType As System.Type,
05.                            parameter As Object,
06.                            culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
07.        Return DirectCast(value, ExportFactory(Of IFilterView)).CreateExport.Value
08. 
09.    End Function
10. 
11.    Public Function ConvertBackvalue As Object,
12.                                targetType As System.Type,
13.                                parameter As Object,
14.                                culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
15.        Throw New NotSupportedException
16.    End Function
17. 
18.End Class


It's after 3am here ... so in the morning, if I have time, I'll try and put together a sample and uploaded it.

Otherwise, enjoy!

Graeme

0
Graeme
Top achievements
Rank 2
answered on 05 Mar 2014, 04:15 PM
Small Adjustment to the viewmodel. Left out the following:

1.Public Property Items As New ObservableCollection(Of PanelItemData)

From:

01.#Region "Plug-in Management"
02. 
03.    <ImportMany("PanelBar.UIProvider", AllowRecomposition:=True)>
04.    Public Property Plugins() As UIProviderBase()
05. 
06.    Public Sub OnImportsSatisfied() Implements System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
07. 
08.        For Each plugin As UIProviderBase In Plugins
09.            Items.Add(New PanelItemData With {.Header = plugin.Title, .Contents = New ObservableCollection(Of UIFilterViewProviderBase) From {plugin}})
10.        Next
11. 
12.    End Sub
13. 
14.#End Region

1.Friend Class PanelItemData
2.    Property Header As String
3.    Property Contents As ObservableCollection(Of UIFilterViewProviderBase)
4.End Class

4. Here's the Xaml for the PanelBar control:

01.<UserControl.Resources>
02.    <converters:UIProviderToFilterControlConverter x:Key="UIProviderToFilterControlConverter"/>
03.     
04.    <DataTemplate x:Key="ContentTemplate">
05.        <ContentControl Content="{Binding EntryPage, Converter={StaticResource UIProviderToFilterControlConverter}}" />
06.    </DataTemplate>
07.</UserControl.Resources>
08. 
09.<Grid x:Name="LayoutRoot">
10.    <telerik:RadPanelBar ItemsSource="{Binding Items}">
11.        <telerik:RadPanelBar.ItemTemplate>
12.            <telerik:HierarchicalDataTemplate ItemsSource="{Binding Contents}" ItemTemplate="{StaticResource ContentTemplate}">
13.                <Grid VerticalAlignment="Center" >
14.                    <TextBlock Text="{Binding Header}" />
15.                </Grid>
16.            </telerik:HierarchicalDataTemplate>
17.        </telerik:RadPanelBar.ItemTemplate>
18.    </telerik:RadPanelBar>
19.</Grid>

5. Finally, the Converter class to inject the control:
 
01.Public Class UIProviderToFilterControlConverter : Implements IValueConverter
02. 
03.    Public Function Convertvalue As Object,
04.                            targetType As System.Type,
05.                            parameter As Object,
06.                            culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
07.        Return DirectCast(value, ExportFactory(Of IFilterView)).CreateExport.Value
08. 
09.    End Function
10. 
11.    Public Function ConvertBackvalue As Object,
12.                                targetType As System.Type,
13.                                parameter As Object,
14.                                culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
15.        Throw New NotSupportedException
16.    End Function
17. 
18.End Class


It's after 3am here ... so in the morning, if I have time, I'll try and put together a sample and uploaded it.

Otherwise, enjoy!

Graeme

[/quote]
0
Graeme
Top achievements
Rank 2
answered on 05 Mar 2014, 05:41 PM
I've broken out the code from our main app into a demo app - DynamicLoadRadPanelBar.zip . This will demonstrate how to dynamically load the RadPanelBar control Panes with UserControls at runtime using MVVM with MEF. This method is pretty universal and can be used elsewhere. :)

Enjoy!
0
Tina Stancheva
Telerik team
answered on 10 Mar 2014, 11:36 AM
Hi Graeme,

Thank you for sharing your solution with the community. I updated your Telerik points for your involvement.

Regards,
Tina Stancheva
Telerik

DevCraft Q1'14 is here! Watch the online conference to see how this release solves your top-5 .NET challenges. Watch on demand now.

Tags
PanelBar
Asked by
Carlos
Top achievements
Rank 1
Answers by
Tina Stancheva
Telerik team
Carlos
Top achievements
Rank 1
Bala
Top achievements
Rank 1
Graeme
Top achievements
Rank 2
Share this question
or