Граница DataGridRow поверх границы DataGrid

#wpf

#wpf

Вопрос:

Я пытаюсь отобразить границу DataGridRow поверх границы DataGrid. Возможно ли это вообще с помощью стиля или я должен использовать пользовательский элемент оформления?

введите описание изображения здесь

Я хочу добиться чего-то подобного:

введите описание изображения здесь

Я пытался использовать Panel.ZIndex и ClipToBounds="False" , но, похоже, в этом случае это не работает.

 <Style x:Key="MyDataGridRowStyle" TargetType="{x:Type DataGridRow}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
    <Setter Property="ValidationErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <TextBlock
                    Margin="2,0,0,0"
                    VerticalAlignment="Center"
                    Foreground="Red"
                    Text="!" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridRow}">
                <Border
                    x:Name="DGR_Border"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    ClipToBounds="False"
                    SnapsToDevicePixels="True">
                    <SelectiveScrollingGrid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

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

                        <DataGridCellsPresenter
                            Grid.Column="1"
                            ItemsPanel="{TemplateBinding ItemsPanel}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />

                        <DataGridDetailsPresenter
                            Grid.Row="1"
                            Grid.Column="1"
                            SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"
                            Visibility="{TemplateBinding DetailsVisibility}" />

                        <DataGridRowHeader
                            Grid.RowSpan="2"
                            SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                            Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}" />
                    </SelectiveScrollingGrid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsNewItem" Value="True">
            <Setter Property="Margin" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NewItemMargin}" />
        </Trigger>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="BorderBrush" Value="Red" />
            <Setter Property="Margin" Value="-1,-1,-1,-1" />
            <Setter Property="Panel.ZIndex" Value="123" />
        </Trigger>
    </Style.Triggers>
</Style>
  

Ответ №1:

Из-за жесткости WPF это невозможно использовать Panel.ZIndex таким образом, поскольку его можно использовать только на том же уровне. Несколько решений этой проблемы:

  • Пользовательский редактор, который рисует прямоугольник выделения для выбранных строк (должен использовать слой adorner выше / на том же уровне границы DataGrid) пользовательский шаблон можно использовать для добавления AdornerDecorator чуть выше границы.

  • Добавьте Canvas и <Rectangle x:Name="PART_SelectionRectangle" /> в шаблон DataGrid, подкласс DataGrid и измените положение прямоугольника в Canvas на основе текущего выделения в вашей подклассовой DataGrid.

Я не уверен, есть ли какой-либо способ сделать это только с помощью style без подкласса DataGrid / добавления к нему обработчиков событий, возможно, с помощью пользовательского конвертера, который вычисляет положение и размер прямоугольника выделения и свойства привязки Rectangle с использованием этого конвертера.