2016-06-10 10 views
0

Eine weitere WPF DataGrid-bezogene Frage.WPF DataGrid gruppierte Zeilen in Expander fügt zusätzliche Spalte auf der rechten Seite hinzu, verschwindet, wenn alle Expander geschlossen sind

Ich habe ein DataGrid, dessen Zeilen gruppiert sind, und jede Gruppe ist unter einem Expander-Steuerelement. Es gibt zwei Spalten pro Zeile. Standardmäßig habe ich alle Expander geöffnet. Die Breite der zweiten Spalte ist auf "*" gesetzt und die Zeilenüberschriften wurden bereits deaktiviert.

Wenn ich alle Expander schließe, ändert das Layout ein winziges bisschen und verschiebt die Expandersteuerung ein wenig nach links. Wenn ich einen der Expander öffne, verschiebt er das kleinste Bit nach rechts. Ich merke auch, dass bei geöffnetem Expander die Spaltenüberschriften auf der rechten Seite eine zusätzliche Spalte zeigen, wodurch die horizontale Bildlaufleiste erscheint.

Wie kann ich die Datagrid-Deklaration anpassen, damit diese zusätzliche Spalte nicht vorhanden ist/erscheint, wenn ein Expander geöffnet ist?

<Grid> 
    <ScrollViewer VerticalScrollBarVisibility="Auto" 
       HorizontalScrollBarVisibility="Disabled" > 
    <DataGrid AutoGenerateColumns="False" 
       ItemsSource="{Binding Path=MyCollection}" 
       GridLinesVisibility="None" 
       CanUserAddRows="False" 
       CanUserDeleteRows="False" 
       CanUserReorderColumns="False" 
       CanUserSortColumns="False" 
       CanUserResizeColumns="False" 
       CanUserResizeRows="False" 
       HeadersVisibility="Column"> 
     <DataGrid.Resources> 
     <ResourceDictionary> 
      <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> 
      <Setter Property="Background" Value="{x:Null}" /> 
      <Setter Property="BorderBrush" Value="{x:Null}" /> 
      <Style.Triggers> 
       <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="Background" Value="{x:Null}" /> 
       <Setter Property="Foreground" Value="Black" /> 
       <Setter Property="BorderBrush" Value="{x:Null}" /> 
       </Trigger> 
      </Style.Triggers> 
      </Style> 
      <Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}"> 
      <Setter Property="Margin" Value="4" /> 
      <Setter Property="Background" Value="{x:Null}" /> 
      <Setter Property="BorderBrush" Value="{x:Null}" /> 
      <Style.Triggers> 
       <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="Background" Value="{x:Null}" /> 
       <Setter Property="Foreground" Value="Black" /> 
       <Setter Property="BorderBrush" Value="{x:Null}" /> 
       </Trigger> 
      </Style.Triggers> 
      </Style> 
     </ResourceDictionary> 
     </DataGrid.Resources> 
     <DataGrid.GroupStyle> 
     <GroupStyle> 
      <GroupStyle.Panel> 
      <ItemsPanelTemplate> 
       <DataGridRowsPresenter /> 
      </ItemsPanelTemplate> 
      </GroupStyle.Panel> 
      <GroupStyle.ContainerStyle> 
      <Style TargetType="{x:Type GroupItem}"> 
       <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type GroupItem}"> 
        <Expander Margin="4" 
           IsExpanded="True"> 
         <Expander.Header> 
         <StackPanel Orientation="Horizontal" 
            Margin="4"> 
          <TextBlock FontWeight="Bold" 
            FontSize="14" 
            Text="{Binding Path=Name}" /> 
         </StackPanel> 
         </Expander.Header> 
         <ItemsPresenter /> 
        </Expander> 
        </ControlTemplate> 
       </Setter.Value> 
       </Setter> 
      </Style> 
      </GroupStyle.ContainerStyle> 
     </GroupStyle> 
     </DataGrid.GroupStyle> 
     <DataGrid.Columns> 
     <DataGridTemplateColumn Width="Auto"> 
     ... 
     </DataGridTemplateColumn> 
     <DataGridTemplateColumn Width="*"> 
     ... 
     </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
    </ScrollViewer> 
</Grid> 

Antwort

0

Dies ist Teil Hack, Teil echte Antwort, denke ich.

Hack-Teil: Damit die horizontale Bildlaufleiste nicht angezeigt wird, habe ich sie einfach in der DataGrid-Deklaration deaktiviert. Um sicherzustellen, dass die Spalte nicht auf der rechten Seite etwas abrasiert wurde, setzte ich den Zeilenabstand und den Abstand im Stil, den ich zum Deaktivieren der Auswahlfarbe verwendet habe.

Realteil: Einstellung der vertikalen Bildlaufleiste, um immer ordnungsgemäß zu funktionieren, solange die Höhe der zweiten Zeile des äußersten Rasters auf "*" (Sternchen) gesetzt ist. Dies stellt sicher, dass das DataGrid die richtige Menge an Speicherplatz verwendet, wenn ein Expander geöffnet wird und es zu viele Zeilen zum Anzeigen gibt.

Die endgültige Datagrid Deklaration sieht wie folgt aus:

