2009-09-03 4 views
27

Добавление нескольких дочерних элементов в WPF StatusBar приводит к плохой компоновке с небольшой возможностью настройки. Например, этот код:Как настроить макет статуса WPF StatusBar?

<Window x:Class="StatusBar.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <DockPanel> 
     <StatusBar DockPanel.Dock="Bottom"> 
      <StatusBarItem> 
       <TextBlock>Ready</TextBlock> 
      </StatusBarItem> 
      <StatusBarItem> 
       <TextBlock>Set</TextBlock> 
      </StatusBarItem> 
     </StatusBar> 

     <Label>Main Content</Label> 
    </DockPanel> 
</Window> 

Результаты в:

enter image description here

Это не идеальное расположение, так как "Set" выдавливается прямо против "Ready".

Как получить полный контроль над компоновкой элемента управления WPF StatusBar?

ответ

72

По умолчанию StatusBar использует DockPanel для размещения своих детей. Это отлично работает для одного элемента, но имеет тенденцию делать вещи беспорядочными и неудобными при работе с более чем одним ребенком.

Чтобы получить высокий уровень контроля над позиционированием строки состояния детей, вы можете поменять на DockPanel для Grid:

<Window x:Class="StatusBar.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <DockPanel> 
     <StatusBar DockPanel.Dock="Bottom"> 
      <StatusBar.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="*"/> 
         </Grid.RowDefinitions> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="4*"/> 
          <ColumnDefinition Width="Auto"/> 
          <ColumnDefinition Width="*"/> 
          <ColumnDefinition Width="*"/> 
         </Grid.ColumnDefinitions> 
        </Grid> 
       </ItemsPanelTemplate> 
      </StatusBar.ItemsPanel> 
      <StatusBarItem> 
       <TextBlock>Ready</TextBlock> 
      </StatusBarItem> 
      <StatusBarItem Grid.Column="1"> 
       <ProgressBar Value="30" Width="80" Height="18"/> 
      </StatusBarItem> 
      <StatusBarItem Grid.Column="2"> 
       <TextBlock>Set</TextBlock> 
      </StatusBarItem> 
      <StatusBarItem Grid.Column="3"> 
       <TextBlock>Go!</TextBlock> 
      </StatusBarItem> 
     </StatusBar> 

     <Label>Main Content</Label> 
    </DockPanel> 
</Window> 

Это приводит к:

enter image description here

Для более углубленное обсуждение, пожалуйста, посетите мой пост в блоге here.

+36

@ Давид: не смешно. Я опубликовал этот вопрос, потому что аналитика google сообщила мне, что это одна из моих самых популярных сообщений в блогах, поэтому прямой ответ на этот вопрос в stackoverflow был бы полезен для сообщества. У меня нет рекламы на моем блоге, поэтому не стоит ничего выиграть от ссылки на трауле. И я поставил более чем достаточно информации в своем ответе, что вам даже не нужно посещать мой блог, если вы не хотите больше информации. Теперь любезно пойти и найти что-то конструктивное. –

+0

Спасибо, это то, что я искал –

+0

Мммм, кто-то знает, почему, если я поставлю разделитель внутри StatusBarItem, он не будет нарисован? Благодарю. –

11

На самом деле, после ответа Кента Я попробовал это, и это работает прекрасно:

<StatusBar> 
    <StatusBarItem DockPanel.Dock="Right"> 
     <TextBlock>Go!</TextBlock> 
    </StatusBarItem> 
    <StatusBarItem DockPanel.Dock="Right"> 
     <TextBlock>Set</TextBlock> 
    </StatusBarItem> 
    <StatusBarItem DockPanel.Dock="Right"> 
     <ProgressBar Value="30" Width="80" Height="18"/> 
    </StatusBarItem> 
    <!-- Fill last child is true by default --> 
    <StatusBarItem> 
     <TextBlock>Ready</TextBlock> 
    </StatusBarItem> 
</StatusBar> 
+0

Я не предлагал, чтобы это не сработало, но это «грязно и неудобно», потому что оно в нелогичном порядке и потому, что у вас гораздо меньше контроля над макетом. Попробуйте сделать элемент * Set * занятым половиной доступной ширины, и вы поймете, что я имею в виду. –

+6

Я думаю, что если вы понимаете, как работает DockPanel, это самый чистый способ сделать это. – Sonhja

+0

, похоже, не работает, если моя панель состояния находится в usercontrol и что usercontrol отображается как contentcontrol, где contentcontrol пристыкован к основанию. – juFo

1

Просто ради справки для тех, кто читает отличные ответы выше, я хотел бы предложить что-то еще более простое, что добивается своего такие же результаты. (Использование ни DockPanel, ни StatusBar).

<Window> 
. 
. 

<Grid Margin="2"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="15"/> 
     </Grid.RowDefinitions> 

     <SomeContainer Grid.Row="0" /> <!-- Main Content.. --> 

     <Grid Grid.Row="1"> 
      <!-- Status bar laid out here (using similar approach)--> 
     </Grid> 
</Window> 

Отказ от ответственности: Это было давно в то время, когда я начинал работу с WPF.

Смежные вопросы