Pergunta

Eu tenho um menu (com menuitems) em WPF. Infelizmente, quando eu clicar sobre o título de menu que abre o menu à direita. O problema é que há coisas à direita que eu não quero que se sobrepõem. Como eu digo WPF para abrir o menu à esquerda? Preciso fazer um modelo de controle? (Modelos de controle parecem tão pesado entregou para tais mudanças de estilo básico).

Obrigado!

KSG

Foi útil?

Solução

Enquanto você pode criar um ControlTemplate para fazer isso como eles fazem aqui , concordo que é um método complicado apenas para modificar um valor em uma parte dos MenuItems. Em vez disso, eu acho que este é um ótimo lugar para usar um AttachedProperty. Podemos criar algo como o ContextMenuService , mas para Popups (na verdade, estou um pouco surpreso que ele não está embutido).

Para alterar onde o contexto é de abertura, vamos querer definir PlacementMode do Popup. Podemos usar o atalho propa para gerar nossos AttachedProperty (ou propriedades se você deseja implementar o resto). Precisamos adicionar uma chamada de retorno para o nosso PropertyMetadata, mas se o AttachedProperty é definido em linha no controle em XAML, em seguida, a chamada de retorno irá disparar antes de todo o controle é totalmente construído. Para garantir o modelo do MenuItem é aplicada, eo Popup existe antes de tentar configurá-lo de valor, podemos apenas anexar ao evento Loaded se ele já não está carregado. Uma vez que ele é carregado, queremos recuperar o Popup do modelo, e se olharmos para o classe MenuItem podemos ver que ele tem um TemplatePartAttribute definir o nome do Popup como 'PART_Popup'. Assim que tivermos isso, podemos definir o PlacementMode em Popup do MenuItem.

    public static PlacementMode GetMenuPlacement(DependencyObject obj)
    {
        return (PlacementMode)obj.GetValue(MenuPlacementProperty);
    }

    public static void SetMenuPlacement(DependencyObject obj, PlacementMode value)
    {
        obj.SetValue(MenuPlacementProperty, value);
    }

    // Using a DependencyProperty as the backing store for MenuPlacement.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MenuPlacementProperty =
        DependencyProperty.RegisterAttached("MenuPlacement",
        typeof(PlacementMode),
        typeof(Window1),
        new FrameworkPropertyMetadata(PlacementMode.Bottom, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnMenuPlacementChanged)));

    private static void OnMenuPlacementChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var menuItem = o as MenuItem;
        if (menuItem != null)
        {
            if (menuItem.IsLoaded)
            {
                SetPopupPlacement(menuItem, (PlacementMode)e.NewValue);
            }
            else
            {
                menuItem.Loaded += new RoutedEventHandler((m, v) => SetPopupPlacement(menuItem, (PlacementMode)e.NewValue));
            }
        }
    }

    private static void SetPopupPlacement(MenuItem menuItem, PlacementMode placementMode)
    {
        Popup popup = menuItem.Template.FindName("PART_Popup", menuItem) as Popup;
        if (popup != null)
        {
            popup.Placement = placementMode;
        }
    }

Agora que temos o nosso AttachedProperty, é fácil alterar o posicionamento Popup na interface do usuário.

<Menu>
    <MenuItem Header="Item 1"
              local:Window1.MenuPlacement="Right">
        <MenuItem Header="SubItem 1" />
        <MenuItem Header="SubItem 2" />
        <MenuItem Header="SubItem 3" />
        <MenuItem Header="SubItem 4" />
    </MenuItem>
    <MenuItem Header="Item 2"
              local:Window1.MenuPlacement="Left">
        <MenuItem Header="SubItem 5" />
        <MenuItem Header="SubItem 6" />
        <MenuItem Header="SubItem 7" />
        <MenuItem Header="SubItem 8" />
    </MenuItem>
    <MenuItem Header="Item 3"
              local:Window1.MenuPlacement="Mouse">
        <MenuItem Header="SubItem 9" />
        <MenuItem Header="SubItem 10" />
        <MenuItem Header="SubItem 11" />
        <MenuItem Header="SubItem 12" />
    </MenuItem>
</Menu>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top