【问题标题】:wpf Datagrid columns width fail in ListBoxwpf Datagrid列宽度在ListBox中失败
【发布时间】:2013-03-31 16:16:50
【问题描述】:

我有一个包含从 UserControl 派生的项目的 ListBox。具体的 UserControl 包含(除其他外)一个 DataGrid。基本上我无法更改具体的 UserControl(仅出于测试目的而更改;它的第三方类型)。一旦将一个列宽设置为“*”,所有列的 DataGrid 列宽就会被破坏,这是填充整个空间所必需的。

我可以用一个简化的例子来重现它(没有用户控件)。因此,如果我将 DataGrid 添加为 ListBoxItem,指定列宽“*”会破坏列宽。顺便说一句,用户也不能再调整列的大小了。

简单示例:

<Window x:Class="DataGridSpike.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListBox HorizontalContentAlignment="Stretch" >
        <!-- Column width is basically ok but only since not "*" -->
        <DataGrid>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Column1"/>
                <DataGridTextColumn Header="Column2"/>
                <DataGridTextColumn Header="Column3"/>
            </DataGrid.Columns>
        </DataGrid>

        <!-- Broken column width: -->
        <DataGrid>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Column1"/>
                <DataGridTextColumn Header="Column2" Width="*"/>
                <DataGridTextColumn Header="Column3"/>
            </DataGrid.Columns>
        </DataGrid>
    </ListBox>
</Grid>

有谁知道如何解决这个问题?

问候

【问题讨论】:

    标签: wpf datagrid listbox


    【解决方案1】:

    根据 sa_ddam213 的建议,我发现了一个有效的组合。 到目前为止我没有其他想法。

    我用 ListView 包裹 DataGrid,从 ListView 中移除所有“装饰”,并将 GridViewColumn 的宽度绑定到 ListView 的 ActualWidth。也许 ListView 以外的某些控件也可以工作。我只是在玩 ListView。简单的边框是行不通的。

    必须以某种方式调整边距,并且右侧有一个我无法消除的间隙(但我可以忍受)。除非我禁用 DataGrid 的 Horizo​​ntalScrollBarVisibility,否则在用鼠标拖动寡妇宽度时,我会得到奇怪的闪烁鬼水平滚动条。

    所以这里的 XAML 似乎就足够了。 请注意,实际的 ListView kludge 将是具体 UserControl 的一部分。 但是,以下(简化的)代码显示了我所做的:

    <Window x:Class="DataGridSpike.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
            <ListBox HorizontalContentAlignment="Stretch">
                <!-- ListView is just a kludge -->
                <ListView HorizontalContentAlignment="Stretch" Padding="-4,2,-10,0" BorderThickness="0">
                    <ListView.View>
                        <GridView>
                            <GridView.ColumnHeaderContainerStyle>
                                <Style>
                                    <Setter Property="FrameworkElement.Visibility" Value="Collapsed"/>
                                </Style>
                            </GridView.ColumnHeaderContainerStyle>
                            <GridViewColumn Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" />
                        </GridView>
                    </ListView.View>
                    <DataGrid HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"
                        Padding="-2,0" HorizontalScrollBarVisibility="Disabled">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Column1"/>
                            <DataGridTextColumn Header="Column2" Width="1*" />
                            <DataGridTextColumn Header="Column3"  />
                        </DataGrid.Columns>
                    </DataGrid>
                </ListView>
            </ListBox>
        </Grid>
    </Window>
    

    不过,这只是一种解决方法。仍然欢迎任何合理的“修复”。

    【讨论】:

      【解决方案2】:

      您可以将DataGrid 宽度绑定回ListBox ActualWidth,这将为DataGrid 提供一个不同于Auto 的实际大小,并且* 的大小应该可以工作。

      <!-- Broken column width: -->
      <DataGrid Width="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsPresenter}}}" Margin="-2,0,0,0">
          <DataGrid.Columns>
              <DataGridTextColumn Header="Column1"/>
              <DataGridTextColumn Header="Column2" Width="*"/>
              <DataGridTextColumn Header="Column3"/>
          </DataGrid.Columns>
      </DataGrid>
      

      但是,由于内容和ListBox 的边缘之间存在一些间距,您可能需要稍微调整Margin(就像我在上面所做的那样)以避免DataGrid 超出向右。

      结果:

      【讨论】:

      • 这是一个很有前途的方法。不幸的是,这仅适用于我的简单示例。正如我所提到的,实际的 dataGrid 在 UserControl 中的“某处”。事实上,它是 Grid 的一部分,它是 Expander 的一部分,并且缩进了一些像素。所以 ItemPresenter 的 ActualWidth 不是 DataGird 所需的宽度,我无法对差异做出任何假设。所以我尝试将 DataGrid 嵌套到另一个 Grid 中并将宽度绑定到该 Gird 的 ActualWidth。放大窗口时效果很好,但缩小窗口时 DataGrid 不再缩小。
      【解决方案3】:

      Width="Auto" 将解决问题。您还可以指定“MaxWidth”来限制列宽扩展。

            <DataGrid.Columns>
                      <DataGridTextColumn Header="Column1"/>
                      <DataGridTextColumn Header="Column2" Width="Auto" MaxWidth="200" />
                      <DataGridTextColumn Header="Column3"/>
            </DataGrid.Columns>
      

      希望这会有所帮助。

      【讨论】:

      • 恐怕不会。 Width="Auto" 将根据内容调整大小,而 "*" 将扩展 到可用空间。我需要后者。顺便说一句,如果未指定 Width,则 Width="Auto" 是默认值 - AFAIK。所以 Width="Auto" 将与我的示例中的第一个 ListBoxItem 相同。
      猜你喜欢
      • 2015-03-20
      • 2012-06-06
      • 2011-11-02
      • 2010-11-11
      • 2011-08-22
      • 2013-07-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      相关资源
      最近更新 更多