WPF ToolBar: como remover aderência e estouro

98

Em um WPF ToolBarPanel-ToolBar-Menu aninhado, queremos nos livrar da alça à esquerda e da área de estouro à direita. ambos estão acinzentados, mas gostaríamos que não fossem exibidos.

alguma ideia de como fazer isso?

apenas no caso de meus termos não estarem totalmente corretos, se você olhar para a imagem na Figura 3 do link abaixo, na parte inferior das três barras de ferramentas está a alça à esquerda da lista suspensa e à direita da mais à direita botão há o estouro.

Imagem de barras de ferramentas

Tom
fonte
Você provavelmente poderia fazer isso substituindo o modelo de controle ... mas eu não recomendo.
apandit
Você pode colocar Margin = "0,0, -14,0" na Barra de Ferramentas para empurrar o lado direito para fora de vista. Esta é a solução mais fácil que encontrei, mas só testei com um único ToolBar, não dentro de um ToolBarPanel ou ToolBarTray.
Wayne Bloss,

Respostas:

153

A alça pode ser removida definindo a propriedade anexada ToolBarTray.IsLocked="True"na Barra de Ferramentas.

Para remover o Overflow ToggleButton , você terá que removê-lo em um ControlTemplate personalizado, conforme seis variáveis ​​de letras sugerem, o que, se você tiver blend ou puder baixar o Blend 3 Preview, não é excessivamente difícil.

Você também pode simplesmente ocultar o botão no evento carregado da Barra de Ferramentas, embora seja qual for a rota que você tomar, você também deve definir a propriedade anexada ToolBar.OverflowMode="Never"no menu da Barra de Ferramentas, para que os itens não possam transbordar acidentalmente para uma área inacessível.

<ToolBarPanel DockPanel.Dock="Top">
    <ToolBar ToolBarTray.IsLocked="True" Loaded="ToolBar_Loaded">
        <Menu ToolBar.OverflowMode="Never">
            <MenuItem Header="File" />
            <MenuItem Header="New" />
        </Menu>
    </ToolBar>
</ToolBarPanel>

E defina o Overflow ToggleButton para recolhido:

private void ToolBar_Loaded(object sender, RoutedEventArgs e)
{
    ToolBar toolBar = sender as ToolBar;
    var overflowGrid = toolBar.Template.FindName("OverflowGrid", toolBar) as FrameworkElement;
    if (overflowGrid != null)
    {
        overflowGrid.Visibility = Visibility.Collapsed;
    }
    var mainPanelBorder = toolBar.Template.FindName("MainPanelBorder", toolBar) as FrameworkElement;
    if (mainPanelBorder != null)
    {
        mainPanelBorder.Margin = new Thickness();
    }
}
rmoore
fonte
15
Surge a pergunta: Por que usar uma barra de ferramentas? Por que não usar um StackPanel simples com botões? Qual benefício o ToolBar oferece?
Josh G
5
Em resposta a Josh G: Se você usar um botão transparente com uma imagem em um painel normal (StackPanel etc), ele terá um contorno branco. Quando o mesmo botão é colocado em uma barra de ferramentas, o contorno branco não está presente.
Chris Bennet,
2
Isso também é útil se você quiser o tema de uma barra de ferramentas neste contexto, por exemplo, o comportamento do mouseover.
Greg D,
36
Para sua informação: você pode usar um StackPanel simples e ainda obter o estilo da Barra de Ferramentas. <Button Style = "{StaticResource {x: Static ToolBar.ButtonStyleKey}}"> <Image Source = "{StaticResource ZoomIn}"> </Image> </Button>
thrag
1
Além disso, descobri que se você não quiser usar o controle <Menu> na barra de ferramentas, a propriedade ToolBar.OverflowMode = "Nunca" pode ser definida diretamente no controle <Button> na barra de ferramentas. Isso criou o efeito que eu estava procurando
ford
8

Você pode usar o Blend para simplesmente substituir o ControlTemplate para ToolBarPanel, Menu ou ToolBar.

  1. Clique com o botão direito na barra de ferramentas e selecione Editar modelo
  2. Em Editar modelo, selecione Editar uma cópia
  3. Eu recomendo adicionar a cópia a um Dicionário de Recursos
  4. Clique OK

