WPF - определите ширину для FlowDocument - PullRequest
2 голосов
/ 13 мая 2009

Я работаю в C # и VS2008.

У меня есть приложение WPF, содержащее FlowDocument, который содержит абзац, который содержит ряд довольно коротких строк (то есть Spans и LineBreaks). Однако длина линий варьируется. Мне бы хотелось, чтобы ширина FlowDocument была достаточно большой, чтобы вместить самую длинную из этих строк без переноса, но не шире, чтобы не тратить пространство.

Помещение в столбец сетки с Width = Auto не работает: FlowDocument всегда использует максимально допустимую ширину, поскольку FlowDocument может корректно переноситься для соответствия разным значениям ширины.

Я мог бы пройтись по строкам, генерируя их в коде, и определить ширину для каждого, но я не вижу свойства Width в классах Span или Run.

Есть идеи, как автоматически или вручную установить ширину для этого документа?


Я использовал предложенную AndrewS идею и перешел из FlowDocument в StackPanel с метками, каждая из которых содержит строку. Разметка XAML

<Border BorderThickness="2" Margin="2" BorderBrush="Black">
    <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
        <StackPanel 
         Orientation="Vertical"
            x:Name="itemsStackPanel" />
    </ScrollViewer>
</Border>

Код создает пролеты и добавляет их следующим образом:

        Label itemLabel = new Label();
        // pad left and right, keep close top and bottom
        itemLabel.Padding = new Thickness(2,0,2,0);
        itemLabel.Content = contentSpan;
        this.itemsStackPanel.Children.Add(itemLabel);

Размерирование теперь идеально, и единственное препятствие заключается в том, что шрифт не выглядит точно так же, как рядом с ним FlowDocument, несмотря на то, что семейство шрифтов и размер шрифта совпадают (пользовательский интерфейс Segoe, 15pt), и что Метки выглядят намного дальше друг от друга, чем строки в FlowDocument. Я задал это как отдельный вопрос

Ответы [ 2 ]

1 голос
/ 03 января 2010

У меня похожая ситуация, но я хочу измерить ширину линии. К сожалению, RichTextBox имеет две важные функции, связанные вместе: текст переднего плана и цвета фона при запуске и форматировании. Мне нужны цвета, и мне наплевать на форматирование. У меня есть «сетка» символов, и я хочу запустить несколько «курсоров» над персонажами. Я планирую реализовать цвета фона в качестве отдельных курсоров и использовать цвета переднего плана для окраски синтаксиса. Это шрифт с фиксированной шириной, и я не хочу, чтобы сетка была перенесена, так что по сути не нужно форматировать. Я полагаю, я мог бы реализовать это как сетку, в которой я устанавливаю строки и столбцы во время выполнения в соответствии с размером моего текста, но это выглядит как реальная трата ресурсов - особенно если файл действительно большой - то есть сетка 100x100 с отдельный ярлык в каждой клетке. Первоначально, и, возможно, немного наивно, я думал, что с RichTextBox все будет просто, но я начинаю верить в обратное. Другая возможность - поместить холст поверх стандартного TextBox и рисовать самостоятельно, но мне приходится иметь дело со всем, поскольку прокрутка материала и т. Д. Звучит некрасиво и подвержена ошибкам. Мой код сейчас:

    private static void SetRichText(RichTextBox rtb, string[] arLines)
    {
        Contract.Assert(arLines.All(l => l.Length == arLines[0].Length));
        FlowDocument doc = new FlowDocument { PageWidth = 65535.0 };

        IEnumerable<Paragraph> iep = arLines.Select(l =>
                                            {
                                                Paragraph p = new Paragraph();
                                                p.Inlines.Add(new Run(l));
                                                return p;
                                            });
        foreach (Paragraph p in iep)
        {
            doc.Blocks.Add(p);
        }

        rtb.Document = doc;
        doc.PagePadding = new Thickness(0, 0, 0, 0);

        Rect rcEOL = rtb.Document.ContentStart.GetPositionAtOffset(arLines[0].Length).GetCharacterRect(LogicalDirection.Forward);
        // TODO : Figure why I have to add a fudge factor in the following (I'm guessing some margin I'm unaware of in the 
        // RichTextBox somewhere)...
        rtb.Document.PageWidth = rcEOL.Right + 18;
    }

Как я утверждаю в комментариях, похоже, это работает для моего текущего случая, но я действительно не проверял его со многими другими, так что я не уверен, работает ли он в целом, плюс в любом случае, это просто большой шаг, который Я не могу объяснить, поэтому я хотел бы знать, как справиться с этим правильно. Спасибо за любые ответы. О, я должен указать, как я уже говорил выше, что for является фиксированным шагом, и все входящие строки имеют одинаковую длину, как указано в контракте, поэтому все строки должны быть точно одинаковой длины.

1 голос
/ 13 мая 2009

Вы можете заменить строки другим типом элемента, таким как TextBlocks или Labels (для которых вы можете управлять переносом) или Glyphs, которые «предназначены для представления документов фиксированного формата и сценариев печати».

Я действительно не думаю, что вы хотите попробовать измерить линии и увеличить ширину документа.

...