WPF Grid и DataGrid - PullRequest
       11

WPF Grid и DataGrid

1 голос
/ 21 января 2010

UserControl, с которым я пытаюсь работать, по сути выложено так:

<Grid>
   <Grid.RowDefinitions>
       <Row Height="*"/>
       <Row Height="*"/>
   </Grid.RowDefinitions>
   <wpftoolkit:DataGrid x:Name="PrimaryGrid"/> <!-- ~10 rows -->
   <Border>
      <Grid>
         <Grid.RowDefinitions>
             <Row Height="*"/>
             <Row Height="*"/>
         </Grid.RowDefinitions>
         <wpftoolkit:DataGrid x:Name="SecondaryGrid"/> <!-- ~2 rows -->
         <wpftoolkit:DataGrid x:Name="OtherGrid"/> <!-- ~50 rows -->
      </Grid>
   </Border>
</Grid>

Этот UserControl затем помещается в мой Window как последний член Grid, единственный с Height="*". У меня проблемы с размером DataGrid s.

Если я установлю VerticalAlignment из UserControl в Stretch в Window, тогда PrimaryGrid получит половину высоты UserControl, и каждый из двух в Border получит 1/4. Они имеют одинаковый размер независимо от количества строк в каждой, оставляя OtherGrid со слишком маленьким вертикальным пространством, а другие - с пустым пробелом внутри прокрутки.

Если я установлю VerticalAlignment на Top, сетки, похоже, будут достаточно хорошо соответствовать их содержимому, за исключением того, что в нижней части UserControl остается необъяснимое пустое пространство. Я использовал Snoop и RowDefinition для UserControl имеет правильное ActualHeight, но UserControl использует только его часть - 80% или около того.

Я не против того, чтобы исправить случай Stretch (Как сделать так, чтобы DataGrid не растягивался больше, чем количество строк?) Или случай Top (Как сделать UserControl использовать все доступное ему пространство?)

Ответы [ 4 ]

3 голосов
/ 22 января 2010

Сводка : используйте Stretch для UserControl, но Auto (вместо *) для высоты строк внутри UserControl.

Объяснение : «Авто» означает : столько места, сколько необходимо (что вам нужно), тогда как «*» означает: пропорциональная доля всего доступного пространства (в результате в распределении 1/2, 1/4, 1/4).

Поскольку вы хотите, чтобы UserControl использовал все доступное пространство, Stretch является правильным вариантом (это означает именно это). Установите одну высоты строк внутри UserControl обратно на "*", если вы хотите, чтобы эта строка занимала оставшееся доступное пространство.

1 голос
/ 22 января 2010

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

  • Авторазмер (как уже упоминалось)
  • DockPanel с каждым значением Dock = Top - это будет иметь эффект, аналогичный VerticalAlignment = Top, но последний DataGrid (только 1) будет растягиваться, чтобы заполнить оставшееся пространство. Также плохо, если первый или второй занимают больше места, чем существует, потому что они вытесняют других.
  • Установите MinHeight / MaxHeight в сочетании с двумя другими изменениями в ваших DataGrids, чтобы они не вышли из-под контроля. Это избавляет от некоторой гибкости автоматической разметки в обмен на то, чтобы убедиться, что все отображается.

Помимо этих, вы можете попробовать что-то более сложное, например, создать пользовательскую панель (или найти ту, что уже сделал кто-то другой), или создать MultiValueConverter, который может рассчитать соответствующие параметры высоты (или MinHeight, MaxHeight) для каждого DG или строки на основе высота UC и каждого из DG.

0 голосов
/ 06 октября 2011

Просто хотел решить эту проблему. Со временем решение, которое я предоставил выше, просто не соответствовало ожиданиям пользователей. Теперь я перешел на такую ​​схему:

<ScrollViewer VerticalScrollBarVisibility="Auto">
   <Grid>
      <!-- row definitions -->
      <KentBoogart's Resizer ResizeDirection="South">
         <DataGrid/>
      </kb:Resizer>
      <kb:Resizer ResizeDirection="South">
         <DataGrid/>
      </kb:Resizer>
   </Grid>
</ScrollViewer>

В другом месте, где я использовал эту идиому, я установил Resizer, чтобы MaxHeight был привязан к ActualHeight ScrollViewer, чтобы он не выходил из-под контроля. Этот дизайн может немного запутать общую полосу прокрутки, а также полосы прокрутки в DataGrid, но с хорошими границами и полями это не так уж плохо.

0 голосов
/ 23 января 2010

Ну, вот что я закончил. В основном это то, что я хочу от макета. Чуть больше кода позади, чем хотелось бы, ну да ладно.

В моем обработчике событий DataContextChanged:

//for each grid
_reportObserver = new PropertyObserver<ItemCollection>(PrimaryGrid.Items)
    .RegisterHandler(c => c.Count, c => UpdateMaxHeight(PrimaryGrid));
UpdateMaxHeight(PrimaryGrid);

PropertyObserver от http://joshsmithonwpf.wordpress.com/2009/07/11/one-way-to-avoid-messy-propertychanged-event-handling/

//Lots of ugly hard-coding     
private void UpdateMaxHeight(DataGrid grid)
{
   double header_height = grid.ColumnHeaderHeight;
   if (double.IsNaN(header_height))
      header_height = 22;
   double margin_height = grid.Margin.Bottom + grid.Margin.Top;
   grid.MaxHeight = header_height + margin_height + grid.Items.Count * (grid.RowHeight+2);

   UpdateLayout(); //this is key for changes to number of items at runtime
}

Даже после установки MaxHeight в DataGrid все еще было некрасиво, поэтому мне также пришлось установить максимальную высоту для RowDefinition. Но это все еще не правильно, в результате чего добавление margin_height выше.

<RowDefinition Height="*" MaxHeight="{Binding ElementName=PrimaryGrid, Path=MaxHeight}"/>

В какой-то момент я приму к сведению мои необязательные детали строки в моем некрасивом коде максимальной высоты.

Что касается Top vs Stretch, то по другим причинам у меня появился контроль пользователя в ListView. Теперь все размеры хороши.

Еще раз спасибо за просмотр моей проблемы.

...