Search code examples
wpflocalizationcontrolsscrollbarcontextmenu

How to get default localization for custom context menu of ScrollBar like the default context menu?


I have succesfully created a fully working context menu for the scrollbar control by following this question: WPF - How to replace the scrollbar ContextMenu

The problem is that the new context menu is always in English, when the original context menu is auto translated (in my case in Italian).

I know that I can use ApplicationCommands for auto translate the menus (for example Cut, Copy, Paste in textboxes), but I was not able to find any commands for scrollbars.

Here a copy of the contextmenu for reference:

<ContextMenu x:Key="VScrollBarContextMenu" x:Shared="true">
    <MenuItem Header="Scroll _Here" Command="ScrollBar.ScrollHereCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
    <Separator/>
    <MenuItem Header="_Top" Command="ScrollBar.ScrollToTopCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
    <MenuItem Header="_Bottom" Command="ScrollBar.ScrollToBottomCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
    <Separator/>
    <MenuItem Header="Page _Up" Command="ScrollBar.PageUpCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
    <MenuItem Header="Page _Down" Command="ScrollBar.PageDownCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
    <Separator/>
    <MenuItem Header="Scroll U_p" Command="ScrollBar.LineUpCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
    <MenuItem Header="Scroll Dow_n" Command="ScrollBar.LineDownCommand" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
</ContextMenu>

Just place the menu in the style.

<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Style.Triggers>
        <Trigger Property="Orientation" Value="Horizontal">
            <Setter Property="Width" Value="Auto"/>
            <Setter Property="Height" Value="18"/>
            <Setter Property="ContextMenu" Value="{DynamicResource HScrollBarContextMenu}"/>
            <Setter Property="Template" Value="{StaticResource HorizontalScrollBar}"/>
        </Trigger>
        <Trigger Property="Orientation" Value="Vertical">
            <Setter Property="Width" Value="18"/>
            <Setter Property="Height" Value="Auto"/>
            <Setter Property="ContextMenu" Value="{DynamicResource VScrollBarContextMenu}"/>
            <Setter Property="Template" Value="{StaticResource VerticalScrollBar}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Original menu

original-menu

Reworked menu

reworked-menu


Solution

  • A MenuItem of the default ContextMenu gets its Header value from the resources in the language packs which you can see in the source code:

    private static ContextMenu VerticalContextMenu
    {
        get
        {
            ContextMenu verticalContextMenu = new ContextMenu();
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollHere, "ScrollHere", ScrollBar.ScrollHereCommand));
            verticalContextMenu.Items.Add(new Separator());
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_Top, "Top", ScrollBar.ScrollToTopCommand));
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_Bottom, "Bottom", ScrollBar.ScrollToBottomCommand));
            verticalContextMenu.Items.Add(new Separator());
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageUp, "PageUp", ScrollBar.PageUpCommand));
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageDown, "PageDown", ScrollBar.PageDownCommand));
            verticalContextMenu.Items.Add(new Separator());
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollUp, "ScrollUp", ScrollBar.LineUpCommand));
            verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollDown, "ScrollDown", ScrollBar.LineDownCommand));
            return verticalContextMenu;
        }
    }
    

    These are internal so you cannot bind to them. If you create your own custom ContextMenu, you need to define the translations yourself.