dr11
dr11

Reputation: 5756

Add scrollability to MenuItem in a Style

I'd like to create a style for my menus. In case if there are more that X elements there should appear a scrollbar in a menu (to scroll all menu items). At the moment my style is:

<MenuItem.Resources>
    <!--From BFR, need to retrieve from SDK-->
    <Style x:Key="HierarchyDynamicMenuStyle" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
                    <Setter Property="Header" Value="{Binding Path=Header}" />
                    <Setter Property="Command" Value="{Binding Command}"/>
                    <Setter Property="CommandParameter" Value="{Binding Path=CommandParameter}"/>
                    <Setter Property="ItemsSource" Value="{Binding Children}"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template" >
            <Setter.Value>
                <ControlTemplate>
                    <ScrollViewer>
                      <ContentPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</MenuItem.Resources>

And now i'm adding a new menu:

<MenuItem Header="My menu with scrollbar" Style="{StaticResource HierarchyDynamicMenuStyle}" ItemsSource="{Binding MyItems}"></MenuItem>

Could you please help me with a template? There can be some height constraint for scrollbar, or items count, etc.

Upvotes: 0

Views: 1310

Answers (3)

dr11
dr11

Reputation: 5756

In case somebody looks an example for the same question:

<MenuItem.Resources>
    <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type FrameworkElement}, ResourceId=MenuScrollViewer}"
       TargetType="{x:Type ScrollViewer}" BasedOn="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type FrameworkElement}, ResourceId=MenuScrollViewer}}">
        <Setter Property="MaxHeight" Value="480"/>
    </Style>

    <!--From BFR, need to retrieve from SDK-->
    <Style x:Key="HierarchicalDynamicMenuStyle" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
                    <Setter Property="Header" Value="{Binding Path=Header}" />
                    <Setter Property="Command" Value="{Binding Command}"/>
                    <Setter Property="CommandParameter" Value="{Binding Path=CommandParameter}"/>
                    <Setter Property="ItemsSource" Value="{Binding Children}"/>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>
</MenuItem.Resources>

where 480 is a max height of the scrollable area

And this is an example of menu node for hierarchy:

public class HierarchyMenuItem : NotificationObject
{
    public ICommand Command { get; set; }
    public string Header { get; set; }
    public string CommandParameter { get; set; }

    public ObservableCollection<HierarchyMenuItem> Children { get; set; }
}   

Upvotes: 1

Armen Mkrtchyan
Armen Mkrtchyan

Reputation: 921

take a look at this. You must change menu control' ItemsPanel (i think, it is wrapPanel)

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <Menu>
            <MenuItem Header="Hello"></MenuItem>
            <MenuItem Header="Bye"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="Alex"></MenuItem>
            <MenuItem Header="John"></MenuItem>
            <Menu.ItemsPanel>
                <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"></StackPanel>
                </ItemsPanelTemplate>
            </Menu.ItemsPanel>
            <Menu.Template>
                <ControlTemplate>
                    <ScrollViewer HorizontalScrollBarVisibility="Auto" x:Name="ScrollViewer" >
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </Menu.Template>
        </Menu>

    </Grid>
</Window>

Upvotes: 0

Armen Mkrtchyan
Armen Mkrtchyan

Reputation: 921

 <Setter Property="Template" >
            <Setter.Value>
                <ControlTemplate>
                    <ScrollViewer>
                      <ContentPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

Upvotes: 0

Related Questions