I am binding the ItemsSource of a RadToolbarTray to a ViewModel property to create one or more toolbars dynamically via the following.
<
telerik:RadToolBarTray
telerikQuickStart:ThemeAwareBackgroundBehavior.IsEnabled
=
"True"
ItemsSource
=
"{Binding MergedToolbarCommands}"
x:Name
=
"ToolbarTray"
>
<
telerik:RadToolBarTray.ItemTemplate
>
<
DataTemplate
>
<
telerik:RadToolBar
ItemsSource
=
"{Binding}"
OverflowMode
=
"AsNeeded"
>
<
telerik:RadToolBar.ItemContainerStyle
>
<
Style
TargetType
=
"{x:Type ContentPresenter}"
>
<
Setter
Property
=
"ToolBar.OverflowMode"
Value
=
"Never"
/>
</
Style
>
</
telerik:RadToolBar.ItemContainerStyle
>
</
telerik:RadToolBar
>
</
DataTemplate
>
</
telerik:RadToolBarTray.ItemTemplate
>
</
telerik:RadToolBarTray
>
Unfortunately, the ToolbarTray is not displayed. When I inspect it with Snoop, I notice that all my Toolbars have their DataContexts set correctly and Snoop correctly renders each one individually, but the RadToolbarTray measures itself to have zero height, so it is not displayed. How do I get The RadToolbarTray to measure itself correctly?
Cheers,
Mike
6 Answers, 1 is accepted
Unfortunately the RadToolBarTray doesn't support this scenario at the moment. However, we've logged this task in our PITS where you can vote for it thus increasing its priority.
Regards,Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
There is a universal wpf pattern that enables your scenario.
Create your own ItemsSource property as AttachedProperty. In DependencyPropertyChanged callback transform items from collection to UIElements and add it to your container, in your case RadToolBarTray. You can attach to INotifyCollectionChanged and use DataTemplates or DataTemplateSelecor if needed.
Here's my quick solution:
<
telerik:RadToolBarTray
DockPanel.Dock
=
"Top"
assets:ToolbarTrayExtensions.ItemsSource
=
"{Binding Toolbars}"
>
<
telerik:RadToolBarTray.ItemTemplate
>
<
DataTemplate
>
<
telerik:RadToolBar
ItemsSource
=
"{Binding Items}"
Visibility
=
"{Binding IsVisible, Converter={StaticResource VisibilityConverter}}"
>
<
telerik:RadToolBar.ItemTemplate
>
<
DataTemplate
>
<
telerik:RadButton
Content
=
"{Binding Name}"
Visibility
=
"{Binding IsVisible, Converter={StaticResource VisibilityConverter}}"
Command
=
"{Binding Command}"
IsEnabled
=
"{Binding IsEnabled}"
/>
</
DataTemplate
>
</
telerik:RadToolBar.ItemTemplate
>
</
telerik:RadToolBar
>
</
DataTemplate
>
</
telerik:RadToolBarTray.ItemTemplate
>
</
telerik:RadToolBarTray
>
namespace
Monogram.Wpf.Assets
{
public
class
ToolbarTrayExtensions
{
#region Attached
public
static
IEnumerable GetItemsSource(DependencyObject obj)
{
return
(IEnumerable)obj.GetValue(ItemsSourceProperty);
}
public
static
void
SetItemsSource(DependencyObject obj, IEnumerable value)
{
obj.SetValue(ItemsSourceProperty, value);
}
public
static
readonly
DependencyProperty ItemsSourceProperty = DependencyProperty.RegisterAttached(
"ItemsSource"
,
typeof
(IEnumerable),
typeof
(ToolbarTrayExtensions),
new
PropertyMetadata(ItemsSourceChanged));
private
static
ToolbarTrayExtensions GetToolbarTrayExtensions(DependencyObject obj)
{
return
(ToolbarTrayExtensions)obj.GetValue(ToolbarTrayExtensionsProperty);
}
private
static
void
SetToolbarTrayExtensions(DependencyObject obj, ToolbarTrayExtensions value)
{
obj.SetValue(ToolbarTrayExtensionsProperty, value);
}
private
static
readonly
DependencyProperty ToolbarTrayExtensionsProperty = DependencyProperty.RegisterAttached(
"ToolbarTrayExtensions"
,
typeof
(ToolbarTrayExtensions),
typeof
(ToolbarTrayExtensions));
#endregion
private
static
void
ItemsSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
RadToolBarTray tray = (RadToolBarTray)o;
ToolbarTrayExtensions extentions = GetToolbarTrayExtensions(tray);
if
(extentions ==
null
)
{
extentions =
new
ToolbarTrayExtensions(tray);
SetToolbarTrayExtensions(tray, extentions);
}
if
(e.OldValue !=
null
)
{
tray.Items.Clear();
if
(e.OldValue
is
INotifyCollectionChanged)
{
((INotifyCollectionChanged)e.OldValue).CollectionChanged -= extentions.ItemsSource_CollectionChanged;
}
}
if
(e.NewValue !=
null
)
{
foreach
(var item
in
(IEnumerable)e.NewValue)
{
tray.Items.Add(GenerateItemContainer(item, tray.ItemTemplate));
}
if
(e.NewValue
is
INotifyCollectionChanged)
{
((INotifyCollectionChanged)e.NewValue).CollectionChanged += extentions.ItemsSource_CollectionChanged;
}
}
}
private
static
FrameworkElement GenerateItemContainer(
object
dataItem, DataTemplate template)
{
FrameworkElement itemContainer = (FrameworkElement)template.LoadContent();
itemContainer.DataContext = dataItem;
return
itemContainer;
}
private
readonly
RadToolBarTray tray;
private
ToolbarTrayExtensions(RadToolBarTray tray)
{
this
.tray = tray;
}
private
void
ItemsSource_CollectionChanged(
object
sender, NotifyCollectionChangedEventArgs e)
{
if
(e.OldItems !=
null
)
{
foreach
(var item
in
e.OldItems)
{
FrameworkElement itemContainer = tray.Items.OfType<FrameworkElement>().FirstOrDefault(el => el.DataContext == item);
if
(itemContainer !=
null
)
{
tray.Items.Remove(itemContainer);
}
}
}
if
(e.NewItems !=
null
)
{
foreach
(var item
in
e.NewItems)
{
tray.Items.Add(GenerateItemContainer(item, tray.ItemTemplate));
}
}
if
(e.Action == NotifyCollectionChangedAction.Reset)
{
tray.Items.Clear();
}
}
}
}
This bug is still exist in 2014 Q1, is there any chanse that it would be solved in next few releases?
RadToolBar still does not support data binding. You can track the status of this feature request in our feedback portal. Currently we cannot say a possible time frame when this will be implemented.
Regards,
Petar Mladenov
Telerik
Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.
Hello Sergey,
This feature is currently not planned. Could you please add more details regarding your scenario so that we can have it mind when we estimate it eventually ?
Regards,
Petar Mladenov
Progress Telerik