WPF: Как сделать RichTextBox похожим на TextBlock? - PullRequest
13 голосов
/ 28 апреля 2011

Как я могу сделать RichTextBox без полей, границ, отступов и т. Д.?Другими словами, отображать содержимое так же, как TextBlock, не так ли?Я пробовал это:

<RichTextBox Margin="0" Padding="0" Grid.Row="0" BorderThickness="0" >
    <FlowDocument >
        <Paragraph>LLL</Paragraph>
    </FlowDocument>
</RichTextBox>
<TextBlock>LLL</TextBlock>

Но результат все равно не то, что я хочу:

enter image description here

До содержимого документа еще есть место (итакже может быть после, в верхней или нижней части документа ...).Как я могу удалить его?


Если вам интересно, зачем мне это нужно: я пытаюсь ответить HB на мой вопрос Создать редактор гитарных аккордов в WPF работать с кернингом и я не хочу иметь неестественный пробел между символами.


Редактировать

Так что это не ControlTemplate, по крайней мере, неттолько потому, что следующий код даст точно такой же результат (как на рисунке выше):

<RichTextBox Margin="0" Padding="0" Grid.Row="0" BorderThickness="0">
    <RichTextBox.Template>
        <ControlTemplate>
            <ScrollViewer Padding="0" Margin="0" x:Name="PART_ContentHost"/>
        </ControlTemplate>
    </RichTextBox.Template>
    <FlowDocument PagePadding="0">
        <Paragraph Padding="0" Margin="0" >LLL</Paragraph>
    </FlowDocument>
</RichTextBox>

И я подумал, что на этот вопрос будет легко ответить ... Интересное наблюдение: , когда у меня установлен шаблон и я установил PagePadding="0" на FlowDocument , он отображает макет, который я хочу в конструкторе VisualStudio - , пока я не запустил демонстрационную версию .В демоверсии это снова не так ... А когда я закрываю демо, это снова неправильно в дизайнере.Это небольшая ошибка VS или она на некоторое время настроена на правильный макет, но затем что-то меняет значение PagePadding обратно на какое-то неправильное значение?


Edit # 2

Отредактированный ответ Дэниэла Роуза также не работает для меня.Это XAML:

<FlowDocument PagePadding="{Binding PagePadding}">
    <Paragraph x:Name="paragraph" Padding="0" 
        TextIndent="0"  Margin="0,0,0,0" >hello</Paragraph>
</FlowDocument>

И это в коде:

public static DependencyProperty PagePaddingProperty =
            DependencyProperty.Register("PagePadding", typeof(Thickness),   typeof(EditableTextBlock),
            new PropertyMetadata(new Thickness(0)));

public Thickness PagePadding {
    get { return (Thickness)GetValue(PagePaddingProperty); }
    set { SetValue(PagePaddingProperty, value); }
}

Никаких изменений в результате .Осталось свободного места.


Edit # 3

После добавления двухсторонней привязки, как предложил Дэниэл Роуз в своем las edit, он работает.Тем не менее, я не думаю, что это очень ясно (иметь свойство зависимости, потому что мне нужно сохранить значение PagePadding в 0). Я думаю, что это обходной путь. Если у кого-то есть лучшее решение, поделитесь им.

Очевидно, что "изменение PagePadding" FlowDocument на 0,5 является ошибкой.Если у кого-то есть учетная запись MSDN, было бы хорошо, если бы он сообщил об этой ошибке.

Ответы [ 3 ]

21 голосов
/ 01 мая 2011

Я знаю, что это чертовски раздражает.

RichTextBox устанавливает этот PagePadding в CreateRenderScope(), то есть когда он присоединяется к визуальному дереву.В настоящее время все свойства обычно уже установлены, и поэтому PagePadding сбрасывается.

То, что я собираюсь показать вам, является более общей формой того, как вы можете сделать это с помощью присоединенного свойства.В моем собственном коде я обычно делаю это более плотно, потому что я знаю, что а) потоковый документ не изменяется (не нужно беспокоиться о регистрации одного и того же обработчика дважды) и б) заполнение не меняется (если обработчик событий просто равен ((FlowDocument)s).PagePadding = new Thickness(0.0);Поскольку это так, хотя я предоставлю общее решение, которое вы можете просто подключить.

Решение:

        <RichTextBox BorderThickness="0" Margin="0" Padding="0">
            <FlowDocument local:FlowDocumentPagePadding.PagePadding="0">
                <Paragraph>
                    <Run>text</Run>
                </Paragraph>
            </FlowDocument>
        </RichTextBox>

public static class FlowDocumentPagePadding
{
    public static Thickness GetPagePadding(DependencyObject obj)
    {
        return (Thickness)obj.GetValue(PagePaddingProperty);
    }
    public static void SetPagePadding(DependencyObject obj, Thickness value)
    {
        obj.SetValue(PagePaddingProperty, value);
    }
    public static readonly DependencyProperty PagePaddingProperty =
        DependencyProperty.RegisterAttached("PagePadding", typeof(Thickness), typeof(FlowDocumentPagePadding), new UIPropertyMetadata(new Thickness(double.NegativeInfinity),(o, args) =>
            {
                var fd = o as FlowDocument;
                if (fd == null) return;
                var dpd = DependencyPropertyDescriptor.FromProperty(FlowDocument.PagePaddingProperty, typeof(FlowDocument));
                dpd.RemoveValueChanged(fd, PaddingChanged);
                fd.PagePadding = (Thickness) args.NewValue;
                dpd.AddValueChanged(fd, PaddingChanged);
            }));
    public static void PaddingChanged(object s, EventArgs e)
    {
        ((FlowDocument)s).PagePadding = GetPagePadding((DependencyObject)s);
    }
}

исходный комментарий исходного кода:

В первоначальном источнике RichTextBox.CreateRenderScope() разработчики включили этот комментарий:

// Set a margin so that the BiDi Or Italic caret has room to render at the edges of content.
// Otherwise, anti-aliasing or italic causes the caret to be partially clipped.
renderScope.Document.PagePadding = new Thickness(CaretElement.CaretPaddingWidth, 0, CaretElement.CaretPaddingWidth, 0);

отчет об ошибке

вот отчет об ошибке в Microsoft Connect

3 голосов
/ 28 апреля 2011

Всё, как я писал ранее, не работает.По какой-то причине PagePadding перезаписывается как «5,0».Однако, когда я использовал привязку данных, это работало правильно.Так что просто свяжите данные с толщиной 0. Чтобы это работало, вам нужно выполнить двустороннюю привязку:

1 голос
/ 03 марта 2012

Попробуй это.Это работает для меня .... Это гораздо меньше головной боли, чем альтернативы здесь ...

<RichTextBox Padding="-5,0,-5,0">
   <FlowDocument />
</RichTextBox>
...