为了获得您想要的行为,您可能必须修改DataGrid
.
看一下代码。我已经非常接近DataGridView
我认为的 WinForms 外观。
要删除额外的列,您必须从DataGridColumnHeadersPresenter
. 我刚刚评论了它。其余的只是默认模板。
另一个修改是对模板的DataGrid.
By 设置HorizontalAlignment="Left"
,ScrollContentPresenter
行不再占据控件的所有宽度。
这些是我对默认模板所做的仅有的 2 处更改。
<Style TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Grid>
<!-- Remove this filler column -->
<!--<DataGridColumnHeader x:Name="PART_FillerColumnHeader" IsHitTestVisible="False" />-->
<ItemsPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
Padding="{TemplateBinding Padding}">
<ScrollViewer Focusable="false" Name="DG_ScrollViewer">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Command="{x:Static DataGrid.SelectAllCommand}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}"
Style="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type DataGrid}, ResourceId=DataGridSelectAllButtonStyle}}"
Focusable="false"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.All}}" />
<DataGridColumnHeadersPresenter Grid.Column="1" Name="PART_ColumnHeadersPresenter"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"/>
<!-- Set HorizontalAlignment="Left" to have the rows only take up the width they need and not fill the entire width of the DataGrid -->
<ScrollContentPresenter HorizontalAlignment="Left" x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" />
<ScrollBar Grid.Row="1" Grid.Column="2" Name="PART_VerticalScrollBar"
Orientation="Vertical"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<Grid Grid.Row="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar Grid.Column="1"
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
更新
.NET 4 和 .NET 4.5 之间确实存在差异。
我在装有 Visual Studio 2012 的 Windows 8 机器上进行开发,因此作为测试,我尝试以 .NET 4 为目标,看看我是否可以复制错误的行为。但它仍然工作得很好。
可以肯定的是,我尝试在仅安装了 .NET 4 的另一台机器上运行该应用程序,当使列变大然后再次变小时,这里出现了空行。
问题似乎DataGridRows
是行为不正常。在仅安装 .NET 4 的机器上运行时,它们会在缩小列时保持当前大小。在 .NET 4.5 上,它们按预期调整大小。
获得所需行为的新解决方案实际上比以前的解决方案简单得多。
通过简单地将 设置为并HorizontalAlignment
删除填充列,它可以在 .NET 4 和 .NET 4.5 上运行。并且不再需要更换整个模板。DataGridRows
left
DataGrid
<Style TargetType="DataGridRow">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style TargetType="DataGridColumnHeadersPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Grid>
<ItemsPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>