必要な動作を得るには、おそらく のコントロール テンプレートを変更する必要がありDataGrid
ます。
コードを見てください。DataGridView
私が思うに、WinFormsの外観にかなり近づきました。
余分な列を削除するには、 からフィラー列を削除する必要がありますDataGridColumnHeadersPresenter
。ついコメントアウトしてしまいました。残りはデフォルトのテンプレートです。
もう 1 つの変更は、 の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
でDataGridRows
、left
.NET 4 と .NET 4.5 の両方で機能します。のテンプレート全体を置き換える必要はもうありません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>