DataGrid列未正确自动调整大小

时间:2013-07-08 17:25:44

标签: wpf datagrid wpfdatagrid

我的应用程序中有一个DataGrid控件:

<DataGrid AutoGenerateColumns="False"
          BorderThickness="1"
          CanUserDeleteRows="False"
          CanUserReorderColumns="False"
          CanUserResizeColumns="True"
          CanUserResizeRows="False"
          CanUserSortColumns="True"
          EnableColumnVirtualization="True"
          EnableRowVirtualization="True"
          FontSize="16"
          FontWeight="Bold"
          IsReadOnly="True"
          Grid.Column="0"
          Grid.ColumnSpan="2"
          Grid.Row="2"
          Margin="5"
          Name="PendingRowsGrid"
          SelectionUnit="FullRow"
          ScrollViewer.CanContentScroll="True"
          ScrollViewer.HorizontalScrollBarVisibility="Auto"
          ScrollViewer.VerticalScrollBarVisibility="Auto"
          ToolTip="Number of rows pending transmission"
          Visibility="{Binding Converter={StaticResource BoolToHide}, Path=AdvancedSettings.RunningStandAlone, RelativeSource={RelativeSource AncestorType={x:Type cs:Dashboard}}}">
    <DataGrid.Columns>
        <cs:ExtendedTextColumn Binding="{Binding Mode=OneWay, Path=Value.DataTypeDisplay}"
                               Header="Data Type"
                               Width="*" />
        <cs:ExtendedTextColumn Binding="{Binding Converter={StaticResource CountConverter}, ConverterParameter='#,##0', Mode=OneWay, Path=Value.ToEoc}"
                               Header="To EOC"
                               HorizontalAlignment="Right"
                               Width="Auto" />
        <cs:ExtendedTextColumn Binding="{Binding Converter={StaticResource CountConverter}, ConverterParameter='#,##0', Mode=OneWay, Path=Value.FromEoc}"
                               Header="From EOC"
                               HorizontalAlignment="Right"
                               Width="Auto" />
    </DataGrid.Columns
</DataGrid>

第一列左对齐,最后两列需要右对齐。此外,最右边的2列需要调整其宽度以适应列中最宽的值。

以下是ExtendedTextColumn类的代码:

public class ExtendedTextColumn : DataGridTextColumn {

    public static readonly DependencyProperty HorizontalAlignmentProperty =
        DependencyProperty.Register( "HorizontalAlignment", typeof( HorizontalAlignment ), typeof( ExtendedTextColumn ),
                                     new PropertyMetadata( HorizontalAlignment.Stretch ) );

    public static readonly DependencyProperty VerticalAlignmentProperty =
        DependencyProperty.Register( "VerticalAlignment", typeof( VerticalAlignment ), typeof( ExtendedTextColumn ),
                                     new PropertyMetadata( VerticalAlignment.Stretch ) );

    public HorizontalAlignment HorizontalAlignment {
        get { return (HorizontalAlignment) GetValue( HorizontalAlignmentProperty ); }
        set { SetValue( HorizontalAlignmentProperty, value ); }
    }

    public VerticalAlignment VerticalAlignment {
        get { return (VerticalAlignment) GetValue( VerticalAlignmentProperty ); }
        set { SetValue( VerticalAlignmentProperty, value ); }
    }

    protected override FrameworkElement GenerateElement( DataGridCell cell, object dataItem ) {
        FrameworkElement element = base.GenerateElement( cell, dataItem );

        // Set the FrameworkElement's HorizontalAlignment and VeritcalAligment properties
        element.HorizontalAlignment = HorizontalAlignment;
        element.VerticalAlignment   = VerticalAlignment;
        return element;
    }

    protected override FrameworkElement GenerateEditingElement( DataGridCell cell, object dataItem ) {
        TextBox textBox = (TextBox) base.GenerateEditingElement( cell, dataItem );

        // Set the TextBox's TextAlignment and VeritcalAligment properties
        textBox.TextAlignment            = GetTextAlignment();
        textBox.VerticalContentAlignment = VerticalAlignment;
        return textBox;
    }

    private TextAlignment GetTextAlignment() {
        switch ( HorizontalAlignment ) {
            case HorizontalAlignment.Center:
                return TextAlignment.Center;

            case HorizontalAlignment.Left:
                return TextAlignment.Left;

            case HorizontalAlignment.Right:
                return TextAlignment.Right;

            default:
                return TextAlignment.Justify;
        }
    }
}

}

问题是,如果显示XAML,最右边的两列不能正确调整大小。我还尝试将DataGridTemplateColumns用于最右边的两列:

        <DataGridTemplateColumn Header="To EOC"
                                HeaderStyle="{StaticResource CenteredHeaderText}"
                                Width="Auto">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock TextAlignment="Right" 
                               Text="{Binding Converter={StaticResource CountConverter}, ConverterParameter='#,##0', Mode=OneWay, Path=Value.ToEoc}" 
                               VerticalAlignment="Center" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="From EOC"
                                HeaderStyle="{StaticResource CenteredHeaderText}"
                                Width="Auto">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock TextAlignment="Right" 
                               Text="{Binding Converter={StaticResource CountConverter}, ConverterParameter='#,##0', Mode=OneWay, Path=Value.FromEoc}" 
                               VerticalAlignment="Center" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

但是,这些也不合适。在这两种情况下,一到一个半字符被切断。对于原始XAML(使用ExtendedTextColumn类),它是最左边的字符被切断;在第二个XAML(DataGridTemplateColumn案例)中,它是最正确的角色。

我尝试更改原始XAML,因此DataGrid使用DataGridTextColumns代表最右边的两列,并且这些列的大小合适。这让我相信DataGridDataGridTextColumn类在其他两种情况下没有完成,以确定列的宽度,但我的ExtendedTextColumn类下降了来自DataGridTextColumn。我很茫然。

有没有人对如何让它正常工作有任何建议?

1 个答案:

答案 0 :(得分:1)

玩Xaml&amp;在一天的大部分时间里,我都想出了一些几乎可以工作的东西。

首先,我停止使用我的类,而是使用类似于以下内容的XAML代替右侧两列:

<DataGridTextColumn Binding="{Binding Value.FromEoc, ConverterParameter=#\,##0, Converter={StaticResource CountConverter}, Mode=OneWay}"
                    Header="From EOC"
                    HeaderStyle="{StaticResource CenteredHeaderText}"
                    MinWidth="80"
                    Width="*">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

我认为,由于DataGridTextColumn本身已正确调整大小,因此可以解决这个问题。唉,事实并非如此。专栏的结果是1/2字符太窄了!

所以最后,我受到了抨击。最初的问题是,如果要显示的位数为8或更大,则列太窄。我将第一列的Width更改为Auto,将最后两列的Widths更改为*。这些列现在足够宽,在数字位数大于12之前我不应该有问题,并且我们不应该在生产系统中有那么多位数。