<Grid> 
    <Grid.RowDefinitions> 
    <RowDefinition Height="Auto" /> 
    <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 

    <Label Content="Import Data Mappings" 
     FontWeight="Bold" 
     HorizontalAlignment="Center" 
     Margin="4" 
     Padding="4" 
     Grid.Row="0" /> 
    <DataGrid AutoGenerateColumns="False" 
      VerticalScrollBarVisibility="Visible" 
      HorizontalScrollBarVisibility="Disabled" 
      ItemsSource="{Binding Path=MyGroupedCollection, Mode=OneWay}" 
      HeadersVisibility="Column" 
      Grid.Row="1" 
      ... > 
    <DataGrid.Resources> 
     <ResourceDictionary> 
     <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> 
      <Setter Property="Background" Value="White" /> 
      <Setter Property="BorderBrush" Value="{x:Null}" /> 
      <Style.Triggers> 
      <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="Background" Value="White" /> 
       <Setter Property="Foreground" Value="Black" /> 
       <Setter Property="BorderBrush" Value="{x:Null}" /> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     <Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}"> 
      <Setter Property="Margin" Value="0,4,0,4" /> 
      <Setter Property="Background" Value="White" /> 
      <Setter Property="BorderBrush" Value="{x:Null}" /> 
      <Style.Triggers> 
      <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="Background" Value="White" /> 
       <Setter Property="Foreground" Value="Black" /> 
       <Setter Property="BorderBrush" Value="{x:Null}" /> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </ResourceDictionary> 
    </DataGrid.Resources> 

    <DataGrid.GroupStyle> 
     <GroupStyle> 
     <GroupStyle.Panel> 
      <ItemsPanelTemplate> 
      <DataGridRowsPresenter /> 
      </ItemsPanelTemplate> 
     </GroupStyle.Panel> 
     <GroupStyle.ContainerStyle> 
      <Style TargetType="{x:Type GroupItem}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
       <ControlTemplate TargetType="{x:Type GroupItem}"> 
        <Expander Margin="4" 
          IsExpanded="True"> 
        <Expander.Header> 
         <StackPanel Orientation="Horizontal" 
            Margin="4"> 
         <TextBlock FontWeight="Bold" 
            FontSize="14" 
            Text="{Binding Path=Name}" /> 
         </StackPanel> 
        </Expander.Header> 
        <ItemsPresenter /> 
        </Expander> 
       </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
      </Style> 
     </GroupStyle.ContainerStyle> 
     </GroupStyle> 
    </DataGrid.GroupStyle> 

    <DataGrid.Columns> 
     <DataGridTemplateColumn Width="Auto"> 
     <DataGridTemplateColumn.HeaderTemplate> 
      ... 
     </DataGridTemplateColumn.HeaderTemplate> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
      <TextBlock .../> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
     <DataGridTemplateColumn Width="*"> 
     <DataGridTemplateColumn.HeaderTemplate> 
      ... 
     </DataGridTemplateColumn.HeaderTemplate> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
      <DockPanel LastChildFill="True"> 
       <Button Style="{DynamicResource ResourceKey=MyButtonStyle}" 
         Content="Button Text" 
         Command="{Binding Path=MyButtonCommand}" 
         DockPanel.Dock="Left"/> 
       <ComboBox Margin="4" 
         Padding="4" 
         SelectedItem="{Binding Path=MySelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
         ItemsSource="{Binding Path=MyAvailableFields}" 
         DockPanel.Dock="Left"> 
       <ComboBox.ItemTemplate> 
        <DataTemplate> 
        <TextBlock VerticalAlignment="Center" 
           HorizontalAlignment="Center" 
           Text="{Binding Path=MyDisplayName}" /> 
        </DataTemplate> 
       </ComboBox.ItemTemplate> 
       </ComboBox> 
      </DockPanel> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
    </DataGrid> 
</Grid> 
0

Das DataGrid selbst hat einen eingebauten Scrollviewer, so dass der äußere nicht benötigt wird. Ich denke, es ist der Scrollviewer des DataGrid, der das Problem verursacht. Versuchen von außen Scroll loszuwerden und fügen Sie die Attribute an das Datagrid, wie folgt aus:

<DataGrid AutoGenerateColumns="False" 
    ScrollViewer.VerticalScrollBarVisibility="Auto" 
    ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
    ... 
    > 
    ... 
</DataGrid> 

Wenn Sie die außerhalb Scroll aus irgendeinem Grund brauchen, sie halten aber nach wie vor das Datagrid HorizontalScrollBarVisibility deaktivieren.

+0

Es scheint, dass explizit die Bildlaufleiste Eigenschaften festlegen, wie Sie vorschlagen, in ein anderes Verhalten führt, aber nicht das Verhalten ich suche. Mit diesen Einstellungen erhalte ich keine Bildlaufleisten, selbst wenn ich Zeilenelemente über das Ende des Rasters hinaus habe. Die zusätzliche Spalte scheint jetzt keine Probleme mit der Größenänderung zu verursachen, aber jede Zeile ist auf der rechten Seite leicht abgeschnitten, so als ob der Container Platz hinter dem sichtbaren Bereich reserviert. – sethlj11