7

基本的に、WPFDataGridコントロールのレイアウトをWinFormsDataGridViewとまったく同じようにしたいと思います。

より具体的には、これが私が探している動作です。

  • グリッドコントロールは、指定されたスペースを占有する必要があります(つまり、親コントロールで使用できるスペースがいくらでもあります)。ここでは、列ではなく、コントロールのみを参照しています。

  • 作成された列(自動または手動)は、このスペースをすべて占有する場合と占有しない場合があります。

  • 列の作成後に余分なスペースが残っている場合は、このスペースを埋めるために最後の列を拡張しないでください。

  • 列の作成後に余分なスペースが残っている場合は、この余分なスペースを埋めるために何も入っていない空の列を作成しないでください。

私の知る限り、WPFでは、最後の2つの箇条書きは相互に排他的であるように思われるため、どちらかを選択する必要があります。誰かが両方を行う方法を見つけましたか?かなり検索してみましたが、探しているものが見つかりませんでしたが、見つけた投稿はすべて数年前のものである傾向があるので、誰かがこのことを理解してくれることを願っています。

編集:sa_ddam213、これが私があなたの提案をテストするためにまとめた簡単なxamlプロジェクトです。

<Window x:Class="DataGridFix.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataGridFix"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <ObjectDataProvider x:Key="data"
                    ObjectType="{x:Type local:TestObject}"
                    MethodName="GetTestData" />
    </Window.Resources>
    <StackPanel>
        <DataGrid HorizontalAlignment="Left"  ColumnWidth="Auto" Height="150" VerticalAlignment="Top" ItemsSource="{Binding Source={StaticResource data}}" />
    </StackPanel>
</Window>

そして、これが背後にあるコードです:

名前空間DataGridFix{publicclass TestObject {public int Id {get; セットする; } public string Name {get; セットする; }

    public static List<TestObject> GetTestData()
    {
        var items = new List<TestObject>();

        items.Add(new TestObject() { Id = 1, Name = "Joe" });
        items.Add(new TestObject() { Id = 2, Name = "Matt" });
        items.Add(new TestObject() { Id = 3, Name = "Hal" });

        return items;
    }
}

}

本当にあなたの提案から私が見る唯一の注目すべきことは、Horizo​​ntalAlignmentをLeftに設定することです。私はそれを行い、ColumnWidthをさまざまな設定に設定しようとしましたが、それぞれに同じ問題がありました(*もちろん...技術的にはそれを台無しにすることはできますが、それについては説明しません)。

マウスを使用して任意の列を展開してから列サイズを小さくすると、空のフィラー列が表示されます。私があなたの投稿から指摘した他の唯一の違いは、DataGridが複数あるため、DataGridをStackPanelに配置したことです。私はそれを試してみましたが、同じ結果になりました。私がしていることとあなたが提案したことの間に他の違いを見つけたら、私に知らせてください。

4

2 に答える 2

7

必要な動作を得るには、おそらく のコントロール テンプレートを変更する必要があり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 では、期待どおりにサイズが変更されます。

必要な動作を得るための新しいソリューションは、実際には以前のものよりもはるかに単純です。

を に設定し、フィラー列を削除するだけHorizontalAlignmentDataGridRowsleft.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>
于 2013-01-02T01:25:57.230 に答える
5

WPF の列には多くのレイアウト オプションがあり、表示するものを選択するだけです。

  • ピクセル
  • SizeToCells
  • サイズからヘッダーへ
  • 自動
  • 比例(*)

を に設定するHorizontalAlignmentLeft、選択したDataGridに基づいてコンテンツに合わせてサイズが変更されColumnWidthます。

以下は、使用可能な列設定の例です。

   <StackPanel>
        <DataGrid HorizontalAlignment="Left"  ColumnWidth="100" Height="64" VerticalAlignment="Top" ItemsSource="{Binding ElementName=UI, Path=GridItems}" />
        <DataGrid HorizontalAlignment="Left"  ColumnWidth="SizeToCells" Height="64" VerticalAlignment="Top" ItemsSource="{Binding ElementName=UI, Path=GridItems}" />
        <DataGrid HorizontalAlignment="Left"  ColumnWidth="SizeToHeader" Height="64" VerticalAlignment="Top" ItemsSource="{Binding ElementName=UI, Path=GridItems}" />
        <DataGrid HorizontalAlignment="Left"  ColumnWidth="Auto" Height="64" VerticalAlignment="Top" ItemsSource="{Binding ElementName=UI, Path=GridItems}" />
        <DataGrid HorizontalAlignment="Left"  ColumnWidth="*" Height="64" VerticalAlignment="Top" ItemsSource="{Binding ElementName=UI, Path=GridItems}" />
    </StackPanel>

ここに画像の説明を入力

于 2012-12-30T10:28:29.267 に答える