2010-02-04 5 views
11

Ist es möglich, die Elemente innerhalb einer WPF-Symbolleiste eine HorizontalAlignment of Right zu machen?WPF-Toolbar-Elemente HorizontalAligement = "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> 

Ich habe versucht innen in ein Raster, um die Elemente hinzuzufügen und die Zuordnung der ColumnDefinition s Links/Rechts als auch. Ich habe auch eine StackPanel versucht. Egal was ich versuche, ich kann nicht scheinen, dass die ComboBox auf der rechten Seite der Toolbar "verankert" wird.

UPDATE:

<DockPanel LastChildFill="True"> 

nicht funktioniert, es wird nicht das ToolBar Element füllen wie wäre es ein normales Element.

Antwort

15

Weitere Untersuchungen zeigten, dass, um dies zu tun, I die Breite eines Grid innerhalb des ToolBar oder als Chris Nicol gesagt, ein DockPanel innerhalb des ToolBar dynamisch zu der der Breite des festlegen müssen Toolbar mit RelativeSource.

Allerdings fühlt sich das nicht wie eine saubere Lösung an. Es ist ziemlich kompliziert, die Toolbar korrekt bei der Größenänderung zu aktualisieren. Stattdessen fand ich etwas von einem Hack, der aussieht und sauberer arbeitet.

<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"/> 

Da alle meine Elemente auf einem Gitter sind, kann ich meine ComboBox auf dem ToolBar platzieren, indem es Grid.Row auf der gleichen Zeile wie der Symbolleiste zuweisen. Nach dem Setzen meiner Margins, um die ComboBox über leicht ziehen, um nicht mit Aussehen zu stören, funktioniert es wie benötigt ohne Fehler. Da der einzige andere Weg, den ich dazu gefunden habe, die Eigenschaft Width eines DockPanel/Grid dynamisch zu setzen, habe ich das Gefühl, dass dies der sauberere, effizientere Weg ist, dies zu tun.

+1

Eigentlich finde ich das eine brillante (und sehr gepflegte) Lösung. Ich habe dieses Problem schon so lange geplagt. Vielen Dank! – pongba

+0

Das ist wirklich eine brillante Idee. Vielen Dank! – newman

+1

Hübsch, hübsch, ziemlich gut. – SmartK8

2

Haben Sie versucht, ein DockPanel zu verwenden, das die Symbolleiste füllt, dann können Sie die ComboBox an der rechten Seite andocken.

Denken Sie daran, dass bei einem Dockpanel die Reihenfolge, in der Sie die Objekte einfügen, sehr wichtig ist.

HTH

+0

Wie würden Sie die Symbolleiste mit einem DockPanel füllen? Ich habe versucht und kann es nur dynamisch tun. Es sei denn, es gibt etwas, das mir nicht bewusst ist, ist dies das Problem mit der ToolBar. Deshalb wird das bei mir nicht funktionieren. – jsmith

+0

gerade super beschäftigt mit der Arbeit im Moment, werde ich an diesem Wochenende eine Lösung posten, die sich etwas sauberer anfühlen soll. –

1

Meine Lösung war, ein Label-Steuerelement mit einer "Feder" wie Fähigkeit zu erstellen, so dass es die leere Lücke zwischen den Schaltflächen auf der Symbolleiste füllen würde, so "Ausrichten" der Symbolleiste Combobox (oder andere Steuerung, die „rechtsbündig).

Dazu habe ich eine WidthConverter, das würde die tatsächliche Breite des ToolBar Steuerung und dann abziehen, um die den Platzbedarf benötigt, um richtig richten sich die Combobox benötigt .:

Dann fügte ich der Symbolleiste, die auf der linken Seite der Combobox platziert wurde, ein Label Control hinzu Etikett Breite der Actual Symbolleiste und wenden die WidthConverter:

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

Sie müssen die Converter auf Ihre speziellen Bedürfnisse anzupassen, bis Sie das gewünschte „rechts ausrichten“ erhalten. Eine höhere Zahl bietet mehr Platz für die Combobox, während eine niedrigere Zahl weniger Platz bietet.

