1

我有一个 RichTextBox 的格式工具栏。

下划线按钮的 XAML:(rtb 是 RichTextBox)

<ToggleButton x:Name="btnUnderline" Command="{x:Static EditingCommands.ToggleUnderline}" CommandTarget="{Binding ElementName=rtb}">
    <TextBlock Height="16" Width="16" Foreground="Black" Text="S" TextDecorations="Underline" TextAlignment="Center" />
</ToggleButton>

根据所选文本的格式更新工具栏按钮状态的代码:

private void UpdateToggleButtonState()
{
    UpdateItemCheckedState(btnBold, TextElement.FontWeightProperty, FontWeights.Bold);
    UpdateItemCheckedState(btnItalic, TextElement.FontStyleProperty, FontStyles.Italic);
    UpdateItemCheckedState(btnUnderline, Inline.TextDecorationsProperty, TextDecorations.Underline);
    UpdateItemCheckedState(btnAlignLeft, Block.TextAlignmentProperty, TextAlignment.Left);
    UpdateItemCheckedState(btnAlignCenter, Block.TextAlignmentProperty, TextAlignment.Center);
    UpdateItemCheckedState(btnAlignRight, Block.TextAlignmentProperty, TextAlignment.Right);
    UpdateItemCheckedState(btnAlignJustify, Block.TextAlignmentProperty, TextAlignment.Justify);
}

private void UpdateItemCheckedState(ToggleButton button, DependencyProperty formattingProperty,
                                    object expectedValue)
{
    var currentValue = rtb.Selection.GetPropertyValue(formattingProperty);
    button.IsChecked = currentValue != null && currentValue != DependencyProperty.UnsetValue &&
                       currentValue.Equals(expectedValue);
}

我只是格式化文本后一切正常。例如,如果我选择一些文本并应用粗体、斜体和下划线格式,然后在另一个地方选择没有格式的文本,粗体、斜体和下划线按钮将被停用,当我选择格式化文本时,3 个按钮将再次被激活。

问题是当我从数据库中保存和恢复文本时。除下划线按钮外,一切正常。

恢复的文本确实在屏幕上带有下划线,但是当我单击它或选择它时,只有粗体和斜体按钮被激活。下划线按钮保持禁用状态。

这是将格式化文本保存到数据库的代码:

string rtfText; // string to save to database
var tr = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);

using (var ms = new MemoryStream())
{
    tr.Save(ms, DataFormats.Rtf);
    rtfText = Encoding.ASCII.GetString(ms.ToArray());
}

并从数据库中恢复格式化文本:

var rtfText = ... // string recovered from database
var byteArray = Encoding.ASCII.GetBytes(rtfText);

using (var ms = new MemoryStream(byteArray))
{
    var tr = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
    tr.Load(ms, DataFormats.Rtf);
}

如果我写“一些文字”这个短语。并应用粗体、斜体和下划线格式,这是保存到数据库的字符串:

{\rtf1\ansi\ansicpg1252\uc1\htmautsp\deff2{\fonttbl{\f0\fcharset0 Times New Roman;}{\f2\fcharset0 Segoe UI;}}{\colortbl\red0\green0\blue0;\red255\green255 \blue255;}\loch\hich\dbch\pard\plain\ltrpar\itap0{\lang1033\fs18\f2\cf0 \cf0\ql{\f2 {\lang5130\b\i\ul\ltrch 一些文字。}\ li0\ri0\sa0\sb0\fi0\ql\par} } }

任何帮助都感激不尽。

编辑

在 UpdateItemCheckedState() 方法中,currentValue.Equals(expectedValue) 是失败的条件。即使选定的文本带有下划线,它也总是错误的。

编辑 2

现在我正在使用另一个代码来生成将被保存/恢复到/从数据库中的文本。

保存:

using (var sw = new StringWriter())
{
    XamlWriter.Save(rtb.Document, sw);
    rtfText = sw.ToString(); // string to save to database
}

恢复:

// rtfText is the string recovered from database
rtb.Document = XamlReader.Parse(rtfText) as FlowDocument;

对于短语“一些文本”。使用粗体、斜体和下划线格式,数据库中的文本现在是(缩进后):

<FlowDocument PagePadding="5,0,5,0" AllowDrop="True" NumberSubstitution.CultureSource="User" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Paragraph>
        <Run FontStyle="Italic" FontWeight="Bold" xml:lang="es-cr">
            <Run.TextDecorations>
                <TextDecoration Location="Underline" />
            </Run.TextDecorations>
            Some text.
        </Run>
    </Paragraph>
</FlowDocument>

看起来不错,但下划线按钮的问题仍然存在。

4

1 回答 1

1

感谢msfanboy这个问题的回答,最后下划线按钮按预期工作。

我确实改变了这一行:

UpdateItemCheckedState(btnUnderline, Inline.TextDecorationsProperty, TextDecorations.Underline);

有了这个:

UpdateItemUnderlineState(); // To manage the special case

UpdateItemUnderlineState() 方法是:

private void UpdateItemCheckedStateUnderline()
{
    var currentValue = rtb.Selection.GetPropertyValue(Inline.TextDecorationsProperty);
    TextDecorationCollection collection = null;

    if (currentValue is TextDecorationCollection && currentValue != DependencyProperty.UnsetValue)
    {
        collection = currentValue as TextDecorationCollection;
    }

    btnUnderline.IsChecked = collection != null && collection.Count > 0;
}

谢谢msfanboy!

于 2013-12-17T12:10:54.577 回答