应用自定义样式时,DatGridCell会重置

时间:2019-05-23 16:22:16

标签: wpf xaml styles

我有一个包含数据的DataGrid,我想使该dataGrid中的所有数据都以其所在的DataGridCell为中心。

所以我做了如下操作(xaml文件)

<Window x:Class="WPF_Prj.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"
    xmlns:local="clr-namespace:WPF_Prj.View"
    xmlns:vm="clr-namespace:WPF_Prj.ViewModel"
    Title="[Portfolio] MainWindow" Height="500" Width="800">


<StackPanel Orientation="Vertical">
    <DataGrid x:Name="datagrid" AutoGenerateColumns="False" CanUserAddRows="False"
            Width="Auto" Margin="5,5,0,5" HorizontalAlignment="Left" CellEditEnding="datagrid_CellEndEditing">

        <DataGrid.Resources>
            <vm:PositiveConverter x:Key="PositiveConverter"/>                
            <Style TargetType="{x:Type DataGridCell}">
                <Setter Property="TextBlock.TextAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
            </Style>
        </DataGrid.Resources>

        <DataGrid.Columns>
            <DataGridTextColumn                             Header="Name"           Binding="{Binding Name}"                                    IsReadOnly="True"   Width="Auto"/>
            <DataGridTextColumn                             Header="Owned Qty"      Binding="{Binding OwnedQty}"                                IsReadOnly="True"   Width="Auto"/>
            <DataGridTextColumn x:Name="_UnitCost"          Header="Unit Cost"      Binding="{Binding UnitCost}"            IsReadOnly="True"                       Width="Auto"/>
            <DataGridTextColumn x:Name="_MarketCost"        Header="Market Cost"    Binding="{Binding MarketCost}"          IsReadOnly="True"                       Width="Auto"/>
            <DataGridTextColumn     Header="Ordered Qty"    Binding="{Binding OrderedQty,       Mode=TwoWay }"                                 IsReadOnly="False"  Width="Auto">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell" >
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ColorCost}" Value="-1">
                                <Setter Property="Background" Value="Moccasin"/>
                                <Setter Property="Foreground" Value="Black"/>
                                <Setter Property="BorderThickness" Value="3"/>
                                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding ColorCost}" Value="1">
                                <Setter Property="Background" Value="GreenYellow"/>
                                <Setter Property="Foreground" Value="Black"/>
                                <Setter Property="BorderThickness" Value="3"/>
                                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn   Header="Confirmed Qty"  Binding="{Binding ConfirmedQty, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay }" IsReadOnly="True"   Width="Auto"/>
        </DataGrid.Columns>

    </DataGrid>
    <StackPanel Name="ButtomsZone" Orientation="Horizontal">
        <Button x:Name="YellOrders"  Content="Simulate Orders" Width="125" FontFamily="Fire Code" Click="YellOrders_Click" Margin="18,0" Height="25"/>
        <Button x:Name="Confirm"   Content="Confirm Orders"  Width="125" FontFamily="Fire Code" Click="Confirm_Click" Margin="25,0" IsEnabled="False"/>            
        <ComboBox>
            <ComboBoxItem IsSelected="True">Prioritize cheap goods</ComboBoxItem>
            <ComboBoxItem>Prioritize expensive goods</ComboBoxItem>    
        </ComboBox>
    </StackPanel>
</StackPanel>
</Window>

因此,如下图所示,除了Ordered Qty以外的所有数据均已拉伸并居中对齐,而我试图强制对齐toString()却没有成功。

enter image description here

问题是我如何使该列伸展并使其内容居中?预先谢谢你。

1 个答案:

答案 0 :(得分:1)

您正在该列上显式设置CellStyle,这意味着它不使用您在DataGrid.Resources中定义的隐式DataGridCell样式。

很容易通过以下两种方式进行修复:将这两个对齐设置器添加到“订购数量”样式中,或者更好的是,将BasedOn属性用于 base 默认样式上的样式,这将使其继承默认样式具有的所有内容:

<DataGridTextColumn.CellStyle>
    <Style 
        TargetType="DataGridCell" 
        BasedOn="{StaticResource {x:Type DataGridCell}}"
        >
        <Style.Triggers>
            <DataTrigger Binding="{Binding ColorCost}" Value="-1">

如果下周在默认单元格样式中添加其他内容,它将自动包含在“订购数量”的专用样式中。

更新:对齐发生了什么事?

单元格中显示的值为文本,显示在TextBox或TextBlock中。默认情况下,文本内部在TextBox或TextBlock中是左对齐的。因此,您必须设置TextBlock.TextAlignment,它将由TextBox或TextBlock继承,并使其居中。

默认情况下,TextBox或TextBlock会被拉伸以填充DataGridCell的整个宽度,因为DataGridCell会对内容进行处理。您不需要任何这些Horizo​​ntalAlignment设置器。他们是多余的。出于这个原因,我将它们删除:我不喜欢将无操作代码保留在原处,因为明年我或其他人将重新访问该代码,并可能会浪费时间以为它在那里。

在某些列表控件(如ListBox)中,项目内容保持对齐,您可能需要在ListBox上设置HorizontalContentAlignment。 DataGrid并非如此。实际上,如果您想看到一些奇怪的东西,请为您的隐式DataGridCellStyle尝试以下操作:

<DataGrid.Resources>
    <Style TargetType="{x:Type DataGridCell}">
        <Setter Property="TextBlock.TextAlignment" Value="Center"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
    </Style>
</DataGrid.Resources>

在这里,显示文本的控件仅与内容一样宽。它仍然使内容居中,但您无法分辨,因为两边都没有空间。另外,线条看起来很有趣。