Agora você estará editando o modelo de controle para o ToolBarPanel e pode definir a visibilidade como Recolhido para o sinal de alça e estouro. Você pode enxaguar e repetir para os outros controles. É um pouco demorado, mas não é terrivelmente difícil com o Blend.

user7116
fonte
Obrigado pela informação. infelizmente blend2 e vs2008 não parecem funcionar bem juntos para nós, muitos problemas quando um trabalha com o código gerado no outro, então atualmente não permitimos que o blend chegue perto de nosso código vs;)
Tom
1
Sim, usamos o Blend religiosamente até o surgimento do VS2k8SP1. Na verdade, eu meio que desejo o editor WPF no VS2k8 WAS Blend. Muito melhor ser capaz de clicar com o botão direito em algo e dizer Group Into 'StackPanel' ou 'Borda'. Pena que a MS deseja que sejam experiências diferentes.
user7116
Acho que o novo XAML Power Toys adiciona um recurso que permite agrupar controles. (Talvez seja o MoXAML Poder Brinquedos ...)
Number8
8

Você pode "remover" o estouro sem fornecer um novo modelo de controle, definindo o ToolBarpara ter margens direitas negativas (e adicionar uma margem esquerda negativa para que não pareça estranho com bordas esquerdas arredondadas, mas bordas direitas quadradas). Em seguida, adicione ClipToBounds="True"ao ToolBarPanelque cortará as bordas da barra de ferramentas que agora estão fora da área do painel.

<ToolBarPanel Grid.Row="0" ClipToBounds="True">
    <ToolBar ToolBarTray.IsLocked="True" Margin="-5,0,-13,0" Padding="5,0,0,0">
    . . .
John Fisher
fonte
5

Em vez de ocultar o botão de estouro completamente, acho melhor mostrá-lo apenas quando necessário. Isso pode ser feito vinculando sua Visibilitypropriedade à sua IsEnabledpropriedade:

private static void FixupToolBarOverflowArrow(ToolBar toolBar)
{
    Action fixup = () =>
    {
        var overflowButton = toolBar.Template.FindName("OverflowButton", toolBar) as ButtonBase;
        if (overflowButton != null)
        {
            overflowButton.SetBinding(
                VisibilityProperty,
                new Binding("IsEnabled")
                {
                    RelativeSource = RelativeSource.Self,
                    Converter = new BooleanToVisibilityConverter()
                });
        }
    };

    if (toolBar.IsLoaded)
    {
        fixup();
    }
    else
    {
        RoutedEventHandler handler = null;
        handler = (sender, e) =>
        {
            fixup();
            toolBar.Loaded -= handler;
        };

        toolBar.Loaded += handler;
    }
}

(a mesma coisa pode ser feita em XAML redefinindo o modelo)

Thomas Levesque
fonte
3

Estou apenas começando com o WPF e não consegui nenhum dos métodos acima para ocultar minha seta de estouro (Visual Studio 2010). A única coisa que pareceu afetar a seta foi o exemplo Toolbar_Load acima, mas tudo o que fez foi transformar a seta em um espaço vazio que parecia tão ruim quanto a flecha. A maneira mais fácil que eu consegui descobrir foi simplesmente definir as margens da barra de ferramentas.

<ToolBar Height="26" 
         Name="toolBar" 
         DockPanel.Dock="Top" 
         ToolBarTray.IsLocked="True" 
         ToolBar.OverflowMode="Never"        <!-- no effect -->
         Margin="0,0,-13,0">                 <!-- worked -->
         <Menu ToolBar.OverflowMode="Never"> <!-- no affect -->
             <MenuItem Header="_File"></MenuItem>
         </Menu>
</ToolBar>
Belmiris
fonte
0

Os métodos acima funcionam para ocultar o estouro; Usei o seguinte para ocultar a garra:

         <Label Height="44" Width="30" Background="{StaticResource CtrlBackground}" Margin="-20,0,0,0"></Label>

para um layout horizontal, e

         <Label Height="44" Width="230" Background="{StaticResource CtrlBackground}" Margin="0,-20,0,0" HorizontalAlignment="Left"></Label>

para um layout vertical. Coloque o acima após a barra de ferramentas (ou ToolbarTray, se estiver usando)

Use a largura e a altura necessárias para seus botões.

Kaxaml é excelente para brincar com essas coisas.

frediano
fonte