2010-02-04 24 views
11

¿Es posible hacer que los elementos dentro de una barra de herramientas de WPF tengan una alineación horizontal de derecha?Elementos de la barra de herramientas de WPF HorizontalAligment = "Right"

<ToolBar Height="38" VerticalAlignment="Top" Grid.Row="1"> 
    <Button HorizontalAlignment="Left" Width="50" VerticalAlignment="Stretch"/> 
    <Button HorizontalAlignment="Left" Width="50" VerticalAlignment="Stretch"/> 
    <ComboBox Width="120" HorizontalAlignment="Right"/> 
</ToolBar> 

He intentado añadir los elementos en el interior en una rejilla y la asignación de los ColumnDefinition s a izquierda/derecha también. También probé un StackPanel. No importa lo que intento, parece que no puedo hacer que el ComboBox esté "anclado" en el lado derecho de la barra de herramientas.

ACTUALIZACIÓN:

<DockPanel LastChildFill="True"> 

no funciona, no se llenará el elemento de barra de herramientas como lo haría un elemento normal.

Respuesta

15

Investigaciones posteriores mostraron que con el fin de hacer esto necesito fijar la anchura de un Grid dentro de la ToolBar, o como dijo Chris Nicol, un DockPanel dentro de la ToolBar dinámicamente a la de la anchura de la Toolbar usando RelativeSource.

Sin embargo, esto no se siente como una solución limpia. Es bastante complicado obtener el Toolbar para actualizar correctamente al redimensionar. Así que, en cambio, encontré algo así como un truco que se ve y funciona de manera más limpia.

<ToolBar Height="38" VerticalAlignment="Top" Grid.Row="1"> 
    <Button HorizontalAlignment="Left" Width="50" VerticalAlignment="Stretch"/> 
    <Button HorizontalAlignment="Left" Width="50" VerticalAlignment="Stretch"/> 
</ToolBar> 

<ComboBox Margin="0,0,15,0" Width="120" HorizontalAlignment="Right" Grid.Row="1"/> 

Dado que todos mis elementos están en una cuadrícula, puedo poner mi ComboBox en la parte superior de la ToolBar mediante la asignación es Grid.Row a la misma fila que la barra de herramientas. Después de configurar mi Margins para extraer el ComboBox ligeramente para no interferir con la apariencia, funciona según sea necesario sin errores. Dado que la única otra manera que encontré para hacer esto fue establecer dinámicamente una propiedad de DockPanel/Grid's Width, realmente siento que esta es la forma más limpia y eficiente de hacerlo.

+1

En realidad, me parece una solución brillante (y muy clara). He estado plagado por este problema durante tanto tiempo. ¡Gracias! – pongba

+0

Esta es realmente una idea brillante. ¡Gracias! – newman

+1

Bonita, bonita, bastante buena. – SmartK8

2

Ha intentado utilizar un DockPanel que llena la barra de herramientas, y luego puede acoplar el ComboBox a la derecha.

Recuerde que con un dockpanel la secuencia en la que coloca los elementos es muy importante.

HTH

+0

¿Cómo llenarías la barra de herramientas con un DockPanel? Intenté y solo puedo hacerlo dinámicamente. A menos que haya algo que desconozco, este es el problema con la barra de herramientas. Por eso, esto no funcionará para mí. – jsmith

+0

simplemente super ocupado con el trabajo en este momento, voy a publicar una solución este fin de semana que debería sentirse un poco más limpia. –

1

