DataGrid-列宽度未随 ItemsSource 更改而更新

发布于 2024-10-12 11:13:24 字数 1382 浏览 0 评论 0原文

XAML:

<DataGrid.Columns>
    <DataGridTextColumn x:Name="colDisplayName" Width="Auto" IsReadOnly="True" Header="Name" Binding="{Binding ssn.SSN_DISPLAY_NAME}"></DataGridTextColumn>
    <DataGridTextColumn x:Name="colValue" Width="Auto" Header="Value" Binding="{Binding ssv.SSV_VALUE}" CellStyle="{StaticResource SingleClickEditing}"></DataGridTextColumn>
    <DataGridTextColumn x:Name="colDescription" Width="Auto" IsReadOnly="True" Header="Description" Binding="{Binding ssn.SSN_DESCRIPTION}"></DataGridTextColumn>
    <DataGridTextColumn x:Name="colUnit" Width="Auto" IsReadOnly="True" Header="Unit Abbreviation" Binding="{Binding ssn.UNIT_TYPE.UNIT_NAME.UN_ABBREVIATION}"></DataGridTextColumn>
    </DataGrid.Columns>

CS:

private void tvSystemConfiguration_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
       {
           dgSystemSettings.ItemsSource =
               ((tvSystemConfiguration.SelectedItem as SYSTEM_SETTINGS_GROUP).SYSTEM_SETTINGS_NAMEs.Join
               (ssdc.SYSTEM_SETTINGS_VALUEs, x => x.SSN_ID, y => y.SSV_SSN_ID, (x, y) => new DataGridItem{ ssn = x, ssv = y })).ToList();
       }

当增加列大小时,列宽度会缩小以正确适应,但当减少列大小时,不会正确缩小以适应。在增加 ItemsSource 更新后,它不会减少列的大小。希望这是有道理的。任何帮助表示赞赏。谢谢。

XAML:

<DataGrid.Columns>
    <DataGridTextColumn x:Name="colDisplayName" Width="Auto" IsReadOnly="True" Header="Name" Binding="{Binding ssn.SSN_DISPLAY_NAME}"></DataGridTextColumn>
    <DataGridTextColumn x:Name="colValue" Width="Auto" Header="Value" Binding="{Binding ssv.SSV_VALUE}" CellStyle="{StaticResource SingleClickEditing}"></DataGridTextColumn>
    <DataGridTextColumn x:Name="colDescription" Width="Auto" IsReadOnly="True" Header="Description" Binding="{Binding ssn.SSN_DESCRIPTION}"></DataGridTextColumn>
    <DataGridTextColumn x:Name="colUnit" Width="Auto" IsReadOnly="True" Header="Unit Abbreviation" Binding="{Binding ssn.UNIT_TYPE.UNIT_NAME.UN_ABBREVIATION}"></DataGridTextColumn>
    </DataGrid.Columns>

CS:

private void tvSystemConfiguration_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
       {
           dgSystemSettings.ItemsSource =
               ((tvSystemConfiguration.SelectedItem as SYSTEM_SETTINGS_GROUP).SYSTEM_SETTINGS_NAMEs.Join
               (ssdc.SYSTEM_SETTINGS_VALUEs, x => x.SSN_ID, y => y.SSV_SSN_ID, (x, y) => new DataGridItem{ ssn = x, ssv = y })).ToList();
       }

Column widths shrink to fit correctly when increasing in column size but do not properly shrink to fit when decreasing in column size. It will not decrase the size of the column on an ItemsSource update after it has increased. Hope that makes sense. Any help is appreciated. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一瞬间的火花 2024-10-19 11:13:24

对我来说没有任何意义,抱歉。

我理解代码,但这部分:

当列大小增加时,列宽会缩小以正确适应,但确实如此
减小列尺寸时不能正确收缩以适应。它不会
在增加 ItemsSource 更新后减少列的大小

让我感到困惑,

我是这样理解的:

如果列内容的宽度增加,则列的宽度也会增加,但如果
内容的宽度减小,但列的宽度不变。

是这样吗?

如果是这样,这种行为是正常的:如果需要,Wpf 只会将数据网格的列宽设置为“自动”,即:内容无法完全显示。因此,当内容的宽度缩小时,列的大小不会调整,因为内容仍然可以完全看到。

