WPF的FlowDocument表 - 自动调整选项?(WPF FlowDocument Table

2019-07-20 00:39发布

我希望有一个表,根据内容逻辑大小的列。 这是可能在WPF?

替代文字http://img43.imageshack.us/img43/2640/flowdocument.jpg

这里是我正在使用的代码:

<Window x:Class="FlowDocument.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type TableCell}">
            <Setter Property="BorderBrush" Value="Gray" />
            <Setter Property="BorderThickness" Value="3" />


        </Style>
        <Style TargetType="{x:Type Paragraph}">
            <Setter Property="Padding" Value="2, 2, 2, 2" />
        </Style>
    </Window.Resources>
    <Grid>
        <FlowDocumentScrollViewer>
            <FlowDocument>
                <Table>
                    <Table.Columns>
                        <TableColumn Background="LightBlue" />
                        <TableColumn Background="Coral" />
                    </Table.Columns>
                    <TableRowGroup>
                        <TableRow>
                            <TableCell>
                                <Paragraph>This is a long piece of text</Paragraph>
                            </TableCell>
                            <TableCell>
                                <Paragraph>This isn't</Paragraph>
                            </TableCell>
                        </TableRow>
                        <TableRow>
                            <TableCell>
                                <Paragraph>This is a another long piece of text. The column should be wider than the other one!</Paragraph>
                            </TableCell>
                            <TableCell>
                                <Paragraph>Ditto</Paragraph>
                            </TableCell>
                        </TableRow>
                    </TableRowGroup>
                </Table>
            </FlowDocument>
        </FlowDocumentScrollViewer>
    </Grid>
</Window>

Answer 1:

它不太你要找什么,而是你可以这样做

<Table.Columns>
    <TableColumn Background="LightBlue" Width="2*"  />
    <TableColumn Background="Coral" Width="*" />
</Table.Columns>


Answer 2:

它通过确定一列的最宽细胞的期望宽度是可能的。 最宽的细胞可以通过所有的行循环确定所述小区的希望宽度和记忆的最大值来确定。

在这个例子中,所有列都进行了优化。 19值可能会导致左右单元格边距加上单元格边框厚度。

void autoresizeColumns(Table table)
{
    TableColumnCollection columns = table.Columns;
    TableRowCollection rows = table.RowGroups[0].Rows;
    TableCellCollection cells;
    TableRow row;
    TableCell cell;

    int columnCount = columns.Count;
    int rowCount = rows.Count;
    int cellCount = 0;

    double[] columnWidths = new double[columnCount];
    double columnWidth;

    // loop through all rows
    for (int r = 0; r < rowCount; r++)
    {
        row = rows[r];
        cells = row.Cells;
        cellCount = cells.Count;

        // loop through all cells in the row    
        for (int c = 0; c < columnCount && c < cellCount; c++)
        {
            cell = cells[c];
            columnWidth = getDesiredWidth(new TextRange(cell.ContentStart, cell.ContentEnd)) + 19;

            if (columnWidth > columnWidths[c])
            {
                columnWidths[c] = columnWidth;
            }
        }
    }

    // set the columns width to the widest cell
    for (int c = 0; c < columnCount; c++)
    {
        columns[c].Width = new GridLength(columnWidths[c]);
    }
}


double getDesiredWidth(TextRange textRange)
{
    return new FormattedText(
        textRange.Text,
        CultureInfo.CurrentCulture,
        FlowDirection.LeftToRight,
        new Typeface(
            textRange.GetPropertyValue(TextElement.FontFamilyProperty) as FontFamily,
            (FontStyle)textRange.GetPropertyValue(TextElement.FontStyleProperty),
            (FontWeight)textRange.GetPropertyValue(TextElement.FontWeightProperty),
            FontStretches.Normal),
            (double)textRange.GetPropertyValue(TextElement.FontSizeProperty),
        Brushes.Black,
        null,
        TextFormattingMode.Display).Width;
}


Answer 3:

事实上,微软建议使用一个网格,而不是表用于此目的: docs.microsoft.com:表VS网

唉,电网不支持简单的网格线开箱。 微软称Grid.ShowGridLines仅仅是为设计目的,并绘制相当丑陋虚线。 项目建立在微软希望你自己绘制网格线。 如何懒惰是从微软?

下面是一些示例代码如何可以做到这一点:

<FlowDocumentScrollViewer>
  <FlowDocument>
    <BlockUIContainer>
      <Grid HorizontalAlignment="Left" RenderOptions.EdgeMode="Aliased" UseLayoutRounding="True">
        <Grid.ColumnDefinitions>
          <ColumnDefinition/>
          <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.Resources>
          <Style TargetType="Border">
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="Padding" Value="2,0,3,0"/>
          </Style>

        </Grid.Resources>
        <Border Grid.Row="0" Grid.Column="0" BorderThickness="1,1,1,1">
          <TextBlock Text="AAA"/>
        </Border>
        <Border Grid.Row="0" Grid.Column="1" BorderThickness="0,1,1,1">
          <TextBlock Text="BBB"/>
        </Border>
        <Border Grid.Row="1" Grid.Column="0" BorderThickness="1,0,1,1">
          <TextBlock Text="CCC"/>
        </Border>
        <Border Grid.Row="1" Grid.Column="2" BorderThickness="0,0,1,1">
          <TextBlock Text="QgQ"/>
        </Border>
      </Grid>
    </BlockUIContainer>
  </FlowDocument>
</FlowDocumentScrollViewer>

其主要思想是设置每个文本框的框内,并决定对哪些方面需要一个边界每个边界。

为了得到精确的1个像素线,必须设置Grid.RenderOptions.EdgeMode="Aliased"Grid.UseLayoutRounding="True"



文章来源: WPF FlowDocument Table - AutoFit option?