Search code examples
c#wpfmodern-ui

WPF Metro UI - LinkGroup horizontal scrolling issue


I have WPF app with Metro UI. Main window opens on full screen. Top of it I have MenuLinkGroup which looks something like this :

 <mui:ModernWindow.MenuLinkGroups>
        <mui:LinkGroup DisplayName="FirstGroup">
            <mui:LinkGroup.Links>
                <mui:Link DisplayName="Very long description" Source=""/>
                <mui:Link DisplayName="Very long description" Source=""/>
            </mui:LinkGroup.Links>
        </mui:LinkGroup>
        <mui:LinkGroup DisplayName="SecondGroup">
            <mui:LinkGroup.Links>
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
            </mui:LinkGroup.Links>
        </mui:LinkGroup>
        <mui:LinkGroup DisplayName="ThirdGroup">
            <mui:LinkGroup.Links>
                <mui:Link DisplayName="Very long description" Source="" />
                <mui:Link DisplayName="Very long description" Source="" />
            </mui:LinkGroup.Links>
        </mui:LinkGroup>
</mui:ModernWindow.MenuLinkGroups>

Main problem is, wheen user has small monitor, than he cant's see all Names from SecondGroup, and he can't easly navigate tchem with mouse cursor.

My question: is there any to put some of scroll or mayby a wrap, wheen screen is too small ?


Solution

  • To fix the layout of menu in FirstFloor.ModernUI you need to write new wpf style for ModernMenu control to override the default layout. The default style code may be found on the project github page https://github.com/firstfloorsoftware/mui/blob/master/1.0/FirstFloor.ModernUI/Shared/Themes/ModernMenu.xaml. In your application, for instance in App.xaml add reference to ModernMenu class namespace:

    xmlns:firstfloor="clr-namespace:FirstFloor.ModernUI.Windows.Controls;assembly=FirstFloor.ModernUI"
    

    And then in resource define new default style:

    <Style TargetType="firstfloor:ModernMenu"></Style>
    

    The crucial points to change to have wrapped menu is to change 2 listboxes ItemsPanel from StackPanel to WrapPanel and to set property ScrollViewer.HorizontalScrollBarVisibility="Disabled". After these changes your style should look like this:

    <Style TargetType="firstfloor:ModernMenu">
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="firstfloor:ModernMenu">
                    <Grid>
                        <Grid.Resources>
                            <Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
                                <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
                                <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                                <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
                            </Style>
                        </Grid.Resources>
    
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
    
                        <ListBox ItemsSource="{TemplateBinding VisibleLinkGroups}"
                                 ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                                 SelectedItem="{Binding SelectedLinkGroup, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
                            <ListBox.ItemContainerStyle>
                                <Style TargetType="ListBoxItem">
                                    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
                                    <Setter Property="FontFamily" Value="Segoe UI Light" />
                                    <Setter Property="Foreground" Value="{DynamicResource MenuText}" />
                                    <Setter Property="FontSize" Value="23"/>
                                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                                    <Setter Property="VerticalContentAlignment" Value="Center" />
                                    <Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
                                    <Setter Property="Margin" Value="0,0,12,0" />
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="ListBoxItem">
                                                <TextBlock DataContext="{TemplateBinding Content}"
                                                           Text="{Binding DisplayName, Converter={StaticResource ToLowerConverter}}"
                                                           HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                           VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                           SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                                <ControlTemplate.Triggers>
                                                    <Trigger Property="IsMouseOver" Value="true">
                                                        <Setter Property="Foreground" Value="{DynamicResource MenuTextHover}"/>
                                                    </Trigger>
                                                    <Trigger Property="IsSelected" Value="true">
                                                        <Setter Property="Foreground" Value="{DynamicResource MenuTextSelected}"/>
                                                    </Trigger>
                                                </ControlTemplate.Triggers>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </ListBox.ItemContainerStyle>
                            <ListBox.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel Orientation="Horizontal" />
                                </ItemsPanelTemplate>
                            </ListBox.ItemsPanel>
                        </ListBox>
    
                        <ListBox Grid.Row="1"
                                 ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                                 ItemsSource="{Binding SelectedLinkGroup.Links, RelativeSource={RelativeSource TemplatedParent}}"
                                 SelectedItem="{Binding SelectedLink, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                                 VerticalAlignment="Top">
                            <ListBox.ItemContainerStyle>
                                <Style TargetType="ListBoxItem">
                                    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
                                    <Setter Property="FontFamily" Value="Segoe UI" />
                                    <Setter Property="Foreground" Value="{DynamicResource SubMenuText}" />
                                    <Setter Property="FontSize" Value="11"/>
                                    <Setter Property="Margin" Value="0,0,12,0" />
                                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                                    <Setter Property="VerticalContentAlignment" Value="Center" />
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="ListBoxItem">
                                                <Grid DataContext="{TemplateBinding Content}"
                                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                                                    <TextBlock Text="{Binding DisplayName, Converter={StaticResource ToUpperConverter}}" TextAlignment="Center"/>
                                                    <TextBlock Text="{Binding DisplayName, Converter={StaticResource ToUpperConverter}}" FontWeight="Bold" Visibility="Hidden" />
                                                </Grid>
    
                                                <ControlTemplate.Triggers>
                                                    <Trigger Property="IsMouseOver" Value="true">
                                                        <Setter Property="Foreground" Value="{DynamicResource SubMenuTextHover}"/>
                                                    </Trigger>
                                                    <Trigger Property="IsSelected" Value="true">
                                                        <Setter Property="Foreground" Value="{DynamicResource SubMenuTextSelected}"/>
                                                        <Setter Property="FontWeight" Value="Bold" />
                                                    </Trigger>
                                                </ControlTemplate.Triggers>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </ListBox.ItemContainerStyle>
                            <ListBox.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel Orientation="Horizontal" />
                                </ItemsPanelTemplate>
                            </ListBox.ItemsPanel>
                        </ListBox>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>