Как заставить ячейку WPF DataGrid выравниваться по правому краю, не делая крошечную область в новой строке крошечной? - PullRequest
57 голосов
/ 18 октября 2011

Я использую WPF4.0 DataGrid.При двойном щелчке по ячейке в новой строке все работает нормально , если Я не добавил стиль ячейки в этот столбец.Например, у меня есть числовой столбец, в котором я хочу, чтобы данные были выровнены по правому краю, чтобы xaml выглядел следующим образом

<DataGridTextColumn Binding="{Binding Path=ImpaId}"
                    CellStyle="{StaticResource CellRightAlign}">
     <DataGridTextColumn.Header>
          <TextBlock  Style="{StaticResource DataGridHeader}">Impa</TextBlock>
     </DataGridTextColumn.Header>
</DataGridTextColumn>

Где стиль в общем ресурсе просто:

<Style x:Key="CellRightAlign">
    <Setter Property="Control.HorizontalAlignment"
            Value="Right" />
</Style>

результирующая область выбора в новой строке показывается на изображении в виде этой маленькой синей области. Это очень маленькая цель, по которой пользователь может попасть, и это наиболее вероятный столбец, с которого он захочет начать новую строку.

DataGrid cell with tiny width

Если я удалю CellStyle, область будет работать как нужно, но, конечно, я потеряю правильное выравнивание.

DataGrid cell with proper width

Кто-нибудь знает, как добиться обоих?

Вещи, которые я пробовал

  1. Установка TargetNullValue для привязки к формату с некоторой шириной.Это работает для существующих строк, но не влияет на новую строку.
  2. Установка MinWidth для столбца, это не влияет на ширину области выбора новой строки.

Сработало:

Используя информацию из ответа @AngelWPF, я смог перейти от использования CellStyle к использованию ElementStyle следующим образом:

<DataGridTextColumn Binding="{Binding Path=ImpaId}"
                    CellStyle="{StaticResource CellRightAlign}">

Стал

<DataGridTextColumn Binding="{Binding Path=ImpaId}"
                    ElementStyle="{StaticResource CellRightAlign}">

Ответы [ 4 ]

81 голосов
/ 18 октября 2011

Вы можете применить ElementStyle к DataGridTextColumn, нацеленному на TextBlock, и выровнять по правому краю, что будет работать.

      <DataGridTextColumn Binding="{Binding Path=ImpaId}">
          <DataGridTextColumn.Header>
               <TextBlock  Style="{StaticResource
                                  DataGridHeader}">
                    Impa
               </TextBlock>
          </DataGridTextColumn.Header>
          <DataGridTextColumn.ElementStyle>
              <Style TargetType="{x:Type TextBlock}">
                  <Setter Property="HorizontalAlignment" Value="Right" />
              </Style>
          </DataGridTextColumn.ElementStyle>
      </DataGridTextColumn> 
13 голосов
/ 24 февраля 2016

Просто хотел добавить дополнительные примеры для будущих поисков кода.

Я поместил это в начало файла xaml:

<UserControl.Resources>
    <Style TargetType="{x:Type TextBlock}" x:Key="RightCell">
        <Setter Property="Background" Value="{Binding Included, Converter={StaticResource BoolToColorConverter}}"/>
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="TextAlignment" Value="Right"/>
    </Style>
</UserControl.Resources>

А затем в сетку данных:

<DataGridTextColumn Header="Excluded" Binding="{Binding Excluded}" ElementStyle="{StaticResource RightCell}"/>

Это право выравнивает текст, и сортировка по-прежнему включена.Текстовое поле заполняет ячейку и в этом случае окрашивается с помощью конвертера bool.

5 голосов
/ 03 июля 2012

У меня была похожая проблема, и я нашел другое решение, переписав стиль для DataGridCell в Blend.

Измененные элементы из первоначального стиля являются установщиками для VerticalAlignment и VerticalContentAlignment в самом стиле, чтобы растянуть саму ячейку, и VerticalAlignment="Center" и HorizontalAlignment="Right" в свойстве Template для выравнивания содержимого. Измените эти значения на все необходимое для выравнивания содержимого ячеек.

Остальная часть стиля может быть удалена, так что будут использоваться настройки из базового стиля (при использовании StaticResource стиль равен BasedOn). Однако я оставил стиль, как его создал Blend.

Этот полученный XAML-код должен быть включен в ресурсы управления:

<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource ResourceKey={x:Type DataGridCell}}">
    <Setter Property="VerticalAlignment" Value="Stretch" />
    <Setter Property="VerticalContentAlignment" Value="Stretch" />

    <!-- Additional styles, can be removed to fall back to base styles -->
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ContentPresenter
                        ContentTemplate="{TemplateBinding ContentTemplate}"
                        Content="{TemplateBinding Content}"
                        ContentStringFormat="{TemplateBinding ContentStringFormat}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Right"
                        />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="BorderBrush" Value="{DynamicResource {ComponentResourceKey ResourceId=FocusBorderBrushKey, TypeInTargetAssembly={x:Type DataGrid}}}"/>
        </Trigger>
    </Style.Triggers>
</Style>
5 голосов
/ 18 октября 2011

Вы можете попробовать обойти:

           <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                        <TextBlock HorizontalAlignment="Right" Text="{Binding Path=ImpaId}"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...