我能看到强制 wpf 重新计算列宽度的唯一方法是将它们全部强制为 0,然后在后面的代码中返回到 auto,并抛出一两个 updateLayout() ,但这不是很好的编程:-/

编辑:
基本上,在您后面的代码中:

foreach (DataGridColumn c in dg.Columns)
    c.Width = 0;

// Update your DG's source here

foreach (DataGridColumn c in dg.Columns)
    c.Width = DataGridLength.Auto;

您可能需要一个或两个 dg.UpdateLayout() (在更新并可能设置回自动之后)

did not make any sense for me, sorry.

I understand the code, but this part:

Column widths shrink to fit correctly when increasing in column size but do
not properly shrink to fit when decreasing in column size. It will not
decrase the size of the column on an ItemsSource update after it has increased

has me puzzled

I understood this like that:

if the width of a column's content increases, the column's width increases, but if the
content's width decreases, the column's width does not.

Is that right ?

if so, this behaviour is normal: Wpf will just resize a datagrid's column width set to Auto if needed, i.e: the content cannot be displayed entirely. So when the content's width shrinks, the column does not resize as the content can still been seen entirely.

the only way I can see to force wpf to recalculate the columns' widths would be to force them all to 0 and then back to auto in the code behind, with one or two updateLayout() thrown in, but this is not very nice programming :-/

Edit:
basically, in your code behind:

foreach (DataGridColumn c in dg.Columns)
    c.Width = 0;

// Update your DG's source here

foreach (DataGridColumn c in dg.Columns)
    c.Width = DataGridLength.Auto;

and you probably need a dg.UpdateLayout() or two somewhere in there (after the update and the setting back to auto probably)

情绪 2024-10-19 11:13:24

为了方便大家,这里有一个基于 David 答案的扩展方法:

public static void AutoResizeColumnWidths(this System.Windows.Controls.DataGrid dataGrid)
{
    // http://stackoverflow.com/questions/4725724/wpf-datagrid-column-widths-not-updating-on-itemssource-change
    foreach (var column in dataGrid.Columns)
        column.Width = 0;

    dataGrid.UpdateLayout();

    foreach (var column in dataGrid.Columns)
        column.Width = System.Windows.Controls.DataGridLength.Auto;

    dataGrid.UpdateLayout();
}

以及它的调用方式:

dataGrid.AutoResizeColumnWidths();

For everyone's convenience, here is an extension method based on David's answer:

public static void AutoResizeColumnWidths(this System.Windows.Controls.DataGrid dataGrid)
{
    // http://stackoverflow.com/questions/4725724/wpf-datagrid-column-widths-not-updating-on-itemssource-change
    foreach (var column in dataGrid.Columns)
        column.Width = 0;

    dataGrid.UpdateLayout();

    foreach (var column in dataGrid.Columns)
        column.Width = System.Windows.Controls.DataGridLength.Auto;

    dataGrid.UpdateLayout();
}

And how it would be called:

dataGrid.AutoResizeColumnWidths();
李白 2024-10-19 11:13:24

屏幕上的闪烁更少,线条也更少,无需调用 updateLayout:

            foreach (DataGridColumn col in dg.Columns)
            {
                col.Width = DataGridLength.SizeToCells;
                col.Width = DataGridLength.Auto;
            }

Much less flash on screen and less lines, no call to updateLayout necessary:

            foreach (DataGridColumn col in dg.Columns)
            {
                col.Width = DataGridLength.SizeToCells;
                col.Width = DataGridLength.Auto;
            }
极度宠爱 2024-10-19 11:13:24

也许我可以帮忙。我遇到了同样的问题,我认为这是一个很好的解决方案。

private void DataGrid_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        DataGrid dg = (DataGrid)sender;
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            double width = 0;
            foreach (DataGridColumn column in dg.Columns)
            {
                width += column.ActualWidth;
            }
            dg.Width = width + 2;
        }
    }

Maybe I can help. I had the same problem and I found, I think, nice solution.

private void DataGrid_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        DataGrid dg = (DataGrid)sender;
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            double width = 0;
            foreach (DataGridColumn column in dg.Columns)
            {
                width += column.ActualWidth;
            }
            dg.Width = width + 2;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文