WPF DataGrid 文本被截断

问题描述 投票:0回答:2

我的 WPF 4.5 应用程序有一个小(但烦人)的视觉错误,其中

DataGrid
的单元格在加载时被切断: initial load Dropbox 屏幕截图链接

但是一旦您调整窗口大小(单击右上角的方形按钮)并重新最大化它,

DataGrid
的单元格就会按预期显示: after resizing Dropbox 截图链接

在 XAML 中,每列的宽度都设置为

Auto
,“名称”列除外,即
*
。我可以采取什么措施来防止这种视觉错误的发生/我正在做的事情是否导致了这个错误?

这是我的 XAML:

<DataGrid ItemsSource="{Binding Datasets, NotifyOnTargetUpdated=True}" Name="dsDatagrid" SelectionMode="Extended" MouseDoubleClick="ViewDataset">
<DataGrid.Style>
    <Style BasedOn="{StaticResource {x:Type DataGrid}}" TargetType="DataGrid">
        <Setter Property="Visibility" Value="Visible"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsWorking}" Value="True">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.Style>
<i:Interaction.Triggers>
    <i:EventTrigger EventName="TargetUpdated">
        <cmd:EventToCommand Command="{Binding CollectionChangedCommand}"/>
    </i:EventTrigger>
    <i:EventTrigger EventName="SelectionChanged">
        <cmd:EventToCommand Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=dsDatagrid, Path=SelectedItems}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
    <DataGridTemplateColumn Header="" Width="Auto">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Name="NameCell" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Center">
                    <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.BackupSingleCommand}" CommandParameter="{Binding}" Style="{StaticResource BackupSingleButtonStyle}" Margin="5 10"/>
                    <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.DeleteSingleCommand}" CommandParameter="{Binding}" Style="{StaticResource DeleteSingleButtonStyle}" Margin="5 10"/>
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="ID" Width="Auto" Binding="{Binding Id}"/>
    <DataGridTemplateColumn Header="Name" Width="*">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" TextWrapping="Wrap"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="Source Images" Width="Auto" Binding="{Binding SourceImages.Count, StringFormat={}{0:N0}, TargetNullValue=NONE}"/>
    <DataGridTextColumn Header="Start Time" Width="Auto" Binding="{Binding StartTime, StringFormat={}{0:MM}/{0:dd}/{0:yy} {0:HH}\:{0:mm}\:{0:ss}}"/>
    <DataGridTextColumn Header="End Time" Width="Auto" Binding="{Binding EndTime, StringFormat={}{0:MM}/{0:dd}/{0:yy} {0:HH}\:{0:mm}\:{0:ss}, TargetNullValue=In Progress}"/>
    <DataGridTemplateColumn Header="Status" Width="Auto">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Status}" TextWrapping="WrapWithOverflow"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

如果相关,这是我的

DataGrid
风格:

<Style TargetType="DataGridColumnHeader">
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="FontSize" Value="16"/>
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="Background" Value="{StaticResource BannerNormalBrush}"/>
    <Setter Property="Padding" Value="24 10"/>
</Style>
<Style TargetType="DataGridRow">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="FontSize" Value="16"/>
</Style>
<Style TargetType="DataGridCell">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Padding" Value="24 0"/>
    <Setter Property="Foreground" Value="{StaticResource TextBlockDisabledForegroundBrushDark}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridCell">
                <Border Name="Border" Padding="{TemplateBinding Padding}" Background="Transparent">
                    <ContentPresenter VerticalAlignment="Center"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource DataGridRowSelectedBrush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style TargetType="DataGrid">
    <Setter Property="GridLinesVisibility" Value="None"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="RowBackground" Value="{StaticResource DataGridOddRowBackgroundBrush}"/>
    <Setter Property="AlternatingRowBackground" Value="{StaticResource DataGridEvenRowBackgroundBrush}"/>
    <Setter Property="CanUserResizeRows" Value="False"/>
    <Setter Property="CanUserResizeColumns" Value="False"/>
    <Setter Property="IsReadOnly" Value="True"/>
    <Setter Property="Margin" Value="5"/>
    <Setter Property="SelectionMode" Value="Single"/>
    <Setter Property="RowHeaderWidth" Value="0"/>
    <Setter Property="CanUserReorderColumns" Value="False"/>
    <Setter Property="CanUserSortColumns" Value="False"/>
    <Setter Property="AutoGenerateColumns" Value="False"/>
    <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="EnableRowVirtualization" Value="True"/>
    <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
    <Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
    <Setter Property="Background" Value="Transparent"/>
</Style>
wpf xaml datagrid
2个回答
1
投票

还没有真正尝试过你的代码,但只是通过查看它,我有一种预感......

StackPanel 在计算可用空间时往往会出现问题,因此您的问题可能是由列的 DataTemplate 内的 StackPanel 引起的,它无法在加载时将其大小正确传达给列。

我的建议是将 StackPanel 更改为另一个面板。在这种情况下,一个好的旧网格就可以很好地工作,我敢打赌这次您不会看到任何故障。

<DataGridTemplateColumn Header="" Width="Auto">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid Name="NameCell" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Button Grid.Column="0" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.BackupSingleCommand}" CommandParameter="{Binding}" Style="{StaticResource BackupSingleButtonStyle}" Margin="5 10"/>
                <Button Grid.Column="1" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.DeleteSingleCommand}" CommandParameter="{Binding}" Style="{StaticResource DeleteSingleButtonStyle}" Margin="5 10"/>
            </StackPanel>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

0
投票

此问题已解释那里。在我的情况下,也可能是在您的情况下,数据网格绑定到一个

ObservableCollection
,稍后通过如下所示的代码进行更新:

Documents.Clear();
foreach (Document doc in documents)
{
    Documents.Add(doc);
}

遗憾的是,数据网格不会更新列宽度,然后

ObservableCollection
内容会发生变化,因此列的宽度将保持不变(默认情况下是标题宽度)。

我提供的链接在答案中给出了一些解决方案,就我而言,我执行了以下操作:

// Don't bind anymore in the XAML but pass data directly to the ItemsSource (which will trigger the update)
DataGridDocuments.ItemsSource = documents;
// Or call UpdateLayout then the data is updated
Documents.Clear();
foreach (Document doc in documents)
{
    Documents.Add(doc);
}
DataGridDocuments.UpdateLayout();
© www.soinside.com 2019 - 2024. All rights reserved.