如何让WPF DataGrid单元格正确对齐而不会使新行上的可选区域变小?

时间:2011-10-17 22:30:31

标签: wpf xaml datagrid

我正在使用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,这不会影响可选择的新行的宽度 区域。
  3. 有用的东西:

    使用@AngelWPF答案中的信息,我可以使用CellStyle更改为使用ElementStyle,如下所示:

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

    成了

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

5 个答案:

答案 0 :(得分:80)

您可以ElementStyleDataGridTextColumn定位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> 

答案 1 :(得分:13)

只是想为将来的代码搜索添加更多示例。

我把它放在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>

然后在datagrid中:

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

此右对齐文本,仍然启用排序。文本框填充单元格,在这种情况下使用bool转换器着色。

答案 2 :(得分:5)

您可以尝试解决方法:

           <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                        <TextBlock HorizontalAlignment="Right" Text="{Binding Path=ImpaId}"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

答案 3 :(得分:5)

我遇到了类似的问题,并通过在Blend中覆盖DataGridCell的样式找到了另一种解决方案。

原始样式中更改的项目是样式本身中VerticalAlignmentVerticalContentAlignment的设置者,用于拉伸单元格本身以及模板属性中的VerticalAlignment="Center"HorizontalAlignment="Right"对齐内容。将这些值更改为对齐单元格内容所需的任何值。

可以删除样式的其余部分,以便使用基本样式的设置(使用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>

答案 4 :(得分:2)

我遇到了同样的问题,现在解决了。如果要在c#代码中执行此操作,则需要设置一堆setter:

DataGridTextColumn numColumn = new DataGridTextColumn
Style s = new Style();
s.Setters.Add(new Setter(HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
s.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Right));
s.Setters.Add(new Setter(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
s.Setters.Add(new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Right));
numColumn.CellStyle = s;