繁体   English   中英

WPF Grid和DataGrid大小调整

[英]WPF Grid and DataGrid sizing

我试图使用的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作为Grid的最后一个成员放在我的Window中,唯一一个Height="*" 我对DataGrid的大小调整方式有疑问。

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

如果我将VerticalAlignment设置为Top ,则网格的大小似乎与其内容相当,除非在UserControl的底部留下一个莫名其妙的空白。 我使用Snoop和UserControlRowDefinition具有正确的ActualHeight ,但UserControl只使用它的一部分 - RowDefinition 80%左右。

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

简介 :对UserControl使用Stretch ,但对UserControl中的行高使用Auto (而不是* )。

说明 :“自动” 表示 :尽可能多的空间(这是您想要的),而“*”表示:所有可用空间的比例份额(产生1 / 2,1 / 4,1 / 4分布) )。

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

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

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

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

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

在我的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。 现在一切都很好。

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

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

<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中的滚动条有点混淆,但是边框和边距都很好,也不算太糟糕。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM