Как выровнять несколько StatusBarItems с правой стороны в XAML?

У меня есть StatusBar с 4 элементами в моем приложении С#. Я в основном хочу поплавать с двумя последними двумя StatusBarItems. Я попробовал это, установив их как с HorizontalAlignment="Right", но это работает только для последнего элемента.

<StatusBar Name="statusBar1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
    <StatusBarItem />
    <StatusBarItem />
    <StatusBarItem HorizontalAlignment="Right" />
    <StatusBarItem HorizontalAlignment="Right" />
</StatusBar>

Я начал поиск в Google, и я придумал следующее: http://kentb.blogspot.ch/2007/10/perfect-wpf-statusbar.html

Это действительно единственное решение для этого? Или есть более простой способ?

Ответ 1

Вы можете воспользоваться тем, что по умолчанию ItemsPanel для StatusBar есть DockPanel. DockPanel по умолчанию попытается заполнить оставшееся пространство последним. Таким образом, последний StatusBarItem, который вы добавите в StatusBar, заполнит оставшуюся часть пробела. Чтобы воспользоваться этим, вы можете просто вложить StatusBarItems следующим образом:

<StatusBar Name="statusBar1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
  <StatusBarItem Content="Item 1"/>
  <StatusBarItem Content="Item 2" />
  <StatusBarItem HorizontalAlignment="Right">
    <StackPanel Orientation="Horizontal">
      <StatusBarItem  Content="Item 3"/>
      <StatusBarItem Content="Item 4"/>
      <ProgressBar Height="15" Width="50" IsIndeterminate="True" Margin="5,0"/>
    </StackPanel>
  </StatusBarItem>
</StatusBar>

Обратите внимание, что для HorizontalAlignment третьего StatusBarItem установлено значение Right, поэтому содержимое будет выровнено по правому краю.

Конечно, вам не нужно, чтобы Item 3 и Item 4 были StatusBarItems, они могли быть другими элементами управления, такими как Buttons или ProgressBar, как я показал выше. StatusBarItem - это просто контейнер, который обертывает элементы в StatusBar, подобно тому, как ComboBoxItem обертывает элементы внутри ComboBox.

StatusBar автоматически упаковывает содержимое в StatusBarItems, если вы их не используете, поэтому пункты 1 и 2 могут быть легко TextBoxes. Основная причина использования StatusBarItems заключается в том, что вы хотите контролировать, как работает StatusBarItem, например, в третьем StatusBarItem, где он устанавливает HorizontalAlignment вручную, а не полагаться на значение по умолчанию.

Ответ 2

Как уже упоминалось, контейнер по умолчанию - DockPanel. Таким образом, вы можете установить столько элементов, сколько необходимо для DockPanel.Dock="Right". Просто убедитесь, что пункт fill последний.

<StatusBar>
    <StatusBarItem DockPanel.Dock="Right">
        <Slider Width="100" />
    </StatusBarItem>
    <StatusBarItem DockPanel.Dock="Right">
        <Label>Zoom: 100 %</Label>
    </StatusBarItem>
    <StatusBarItem>
        <TextBlock>Ready</TextBlock>
    </StatusBarItem>
</StatusBar>

Ответ 3

Вы также можете установить LastChildFill в false, а затем использовать DockPanel.Dock=Right так же, как и выше, без необходимости беспокоиться о последнем элементе, потребляющем все пространство:

<StatusBar>
  <StatusBar.ItemsPanel>
    <ItemsPanelTemplate>
      <DockPanel LastChildFill="False" />
    </ItemsPanelTemplate>
  </StatusBar.ItemsPanel>
</StatusBar>

Ответ 4

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

<StatusBar Height="30">
  <StatusBar.ItemsPanel>
    <ItemsPanelTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
      </Grid>
    </ItemsPanelTemplate>
  </StatusBar.ItemsPanel>

  <StatusBarItem Grid.Column="0">
    <TextBlock Text="{Binding ProgressMessage, Mode=OneWay}" />
  </StatusBarItem>

  <StatusBarItem Grid.Column="1">
    <ProgressBar Value="{Binding ProgressValue, Mode=OneWay}" Width="100" Height="10" />
  </StatusBarItem>

  <StatusBarItem Grid.Column="2">
    <Ellipse Width="12" Height="12" Stroke="Gray" Fill="Red" />
  </StatusBarItem>
</StatusBar>