Mi solución a esto era crear un control de etiqueta con una habilidad de "resorte", para llenar el vacío vacío entre los botones de la barra de herramientas, alineando "correctamente" el cuadro combinado de la barra de herramientas (o cualquier otro control que necesita "alineado a la derecha).

para hacer esto, he creado un WidthConverter, que llevaría el ancho real del control de barra de herramientas y luego restar el espacio necesario necesario para alinear a la derecha del cuadro combinado .:

public class WidthConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return Math.Max(System.Convert.ToDouble(value) - System.Convert.ToDouble(parameter), 0.0); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Luego, agregué un control de etiqueta a la barra de herramientas, que se encuentra a la izquierda del cuadro combinado que necesita alineado a la derecha. Ancho de etiqueta para ActualWidth de la barra de herramientas y aplicar la WidthConverter:

<Label Width="{Binding Converter={StaticResource WidthConverter}, ElementName=toolBar1, Path=ActualWidth, ConverterParameter=50}" /> 

Usted tendrá que ajustar el ConverterParameter a sus necesidades específicas hasta obtener el deseado "alinear a la derecha". Un número más alto proporciona más espacio para el cuadro combinado, mientras que un número inferior proporciona menos espacio.

Al usar esta solución, la etiqueta cambiará de tamaño automáticamente cada vez que su barra de herramientas cambie de tamaño, haciendo que parezca que ha alineado su cuadro combinado.

Esta solución ofrece dos grandes ventajas en comparación con agregar una cuadrícula a la barra de herramientas. La primera es que si necesita usar botones en la barra de herramientas, no perderá el estilo del botón de la barra de herramientas. El segundo es que el desbordamiento funcionará como se espera si la longitud de la barra de herramientas se reduce mediante el cambio de tamaño de la ventana. Los botones individuales irán al desbordamiento según sea necesario. Si los botones se colocan en una cuadrícula, la cuadrícula se coloca en el desbordamiento y se toman todos los botones.

XAML de ella en uso:

<ToolBarPanel> 
    <ToolBar Name="toolBar1"> 
     <Button> 
      <Image Source="save.png"/> 
     </Button> 
    <Label Width="{Binding Converter={StaticResource Converters.WidthConverter}, 
        ElementName=toolBar1, 
        Path=ActualWidth, 
        ConverterParameter=231}" HorizontalAlignment="Stretch" ToolBar.OverflowMode="Never"/> 
    <Button> 
     <Image Source="open.png"/> 
    </Button> 
</ToolBar> 

Si desea mantener siempre el último botón de la barra de herramientas, por ejemplo un botón de ayuda que siempre quiere visible, añadir la barra Atributo . OverflowMode = "Nunca" a su elemento.

+0

Su solución parece más limpia. Sin embargo, no puedo hacer que funcione para mí. ¿Puede proporcionar una muestra completa para una barra de herramientas con un botón a la izquierda y otro a la derecha? – newman

+0

Se actualizó la respuesta para incluir un ejemplo. El primer botón se alineará a la izquierda, y el segundo botón se alineará a la derecha. Tendrá que ajustar el parámetro del convertidor para obtener el resultado deseado. – PocketDews

0

No estoy muy satisfecho con la solución "WidthConverter" porque obtuve algunos elementos dinámicos al final. La búsqueda adicional me llevó al here, que parece estar funcionando perfecto para mí. Aquí está mi ejemplo de código en caso de estar interesado:

<ToolBar Name="toolBar"> 
    <DockPanel Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ToolBarPanel}}}"> 
     <DockPanel.Resources> 
      <Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"></Style> 
     </DockPanel.Resources> 
     <Button x:Name="btnRefresh" ToolTip="Refresh" Click="btnRefresh_Click"> 
      <Image Margin="2 0" Source="/Resources/refresh.ico" Height="16" Width="16"/> 
     </Button> 
     <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> 
      <Image Margin="2 0" Source="/Resources/Help.ico" Height="16" Width="16"/> 
      <TextBlock Text="Help" Margin="2 0" VerticalAlignment="Center"/> 
     </StackPanel> 
    </DockPanel> 
</ToolBar> 
+0

Ah, este enfoque no funciona perfectamente cuando se cambia el tamaño de la ventana. – newman

+0

Esto no funciona porque todos los botones de la barra de herramientas desaparecen si se reduce la ventana. De lo contrario, funciona perfecto. Por lo tanto, sería genial si hay un pequeño cambio en este enfoque para que funcione. – newman

+0

Bien, encontré otra publicación en http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/dd25fe90-4e39-4cba-bf91-5ca5ab662505 (de dhbusch2) que realmente funciona perfecto para mí, excepto que tengo que aplicar un estilo al botón como Style = "{StaticResource {x: Static ToolBar.ButtonStyleKey}}" – newman