Bei Verwendung dieser Lösung wird die Beschriftung automatisch angepasst, wenn die Größe der Symbolleiste geändert wird. Dadurch wird der Eindruck erweckt, dass Sie Ihre Combobox richtig ausgerichtet haben.

Diese Lösung bietet im Vergleich zum Hinzufügen eines Rasters zur Symbolleiste zwei große Vorteile. Die erste besteht darin, dass Sie das Symbolleisten-Design nicht verlieren, wenn Sie Schaltflächen in der Symbolleiste verwenden müssen. Der zweite ist, dass der Überlauf wie erwartet funktioniert, wenn die Symbolleistenlänge durch die Fenstergrößenänderung reduziert wird. Einzelne Tasten gehen je nach Bedarf in den Überlauf. Wenn die Knöpfe in ein Gitter gelegt werden, wird das Gitter in den Überlauf gebracht, indem alle Knöpfe mitgenommen werden.

XAML davon in Gebrauch:

<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> 

Wenn Sie die letzte Schaltfläche in der Symbolleiste immer behalten wollen, sagen, eine Hilfe-Taste, die Sie immer sichtbar sein sollen, das Attribut ToolBar hinzuzufügen. OverflowMode = "Nie" zu seinem Element.

+0

Ihre Lösung scheint sauberer zu sein. Allerdings kann ich es nicht für mich arbeiten lassen. Können Sie ein vollständiges Beispiel für eine Symbolleiste mit einer Schaltfläche auf der linken und einer anderen auf der rechten Seite bereitstellen? – newman

+0

Die Antwort wurde aktualisiert, um ein Beispiel hinzuzufügen. Die erste Schaltfläche wird ausgerichtet und die zweite Schaltfläche wird rechts ausgerichtet. Sie müssen den Converter-Parameter anpassen, um das gewünschte Ergebnis zu erhalten. – PocketDews

0

Ich bin nicht sehr zufrieden mit der "WidthConverter" Lösung, weil ich einige dynamische Elemente am Ende bekam. Weitere Suche führte mich zu here, die für mich perfekt zu funktionieren scheint. Hier ist mein Codebeispiel, falls Sie daran interessiert sind:

<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, dieser Ansatz funktioniert nicht perfekt, wenn das Fenster in der Größe geändert wird. – newman

+0

Dies funktioniert nicht, da alle Symbolleistenschaltflächen verschwinden, wenn Sie das Fenster verkleinern. Ansonsten funktioniert es perfekt. Es wäre also großartig, wenn dieser Ansatz etwas verbessert würde, damit er funktioniert. – newman

+0

Okay, ich fand einen anderen Beitrag auf http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/dd25fe90-4e39-4cba-bf91-5ca5ab662505 (von dhbusch2), der wirklich perfekt für mich funktioniert, außer dass ich einen Style auf Button wie Style anwenden muss = "{StaticResource {x: Static ToolBar.ButtonStyleKey}}" – newman

1

Dies ist, wie ich es tat:

ich einen Stil für die Symbolleiste erstellt

<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> 

Der wichtigste Teil ist:

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

Und

<ToolBarPanel Grid.Column="2"/> 

Damit wird Ihre Tasten rechts

+0

Das funktioniert, aber es ist schlecht, weil wir Template von ToolBar vollständig ersetzen und somit das Standardstyling verlieren. – 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

ich dies eine ist altes Thema erkennen, ausgerichtet werden, aber es erscheint immer noch auf, wenn die Frage zu stellen. Dies ist, wie ich behandeln diese Frage:

<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> 

effektiv: Ich schaffe zwei Symbolleiste Objekte und haben sie auf dem gleichen Grid.Row. Der erste hat eine Standardausrichtung (links), der zweite ist rechtsbündig ausgerichtet. Es scheint der Trick für mich zu sein.

3

Für alle anderen nach einer Lösung gesucht, arbeitete die folgenden für mich:

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

ich .NET 4.6 und VS2015, aber ich glaube, dass dies auch in früheren Versionen funktionieren würde.