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) が失敗する条件です。選択したテキストに下線が引かれていても、常に false です。

編集 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;
}

ありがとうございます!

于 2013-12-17T12:10:54.577 に答える