1

Esto es cómo lo hice:

creé un estilo de la barra de herramientas

<Style x:Key="{x:Type ToolBar}" TargetType="{x:Type ToolBar}"> 
    <Setter Property="SnapsToDevicePixels" Value="true" /> 
    <Setter Property="OverridesDefaultStyle" Value="true" /> 
    <Setter Property="HorizontalAlignment" Value="Stretch"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ToolBar}"> 
       <Grid Background="{StaticResource ToolGridBackground}"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="Auto"/> 
        </Grid.ColumnDefinitions> 
        <Image Grid.Column="0" Style="{StaticResource LogoImage}"/> 
        <ToolBarPanel Grid.Column="2" x:Name="PART_ToolBarPanel" IsItemsHost="true" Margin="0,1,2,2" Orientation="Horizontal"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

La parte importante es:

<Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="Auto"/> 
        </Grid.ColumnDefinitions> 

Y

<ToolBarPanel Grid.Column="2"/> 

Con esto, los botones se alinean a la derecha

+0

Esto funciona, pero está mal porque reemplazamos completamente la plantilla de ToolBar y por lo tanto, perdemos el estilo predeterminado. – diimdeep

2
<ToolBar Width="100" VerticalAlignment="Top" > 
     <ToolBar.Resources> 
      <Style TargetType="{x:Type ToolBarPanel}"> 
       <Setter Property="Orientation" Value="Vertical"/> 
      </Style> 
     </ToolBar.Resources> 

     <DockPanel> 
      <ToolBarPanel Orientation="Horizontal" > 
       <Button>A</Button> 
       <Button>B</Button> 
      </ToolBarPanel> 
      <Button DockPanel.Dock="Right" HorizontalAlignment="Right">C</Button> 
     </DockPanel> 
    </ToolBar> 

0

me di cuenta que es un viejo tema, pero todavía aparece cuando se hace la pregunta. Esto es cómo manejar esta pregunta:

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition x:Name="MenuRow" Height="25"/> 
     <RowDefinition x:Name="ToolbarRow" Height="25"/> 
     <RowDefinition x:Name="CatalogRow" Height="*"/> 
     <RowDefinition x:Name="RecipeRow" Height="0.4*"/> 
    </Grid.RowDefinitions> 
    <ToolBar Grid.Row="1"> 
     <Button x:Name="tbFileOpen" Margin="0,0,0,0" Click="MenuItem_Click"><Image Source="Icons/Main/File/Load.png"/></Button> 
     <Button x:Name="tbFileSave" Margin="0,0,0,0" Click="MenuItem_Click"><Image Source="Icons/Main/File/Save.png"/></Button> 
     <Button x:Name="tbFileClear" Margin="0,0,0,0" Click="MenuItem_Click"><Image Source="Icons/Main/File/New document.png"/></Button> 
    </ToolBar> 
    <ToolBar Grid.Row="1" HorizontalAlignment="Right"> 
     <Button x:Name="tbFileExit" Margin="0,0,0,0" Click="MenuItem_Click"><Image Source="Icons/Main/File/Exit.png"/></Button> 
    </ToolBar> 
</Grid> 

con eficacia: Puedo crear dos objetos barra de herramientas y ellos tienen el mismo Grid.row. El primero tiene alineación predeterminada (izquierda), el segundo está alineado a la derecha. Parece hacer el truco para mí.

3

Para cualquier otra persona en busca de una solución, el siguiente trabajó para mí:

<ToolBar HorizontalAlignment="Stretch" ToolBarTray.IsLocked="True"> 
    <ToolBar.Resources> 
    <Style TargetType="{x:Type DockPanel}"> 
     <Setter Property="HorizontalAlignment" Value="Right" /> 
    </Style> 
</ToolBar.Resources> 

estoy usando .NET 4.6 y VS2015, pero creo que esto iba a funcionar en las versiones anteriores también.

Cuestiones relacionadas