WPF Grid和DataGrid大小调整

时间:2010-01-21 20:36:13

标签: wpf datagrid grid size wpftoolkit

我正在尝试使用的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唯一成员VerticalAlignment。我对UserControl s的大小有问题。

如果我在Stretch中将Window的{​​{1}}设置为PrimaryGrid,则UserControl会获得Border的1/2高度,OtherGrid内的两个中的每个得到1/4。无论每个行的行数是多少,它们的大小都是这样的,使VerticalAlignment的垂直空间太小而滚动视图中的其他行具有非行空格。

如果我将Top设置为UserControl,则网格的内容看起来相当不错,除了RowDefinition底部留有一个莫名其妙的空格。我使用了Snoop,UserControl的{​​{1}}具有正确的ActualHeight,但UserControl只使用了其中一部分 - 80%左右。

我真的不介意我是否修复Stretch案例(如何使DataGrid拉伸不大于其行数?)或Top案例(如何我是否UserControl使用它可用的所有空间?)

4 个答案:

答案 0 :(得分:3)

摘要:对UserControl使用Stretch,但对于UserControl中的行高,请使用Auto(而不是*

解释:“自动”means:尽可能多的空间(这是你想要的),而“*”表示:所有可用空间的比例分配(导致1 / 2,1 / 4,1 / 4分布)。

由于您希望UserControl使用所有可用空间,Stretch是正确的选项(正是这意味着)。如果您希望此行占用剩余的可用空间,请将UserControl中行高的一个设置回“*”。

答案 1 :(得分:1)

这是一个常见的问题,你真正想要的是两种完全不同的布局行为:当有三个空间时自动调整大小,*没有时调整大小。您可以通过限制尝试一些快速修复:

  • 自动调整大小(如前所述)
  • DockPanel,每个设置为Dock = Top - 这将对VerticalAlignment = Top产生类似的效果,但最后一个DataGrid(仅1)将拉伸以填充剩余空间。如果第一个或第二个占用的空间比存在的多,那也很糟糕,因为它们会将其他空间推出去。
  • 将MinHeight / MaxHeight与DataGrids中的其他2个更改之一结合使用,以防止它们失控。这样可以放弃一些自动布局的灵活性,以确保一切都显示出来。

除此之外,您可以尝试更复杂的内容,例如创建自定义面板(或找到其他人已经制作的面板),或者创建一个MultiValueConverter,可以根据每个DG或行计算适当的高度(或MinHeight,MaxHeight)设置UC和每个DG的高度。

答案 2 :(得分:0)

嗯,这就是我最终的结果。它主要是从布局的角度来做我想要的。比我想要的更多的代码,但哦,好吧。

在我的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
}

即使在设置DataGrid的MaxHeight后,事情仍然很难看,所以我不得不在RowDefinition上设置最大高度。但这仍然是不对的,导致margin_height添加到上面。

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

在某些时候,我会在丑陋的最大高度代码中考虑我可选择的行详细信息。

就Top vs. Stretch而言,我最后因为其他原因而在ListView中使用了usercontrol。现在一切都很好。

再次感谢您查看我的问题。

答案 3 :(得分:0)

只是想跟进这个问题。随着时间的推移,我上面提供的解决方案不符合用户的期望。我现在改成了这样的计划:

<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绑定到ScrollViewer的ActualHeight,以防止它失去控制。这个设计可能会让整个滚动条与DataGrid中的滚动条有点混淆,但是边框和边距都很好,也不算太差。