2016-08-28 2 views
2

У меня есть приложение WPF, и я пытаюсь правильно установить элементы. Есть только четыре элемента, поэтому это должно быть довольно прямолинейно, но я просто не могу заставить его работать.Элемент XAML заполняет все оставшееся пространство

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

Элементы должны быть уложены сверху вниз, поэтому панель стека кажется естественной. Но третий элемент должен заняться всем оставшимся пространством, которое нет в верхних и нижних. Независимо от того, что я пробовал, он занимал слишком много места или слишком мало. Я мог бы только заставить его работать, если бы я дал ему конкретный размер пикселя, который, как объяснялось выше, не будет работать.

Последняя вещь, которую я пробовал, - это панель док-станции. Хотя он выглядит правильно в дизайнере Visual Studio, при его выполнении третий элемент - холст - полностью покрывает нижний элемент.

Мой XAML:

<DockPanel> 
    <Button x:Name="btnClose" DockPanel.Dock="Top" Content="X" 
      HorizontalAlignment="Right" Margin="0,5,5,0" VerticalAlignment="Top" 
      Width="Auto" Height="Auto" Background="Black" 
      Foreground="White" Click="btnClose_Click"/> 
    <Label x:Name="lblTitle" DockPanel.Dock="Top" Content="My Title" 
      HorizontalAlignment="Center" VerticalAlignment="Top" Width="Auto" 
      Foreground="White" FontWeight="Bold" FontSize="22"/> 

    <Label x:Name="lblControls" DockPanel.Dock="Bottom" Content="Placeholder" 
      HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="Auto" 
      Height="Auto" Foreground="White" FontWeight="Bold" FontSize="22"/> 

    <Border x:Name="CanvasBorder" BorderBrush="White" BorderThickness="5" > 
     <Canvas x:Name="cvsChart" Grid.Row="0" HorizontalAlignment="Stretch" 
       VerticalAlignment="Top" Width="Auto"> 
     </Canvas> 
    </Border> 
</DockPanel> 

Любая идея о том, как получить этот холст, чтобы растянуть и заполнить все пространство остальные три не принимают?

UPDATE Поскольку @Peter Duniho довольно много доказало мне, что код работает, я попробовал эксперимент и удалить код изменения размера я имею в месте для того, когда появится окно. Вывод, окно выглядит абсолютно правильно. Это то, что я делаю, чтобы изменить его (в основном) размер рабочего стола:

public const int WINDOW_OFFSET = 10; 
... 

int screenWidth = (int)System.Windows.SystemParameters.PrimaryScreenWidth; 
int screenHeight = (int)System.Windows.SystemParameters.PrimaryScreenHeight; 

// center this window in desktop 
Width = screenWidth - WINDOW_OFFSET; 
Height = screenHeight - WINDOW_OFFSET; 
Left = WINDOW_OFFSET/2; 
Top = WINDOW_OFFSET/2; 

Так что я сделал некоторые ковыряться и нашел комментарий здесь, на «Стек, который сказал, чтобы получить Workarea вместо PrimaryScreenHeight. Я пробовал это и voila!, появляется все окно приложения.

int screenWidth = (int)System.Windows.SystemParameters.WorkArea.Width; 
int screenHeight = (int)System.Windows.SystemParameters.WorkArea.Height; 

Как выясняется, нижний ряд был отображения, я просто не мог видеть, потому что она появилась ниже в нижней части экрана. Теперь я вижу это, и я вернусь к развитию небес!

Спасибо всем за их вклад!

ответ

4

Существует ряд возможных подходов к этому. Одним из наиболее простых должны содержать свои элементы в Grid и установить все, кроме третья высоты строки в Auto:

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition/> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 
    <Button x:Name="btnClose" Content="X" Grid.Row="0" 
      HorizontalAlignment="Right" Margin="0,5,5,0" VerticalAlignment="Top" 
      Width="Auto" Height="Auto" Background="Black" 
      Foreground="White" Click="btnClose_Click"/> 
    <Label x:Name="lblTitle" Content="My Title" Grid.Row="1" 
      HorizontalAlignment="Center" VerticalAlignment="Top" Width="Auto" 
      Foreground="White" FontWeight="Bold" FontSize="22"/> 

    <Label x:Name="lblControls" Content="Placeholder" Grid.Row="3" 
      HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="Auto" 
      Height="Auto" Foreground="White" FontWeight="Bold" FontSize="22"/> 

    <Border x:Name="CanvasBorder" BorderBrush="White" BorderThickness="5" Grid.Row="2"> 
     <Canvas x:Name="cvsChart" Grid.Row="0" HorizontalAlignment="Stretch" 
       VerticalAlignment="Top" Width="Auto"> 
     </Canvas> 
    </Border> 
    </Grid> 

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

Это создает окно, которое выглядит следующим образом:

four row grid with border and canvas filling the third row

(я установить фон окна для Gray, чтобы ваш белый текст и граница будет видна.)

Другим вариантом было бы фактически использовать DockPanel. Мне кажется, что основная проблема в вашей попытке состоит в том, что вы устанавливаете lblControls элемент на DockPanel.Dock="Bottom", когда это должно быть Top. Когда я меняю его на Top, кажется, он работает отлично.

Основываясь на ваш комментарий ниже, кажется, что вы на самом деле хотите lblControls быть установлен в DockPanel.Dock="Bottom", а на самом деле код размещен, кажется, также делать то, что вы хотите. Мне непонятно, что отличается от того, что делает ваш код, и что вы хотите. Было бы лучше, если бы вы предоставили хороший Minimal, Complete, and Verifiable code example, который надежно воспроизводит проблему.

+0

Спасибо за ответ, но ни один подход не работал. Предполагается, что граница и холст появляются в середине окна. Из того, что я понимаю, это должно было сделать последнее, а не придавать ему стыковку. Когда я устанавливаю 'lblControls' в Top, они появляются вверху, над границей и холстом, как им говорят, а не так, как предполагалось. Подход Grid тоже не работал. Я дал всем строкам высоту «Авто», за исключением границы и холста, которые я дал «* *». Он также скрывает нижнюю метку. – Frecklefoot

+0

@Frecklefoot: _ «Граница и холст должны появляться в середине окна» _ - извините, ваш вопрос не был ясен о предполагаемом результате. Код, который вы разместили _does_, сделайте это, поместив 'lblControls' внизу, как вы указали, и' CanvasBorder', с 'cvsChart' внутри, между' lblTitle' и 'lblControls'. Я могу отредактировать пример «Grid», чтобы соответствовать вашему комментарию, но в конечном итоге неясно, почему код, который у вас есть в вашем вопросе, не делает то, что вы хотите. Мне кажется, что это так, основываясь на вашем комментарии здесь. –

+0

Извините за то, что не ясно в моем исходном вопросе. Я боялся, что это может быть проблемой, поскольку я поместил границу и холст в последний раз. Тогда я должен делать что-то еще неправильно, потому что я все еще получаю нижнюю метку, полностью покрытую границей и холстом. По крайней мере, я предполагаю, что это то, что происходит, потому что я не вижу его вообще, когда я его запускаю. Но мое приложение ничего не делает, кроме как появляется. – Frecklefoot

2

Удалить вертикальное выравнивание холста

+0

Спасибо, но это не повлияло. – Frecklefoot

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