我的 WPF 4.5 应用程序有一个小(但烦人)的视觉错误,其中
DataGrid
的单元格在加载时被切断:
Dropbox 屏幕截图链接
但是一旦您调整窗口大小(单击右上角的方形按钮)并重新最大化它,
DataGrid
的单元格就会按预期显示:
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>
还没有真正尝试过你的代码,但只是通过查看它,我有一种预感......
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>
此问题已解释那里。在我的情况下,也可能是在您的情况下,数据网格绑定到一个
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();