Элементы панели инструментов WPF HorizontalAligment = "Right"

Возможно ли, чтобы элементы в панели инструментов WPF имели горизонтальное выравнивание справа?

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

Я попытался добавить элементы внутрь в Grid и назначить ColumnDefinition влево/вправо. Я также попробовал StackPanel. Независимо от того, что я пытаюсь, я не могу заставить ComboBox "привязываться" в правой части панели инструментов.

UPDATE:

<DockPanel LastChildFill="True">

Не работает, он не заполнит элемент ToolBar, как обычный элемент.

Ответ 1

Дальнейшее исследование показало, что для этого мне нужно установить ширину a Grid в пределах ToolBar, или, как сказал Крис Никол, a DockPanel внутри ToolBar динамически по ширине ширины ToolBar, используя RelativeSource.

Однако это не похоже на чистое решение. Довольно сложно получить ToolBar для правильного обновления при изменении размера. Таким образом, вместо этого я нашел несколько хакеров, которые выглядят и работает чище.

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

Поскольку все мои элементы находятся в гриде, я могу разместить ComboBox поверх ToolBar, назначив ему Grid.Row той же строке, что и панель инструментов. После того, как мой Margins слегка потянул ComboBox, чтобы не мешать внешнему виду, он работает по мере необходимости без ошибок. Поскольку единственным способом, который я нашел для этого, является динамическое создание свойства DockPanel/Grid Width, я действительно чувствую, что это более эффективный способ сделать это.

Ответ 2

Для всех, кто ищет решение, для меня работало следующее:

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

Я использую .NET 4.6 и VS2015, но я считаю, что это будет работать и в предыдущих версиях.

Ответ 3

Пробовали ли вы использовать DockPanel, который заполняет панель инструментов, тогда вы можете состыковать ComboBox вправо.

Помните, что с док-станцией очень важна последовательность, в которую вы помещаете элементы.

НТН

Ответ 4

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

Ответ 5

Моим решением было создать элемент управления меткой с "способностью" spring ", чтобы он заполнил пустую пустоту между кнопками на панели инструментов, таким образом," выравнивание по правому краю "на панели инструментов панели инструментов (или любой другой элемент управления, который нуждается в выравнивании по правому краю.

Для этого я создал WidthConverter, который будет использовать фактическую ширину элемента управления ToolBar, а затем вычесть пространство, необходимое для правильного выравнивания выпадающего списка.:

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();
    }
}

Затем я добавил элемент управления меткой на панель инструментов, расположенную слева от выпадающего списка, которое вам нужно выровнять по правому краю. Привяжите ярлык Width к панели инструментов ActualWidth и примените WidthConverter:

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

Вам нужно будет настроить ConverterParameter для ваших конкретных потребностей, пока не получите желаемый "правый выравнивание". Более высокое число предоставляет больше места для combobox, тогда как меньшее число обеспечивает меньшее пространство.

Используя это решение, ярлык будет автоматически изменяться, когда ваша панель инструментов изменится, что приведет к тому, что вы правильно выровняли свои выпадающие списки.

Есть два больших преимущества для этого решения по сравнению с добавлением сетки на панель инструментов. Во-первых, если вам нужно использовать кнопки на панели инструментов, вы не потеряете стиль кнопки на панели инструментов. Во-вторых, переполнение будет работать, как и ожидалось, если длина панели инструментов уменьшается за счет изменения размера окна. Отдельные кнопки переходят в переполнение по мере необходимости. Если кнопки помещаются в сетку, сетка помещается в переполнение, беря с собой все кнопки.

Используется XAML:

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

Если вы хотите всегда удерживать последнюю кнопку на панели инструментов, скажите кнопку помощи, которую вы всегда хотите видеть, добавьте в свой элемент атрибут ToolBar.OverflowMode = "Never".

Ответ 6

Вот как я это сделал:

Я создал стиль для панели инструментов

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

Важная часть:

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

И

<ToolBarPanel Grid.Column="2"/>

При этом ваши кнопки будут выровнены вправо

Ответ 7

Я не очень доволен решением "WidthConverter", потому что у меня есть некоторые динамические элементы. Дальнейший поиск привел меня к здесь, который, кажется, работает идеально для меня. Вот мой пример кода, если вы заинтересованы:

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

Ответ 8

Я понимаю, что это старая тема, но она все еще появляется при задании вопроса. Вот как я решаю этот вопрос:

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

Эффективно: я создаю два объекта панели инструментов и располагаю их на одном и том же Grid.row. Первый имеет выравнивание по умолчанию (слева), второе выравнивается по правому краю. Мне кажется, это трюк.