Seems it does not work for me:
<
UserControl.Resources
>
<
DataTemplate
DataType
=
"vm:MenuItemViewModel"
x:Key
=
"ToolBarItemTemplate"
>
<
c:TemplateSelector
TemplateKey
=
"{Binding MenuItemType}"
Content
=
"{Binding}"
>
<
c:TemplateItem
x:Key
=
"{t:Static Member=vm:MenuItemType.Button}"
>
<
t:RadButton
IsEnabled
=
"{Binding IsEnabled}"
Content
=
"{Binding Text}"
Command
=
"{Binding Command}"
ToolTipService.ToolTip
=
"{Binding ToolTip}"
t:RadToolBar.OverflowMode
=
"{Binding OverflowMode}"
/>
</
c:TemplateItem
>
<
c:TemplateItem
x:Key
=
"{t:Static Member=vm:MenuItemType.Checkbox}"
>
<
t:RadToggleButton
IsEnabled
=
"{Binding IsEnabled}"
Content
=
"{Binding Text}"
Command
=
"{Binding Command}"
CommandParameter
=
"{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}"
ToolTipService.ToolTip
=
"{Binding ToolTip}"
t:RadToolBar.OverflowMode
=
"{Binding OverflowMode}"
/>
</
c:TemplateItem
>
</
c:TemplateSelector
>
</
DataTemplate
>
</
UserControl.Resources
>
<
t:RadToolBarTray
e:RadToolBarTrayExtensions.ItemsSource
=
"{Binding Items}"
VerticalAlignment
=
"Center"
>
<
t:RadToolBarTray.ItemTemplate
>
<
DataTemplate
DataType
=
"vm:MenuViewModel"
>
<
t:RadToolBar
ItemsSource
=
"{Binding Items}"
ItemTemplate
=
"{StaticResource ToolBarItemTemplate}"
/>
</
DataTemplate
>
</
t:RadToolBarTray.ItemTemplate
>
</
t:RadToolBarTray
>
This t:RadToolBar.OverflowMode="{Binding OverflowMode}" is ignored. Even if I set it directly to "Never" or "Always"...
4 Answers, 1 is accepted
It works only in this case with the direct content:
<
t:RadToolBarTray
e:RadToolBarTrayExtensions.ItemsSource
=
"{Binding Items}"
VerticalAlignment
=
"Center"
>
<
t:RadToolBarTray.ItemTemplate
>
<
DataTemplate
DataType
=
"vm:MenuViewModel"
>
<!-- <t:RadToolBar ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ToolBarItemTemplate}" />-->
<
t:RadToolBar
>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Never"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Never"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Never"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Never"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"AsNeeded"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Always"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Always"
/>
<
t:RadButton
Content
=
"Button!"
t:RadToolBar.OverflowMode
=
"Always"
/>
</
t:RadToolBar
>
</
DataTemplate
>
</
t:RadToolBarTray.ItemTemplate
>
</
t:RadToolBarTray
>
I has adapted the next code for RadToolBar from this post:
It use attached ItemsSource instead of RadToolBar's ItemsSource and manually sets the OverflowMode to itemContainer from RadToolBar.ItemContainerStyle.
public
class
RadToolBarExtensions
{
private
static
readonly
DependencyProperty ItemsSourceProperty =
DependencyProperty.RegisterAttached(
"ItemsSource"
,
typeof
(IEnumerable),
typeof
(RadToolBarExtensions),
new
PropertyMetadata(OnItemsSourceChanged));
private
static
readonly
DependencyProperty ToolBarExtensionsProperty =
DependencyProperty.RegisterAttached(
"ToolBarExtensions"
,
typeof
(RadToolBarExtensions),
typeof
(RadToolBarExtensions),
new
PropertyMetadata(
null
));
private
readonly
RadToolBar _toolBar;
private
RadToolBarExtensions(RadToolBar toolBar)
{
_toolBar = toolBar;
}
public
static
IEnumerable GetItemsSource(DependencyObject d)
{
return
(IEnumerable)d.GetValue(ItemsSourceProperty);
}
public
static
void
SetItemsSource(DependencyObject d, IEnumerable value)
{
d.SetValue(ItemsSourceProperty, value);
}
private
static
RadToolBarExtensions GetToolBarExtensions(DependencyObject d)
{
return
(RadToolBarExtensions)d.GetValue(ToolBarExtensionsProperty);
}
private
static
void
SetToolBarExtensions(DependencyObject d, RadToolBarExtensions value)
{
d.SetValue(ToolBarExtensionsProperty, value);
}
private
static
void
OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var toolBar = (RadToolBar)d;
var extensions = GetToolBarExtensions(toolBar);
if
(extensions ==
null
)
{
extensions =
new
RadToolBarExtensions(toolBar);
SetToolBarExtensions(toolBar, extensions);
}
if
(e.OldValue !=
null
)
{
toolBar.Items.Clear();
var ncc = e.OldValue
as
INotifyCollectionChanged;
if
(ncc !=
null
)
ncc.CollectionChanged -= extensions.OnCollectionChanged;
}
if
(e.NewValue !=
null
)
{
foreach
(var item
in
(IEnumerable)e.NewValue)
{
toolBar.Items.Add(GenerateItemContainer(item, toolBar.ItemTemplate, toolBar.ItemContainerStyle));
}
var ncc = e.NewValue
as
INotifyCollectionChanged;
if
(ncc !=
null
)
ncc.CollectionChanged += extensions.OnCollectionChanged;
}
}
// OverflowMode settings is here.
//
private
static
FrameworkElement GenerateItemContainer(
object
dataItem, DataTemplate template, Style itemContainerStyle)
{
if
(template ==
null
)
throw
new
ArgumentNullException(
"template"
);
var itemContainer = (FrameworkElement) template.LoadContent();
itemContainer.DataContext = dataItem;
itemContainer.Style = itemContainerStyle;
if
(itemContainerStyle !=
null
)
{
var overflowModeSetter =
itemContainerStyle.Setters.OfType<Setter>().FirstOrDefault(
x => x.Property == RadToolBar.OverflowModeProperty);
if
(overflowModeSetter !=
null
)
{
var value = overflowModeSetter.Value;
if
(value
is
Binding)
itemContainer.SetBinding(RadToolBar.OverflowModeProperty, (Binding) overflowModeSetter.Value);
else
if
(value
is
OverflowMode)
RadToolBar.SetOverflowMode(itemContainer, (OverflowMode) value);
}
}
return
itemContainer;
}
private
void
OnCollectionChanged(
object
sender, NotifyCollectionChangedEventArgs e)
{
if
(e.OldItems !=
null
)
{
foreach
(var oldItem
in
e.OldItems)
{
var itemContainer =
_toolBar.Items.OfType<FrameworkElement>().FirstOrDefault(x => x.DataContext == oldItem);
if
(itemContainer !=
null
)
_toolBar.Items.Remove(itemContainer);
}
}
if
(e.NewItems !=
null
)
{
foreach
(var newItem
in
e.NewItems)
{
_toolBar.Items.Add(GenerateItemContainer(newItem, _toolBar.ItemTemplate, _toolBar.ItemContainerStyle));
}
}
if
(e.Action == NotifyCollectionChangedAction.Reset)
_toolBar.Items.Clear();
}
}
Usage:
<
t:RadToolBarTray
e:RadToolBarTrayExtensions.ItemsSource
=
"{Binding Items}"
VerticalAlignment
=
"Center"
>
<
t:RadToolBarTray.ItemTemplate
>
<
DataTemplate
DataType
=
"vm:MenuViewModel"
>
<
t:RadToolBar
e:RadToolBarExtensions.ItemsSource
=
"{Binding Items}"
ItemTemplate
=
"{StaticResource ToolBarItemTemplate}"
>
<
t:RadToolBar.ItemContainerStyle
>
<
Style
TargetType
=
"DependencyObject"
>
<
Setter
Property
=
"t:RadToolBar.OverflowMode"
Value
=
"{Binding OverflowMode}"
/>
</
Style
>
</
t:RadToolBar.ItemContainerStyle
>
</
t:RadToolBar
>
</
DataTemplate
>
</
t:RadToolBarTray.ItemTemplate
>
</
t:RadToolBarTray
>
Maybe there is more simple built-in solution of this problem? :)
Thank you for sharing your solution.
The described behavior is a limitation of the control and there is no built-in solution which I can offer you. I logged it in our feedback portal. I also updated your Telerik points as a small gesture of gratitude for reporting this.
Regards,
Martin
Telerik
Modified solution, respects the ItemsControl.ItemTemplateSelector if ItemsControl.ItemTemplate is not setted.
Found strange issue:
- ToolBarContainerStyleSelector in Windows8Touch theme style of RadToolBar doesn't apply it's defined ContainerStyle to type "RadToolBarSeparator", when RadToolBar.ItemContainerStyle is setted to style with "OverflowMode" as writen before. But it applies styles of ToolBarRadButtonStyle and ToolBarRadToggleButtonStyle anyway as defined in theme (current ItemContainerStyle ignored for buttons within this extension).
So, I moved setter from style to the attached RadToolBarExtensions.ItemOverflowModeProperty, which supports binding (current item's context).
Magically, now it works fine:
public
class
RadToolBarExtensions
{
private
static
readonly
DependencyProperty ItemsSourceProperty =
DependencyProperty.RegisterAttached(
"ItemsSource"
,
typeof
(IEnumerable),
typeof
(RadToolBarExtensions),
new
PropertyMetadata(OnItemsSourceChanged));
private
static
readonly
DependencyProperty ItemOverflowModeProperty =
DependencyProperty.RegisterAttached(
"ItemOverflowMode"
,
typeof
(
object
),
typeof
(RadToolBarTrayExtensions),
new
PropertyMetadata(
null
));
private
static
readonly
DependencyProperty ToolBarExtensionsProperty =
DependencyProperty.RegisterAttached(
"ToolBarExtensions"
,
typeof
(RadToolBarExtensions),
typeof
(RadToolBarExtensions),
new
PropertyMetadata(
null
));
private
readonly
RadToolBar _toolBar;
private
RadToolBarExtensions(RadToolBar toolBar)
{
_toolBar = toolBar;
}
public
static
IEnumerable GetItemsSource(DependencyObject d)
{
return
(IEnumerable)d.GetValue(ItemsSourceProperty);
}
public
static
void
SetItemsSource(DependencyObject d, IEnumerable value)
{
d.SetValue(ItemsSourceProperty, value);
}
public
static
object
GetItemOverflowMode(DependencyObject d)
{
return
d.GetValue(ItemOverflowModeProperty);
}
public
static
void
SetItemOverflowMode(DependencyObject d,
object
value)
{
d.SetValue(ItemOverflowModeProperty, value);
}
private
static
RadToolBarExtensions GetToolBarExtensions(DependencyObject d)
{
return
(RadToolBarExtensions)d.GetValue(ToolBarExtensionsProperty);
}
private
static
void
SetToolBarExtensions(DependencyObject d, RadToolBarExtensions value)
{
d.SetValue(ToolBarExtensionsProperty, value);
}
private
static
void
OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var toolBar = (RadToolBar)d;
var extensions = GetToolBarExtensions(toolBar);
if
(extensions ==
null
)
{
extensions =
new
RadToolBarExtensions(toolBar);
SetToolBarExtensions(toolBar, extensions);
}
if
(e.OldValue !=
null
)
{
toolBar.Items.Clear();
var ncc = e.OldValue
as
INotifyCollectionChanged;
if
(ncc !=
null
)
ncc.CollectionChanged -= extensions.OnCollectionChanged;
}
if
(e.NewValue !=
null
)
{
foreach
(var item
in
(IEnumerable)e.NewValue)
{
toolBar.Items.Add(GenerateItemContainer(item, toolBar));
}
var ncc = e.NewValue
as
INotifyCollectionChanged;
if
(ncc !=
null
)
ncc.CollectionChanged += extensions.OnCollectionChanged;
}
}
private
static
FrameworkElement GenerateItemContainer(
object
dataItem, ItemsControl toolBar)
{
var itemTemplate = toolBar.ItemTemplate;
var itemTemplateSelector = toolBar.ItemTemplateSelector;
if
(itemTemplate ==
null
&& itemTemplateSelector !=
null
)
itemTemplate = itemTemplateSelector.SelectTemplate(dataItem, toolBar);
if
(itemTemplate ==
null
)
return
null
;
var itemContainer = (FrameworkElement) itemTemplate.LoadContent();
itemContainer.DataContext = dataItem;
var overflowProperty = GetItemOverflowMode(toolBar);
if
(overflowProperty !=
null
)
{
if
(overflowProperty
is
Binding)
itemContainer.SetBinding(RadToolBar.OverflowModeProperty, (Binding) overflowProperty);
else
if
(overflowProperty
is
OverflowMode)
RadToolBar.SetOverflowMode(itemContainer, (OverflowMode) overflowProperty);
}
return
itemContainer;
}
private
void
OnCollectionChanged(
object
sender, NotifyCollectionChangedEventArgs e)
{
if
(e.OldItems !=
null
)
{
foreach
(var oldItem
in
e.OldItems)
{
var itemContainer =
_toolBar.Items.OfType<FrameworkElement>().FirstOrDefault(x => x.DataContext == oldItem);
if
(itemContainer !=
null
)
_toolBar.Items.Remove(itemContainer);
}
}
if
(e.NewItems !=
null
)
{
foreach
(var newItem
in
e.NewItems)
{
_toolBar.Items.Add(GenerateItemContainer(newItem, _toolBar));
}
}
if
(e.Action == NotifyCollectionChangedAction.Reset)
_toolBar.Items.Clear();
}
}
Usage:
<!-- fragment -->
<
c:ItemTemplateSelector
x:Key
=
"ToolBarItemTemplateSelector"
>
<
c:ItemTemplateRule
DataType
=
"vm:SeparatorMenuItem"
DataTemplate
=
"{StaticResource SeparatorMenuItemTemplate}"
/>
<
c:ItemTemplateRule
DataType
=
"vm:RadioMenuItemViewModel"
DataTemplate
=
"{StaticResource RadioMenuItemTemplate}"
/>
<
c:ItemTemplateRule
DataType
=
"vm:CheckMenuItemViewModel"
DataTemplate
=
"{StaticResource CheckMenuItemTemplate}"
/>
<
c:ItemTemplateRule
DataType
=
"vm:MenuItemViewModel"
DataTemplate
=
"{StaticResource MenuItemTemplate}"
/>
</
c:ItemTemplateSelector
>
</
UserControl.Resources
>
<
t:RadToolBarTray
e:RadToolBarTrayExtensions.ItemsSource
=
"{Binding Items}"
VerticalAlignment
=
"Center"
>
<
t:RadToolBarTray.ItemTemplate
>
<
DataTemplate
DataType
=
"vm:MenuViewModel"
>
<
t:RadToolBar
e:RadToolBarExtensions.ItemOverflowMode
=
"{Binding OverflowMode}"
e:RadToolBarExtensions.ItemsSource
=
"{Binding Items}"
ItemTemplateSelector
=
"{StaticResource ToolBarItemTemplateSelector}"
>
</
t:RadToolBar
>
</
DataTemplate
>
</
t:RadToolBarTray.ItemTemplate
>
</
t:RadToolBarTray
>