【问题标题】:properly resize wpf ListView's last column正确调整 wpf ListView 的最后一列的大小
【发布时间】:2010-12-24 18:00:53
【问题描述】:

如何正确处理 listview 的最后一列大小调整:

  1. listview 不显示丑陋且未使用的“额外”列(参见图 1,或 here 为例)
  2. (实际)最后一列被拉伸以填充剩余空间
  3. 水平滚动条不显示
  4. 在任何方向调整大小都不会留下伪影(见下文)

我已经为此苦苦挣扎了很长一段时间,但没有成功,网络上的大量搜索也没有提供任何见解。这是我到目前为止所拥有的:

  1. 我首先尝试调整最后一列的宽度以完全填满整个视图,但随后会弹出水平滚动条。所以现在我将所有列的 ColumnHeaderContainerStyle 设置为不显示任何内容的透明样式,并用实际样式覆盖每个 Column 上的 HeaderContainerStyle;对于最后一列,我将边距设为负值,以便填充源自额外列的额外空白空间。见图2

  2. 将最后一列的宽度计算为实际宽度与其他列宽度之和之间的差值,同时考虑边距/填充

  3. 与 2 相同;宽度不能太小,否则会显示水平滚动条

  4. 这是由 2 引入的:如果将最后一列的宽度设置为恒定值,我可以毫无问题地增长和缩小。使用代码拉伸列时,视图在增长时会正确拉伸,但在缩小部分列表视图的行时会消失。然而,列标题或多或少保持适当的大小,但仍然比正常小,见图 3。这让我觉得缩小有一些特别之处:我所做的计算是相同的,但在视觉上它不是。但是我找不到框架中发生这种情况的位置/方式。

图片:

Picture 1 http://deathwillendthiswar.dommel.be/default.jpg Picture 2 http://deathwillendthiswar.dommel.be/start.jpg Picture 3 http://deathwillendthiswar.dommel.be/afterdrag.jpg

用于拉伸的代码,应用于 ListView 调整大小处理程序中的最后一列

int StretchLastColWidth( ListView lv, int minWidth )
{
  double width = lv.ActualWidth;
  if( width <= 0 )
    return minWidth;

  GridView grdView = lv.View as GridView;
  for( int i = 0 ; i < grdView.Columns.Count - 1 ; ++i )
    width -= ( grdView.Columns[ i ].ActualWidth + 6 ); //padding?

  Decorator border = VisualTreeHelper.GetChild( lv, 0 ) as Decorator;
  ScrollViewer scroll = border.Child as ScrollViewer;
  if( scroll.ComputedVerticalScrollBarVisibility == System.Windows.Visibility.Visible )
    width -= 14; //my scrollbar is smaller than the system default..

  width -= 12  //comes from padding??

  if( width > minWidth )
    return Convert.ToInt32( width );
  else
    return minWidth;
}

Listview 的 xaml:

<ListView ItemContainerStyle="{StaticResource ListViewItemStyle}">
  <ListView.View>
    <GridView ColumnHeaderContainerStyle="{DynamicResource ListViewEmptyHeaderStyle}">
      <GridViewColumn Width="80" Header="Hdr0" HeaderContainerStyle="{DynamicResource ListViewHeaderStyle}"/>
      <GridViewColumn Header="Hdr1" HeaderContainerStyle="{DynamicResource ListViewLastHeaderStyle}"/>
    </GridView>
  </ListView.View>
</ListView>

如果真的需要,我可以发布整个模板;请注意,虽然我已经使用相当多的修改后的样式显示了图片,但使用标准 ListView 未修改时的结果完全相同。如果有人想尝试,请使用此样式查看项目行周围的边框:

<Style x:Key="ListViewItemStyle" TargetType ="{x:Type ListViewItem}">
  <Setter Property="BorderBrush" Value="White"/>
  <Setter Property="BorderThickness" Value="1"/>
  <Setter Property="Margin" Value="3,1"/> <!--if not used, border sticks to scrollbar etc-->
  <Setter Property="SnapsToDevicePixels" Value="true"/>
</Style>

【问题讨论】:

    标签: c# wpf xaml listview expression-blend


    【解决方案1】:

    查看这篇 CodeProject 文章:

    ListView Layout Manager By Jani Giannoudis

    【讨论】:

    • 我前段时间已经查过了;虽然这是一篇很棒的文章,但作者选择忽略了这样一个事实,即他遇到了与我发布的完全相同的问题:起初,他的行边框总是看起来像我的第三张图片中的那个。其次,如果我调整他的代码来解决这个问题(添加一个简单的'width -= 10'左右),边框会正确显示,但是从我缩小视图的那一刻起,它的右边缘就会消失,就像我的代码一样。
    • 我认为唯一真正解决这个问题的方法是从头开始编写一个 GridViewHeaderRowPresenter 和 GridViewRowPresenter,或者使用某种 IL 反汇编程序来复制和修改框架的......
    • 你可能是对的;谢天谢地,我使用这个 ListViews 的软件不是真正的生产软件,所以也许到时候我会深入研究它,有人已经找到了合适的解决方案。
    猜你喜欢
    • 2013-01-19
    • 2012-06-02
    • 2011-08-22
    • 2017-01-24
    • 1970-01-01
    • 2011-08-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多