如何在不使新行上的可选区域变小的情况下使 WPF DataGrid 单元格右对齐?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7800367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:08:09  来源:igfitidea点击:

How to get a WPF DataGrid cell to right align without making the selectable area on a new row tiny?

wpfxamldatagrid

提问by Tod

I'm using a WPF4.0 DataGrid. When double clicking on a cell in a new row everything works fine unlessI've added a cell style to that column. For example, I have a numeric column where I want the data right aligned so the xaml looks like this

我正在使用 WPF4.0 DataGrid。双击新行中的单元格时,一切正常,除非我向该列添加了单元格样式。例如,我有一个数字列,我希望数据正确对齐,因此 xaml 看起来像这样

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

Where the style in a shared resource is just:

共享资源中的样式只是:

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

The resulting selectable area on a new row is shown in the image as that small blue area.This is a very small target for the user to hit, and this happens to be the most likely column they will want to start with on a new row.

新行上的结果可选区域在图像中显示为蓝色小区域。这是用户点击的一个非常小的目标,这恰好是他们最有可能希望从新行开始的列.

DataGrid cell with tiny width

DataGrid cell with tiny width

If I remove the CellStyle, the area works as desired but of course I lose the right alignment.

如果我删除 CellStyle,该区域会按需要工作,但当然我会失去正确的对齐方式。

DataGrid cell with proper width

DataGrid cell with proper width

Does anyone know how to achieve both?

有谁知道如何实现两者?

Things I tried

我尝试过的事情

  1. Setting TargetNullValue on the binding to a format with some width. This works on existing rows but has no effect on a new row.
  2. Setting MinWidth on the column, this did not affect the width of the new row selectable area.
  1. 将绑定上的 TargetNullValue 设置为具有一定宽度的格式。这适用于现有行,但对新行没有影响。
  2. 在列上设置 MinWidth,这不会影响新行可选区域的宽度。

Thing that worked:

有用的东西:

Using the information from the answer by @AngelWPF I was able to change from using CellStyle to using ElementStyle as follows:

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

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

Became

成为

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

回答by WPF-it

You could apply ElementStyleon the DataGridTextColumntargetted to TextBlockand right align that, it would work.

您可以应用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> 

回答by Rahbek

Just wanted to add to more examples for future code searches.

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

I put this in the top of the xaml file:

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

And then in the datagrid:

然后在数据网格中:

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

This right aligns the text and sorting is still enabled. The textbox fills the cell and in this case is colored using a bool converter.

此右侧对齐文本并且排序仍处于启用状态。文本框填充单元格,在这种情况下使用布尔转换器着色。

回答by mattanja

I just had a similar problem and found another solution by overwriting the Style for the DataGridCell in Blend.

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

The changed items from the original style are the setters for VerticalAlignmentand VerticalContentAlignmentin the Style itself to stretch the cell itself and VerticalAlignment="Center"and HorizontalAlignment="Right"in the Template property to align the content. Change these values to whatever you need to align the cells content.

更改的项目从原来的风格是为制定者VerticalAlignmentVerticalContentAlignment在样式本身伸展细胞本身VerticalAlignment="Center"HorizontalAlignment="Right"在模板属性来对齐内容。将这些值更改为对齐单元格内容所需的任何值。

The rest of the style couldbe removed so that the settings from the base style will be used (using the StaticResource the style is BasedOn). However I left the style as Blend produced it.

风格的其余部分可以被去除,从而从基本样式的设置将用于(使用StaticResource的风格是支持算法FMP)。但是我离开了 Blend 制作它的风格。

This resulting XAML-Code should then be included into the controls resources:

然后应将生成的 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>

回答by MichaelS

You can try a work around :

您可以尝试解决:

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

回答by Christian

I had the same issue and got it solved now. If you want to do it inside the c# code, you need to set a bunch of setters:

我遇到了同样的问题,现在已经解决了。如果你想在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;