WPF EditingCommands не работает, когда RichTextBox просто загружен / пуст? - PullRequest
3 голосов
/ 16 сентября 2011

Вот очень простой пример кода:

<DockPanel>
    <ToolBar DockPanel.Dock="Top" IsTabStop="False">
         <ToggleButton MinWidth="40"  Command="EditingCommands.ToggleBold" CommandTarget="{Binding ElementName=XAMLRichBox}" TextBlock.FontWeight="Bold" IsTabStop="False">B</ToggleButton>
    </ToolBar>
    <RichTextBox x:Name="XAMLRichBox" SpellCheck.IsEnabled="True" MinHeight="100"/>
</DockPanel>

когда я его запускаю, после ввода чего-либо в RichTextBox я могу использовать ToggleButton, чтобы получить BOLD эффект, и все в порядке.

Но если я нажму ToggleButton перед тем, как ввести что-либо в RichTextBox (независимо от того, RichTextBox получить фокус или нет), хотя ToggleButton стал Checked, мой RichTextBox все еще использует обычныйстиль (не BOLD ), пока я снова не нажму ToggleButton.Это ошибка?как я могу обойти?Спасибо!

Ответы [ 3 ]

3 голосов
/ 19 июня 2014

Я нашел полу-решение, и я думал, что поделюсь, так как эта проблема нигде в Интернете не решена, и я думаю, что многие люди имеют проблемы с ним.

Я установил переменную NewInput в конструкторе. Когда будет запущен первый вход в richTextBox, я просто применю к нему все необходимые форматы и передам его элементу управления.

private bool NewInput;
private void richTxt_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    if (NewInput)
    {
        richTxt.BeginChange();
        TextPointer startPosition = richTxt.Selection.Start;
        Run r = new Run(e.Text, startPosition);
        if (IsSelectionBold)
        {
            r.FontWeight = FontWeights.Bold;
        }
        if (IsSelectionItalic)
        {
            r.FontStyle = FontStyles.Italic;
        }
        if (IsSelectionUnderlined)
        {
            r.TextDecorations = TextDecorations.Underline;
        }
        r.FontSize = double.Parse(SelectedFontHeight);
        r.FontFamily = new FontFamily(SelectedFont);

        richTxt.EndChange();


        NewInput = false;
        e.Handled = true;
        richTxt.CaretPosition = richTxt.CaretPosition.GetPositionAtOffset(1);
    }
}

Затем я заменяю каретку в нужном месте. Таким образом, форматирование сохраняется, даже если в RichTextBox ничего нет.

Я уверен, что однажды это кому-нибудь поможет.

3 голосов
/ 17 сентября 2011

MainWindow.xaml

<DockPanel>
    <ToolBar
        DockPanel.Dock="Top"
        IsTabStop="False">
        <ToggleButton
            x:Name="boldButton"
            Command="EditingCommands.ToggleBold"
            CommandTarget="{Binding ElementName=XAMLRichBox}"
            TextBlock.FontWeight="Bold"
            ToolTip="Bold">
           B 
        </ToggleButton>
    </ToolBar>
    <RichTextBox
        x:Name="XAMLRichBox"
        SpellCheck.IsEnabled="True"
        SelectionChanged="SynchronizeWith"
        MinHeight="100" />
</DockPanel>    

MainWindow.xaml.cs

 private void SynchronizeWith(object sender, RoutedEventArgs e)
    {
        object currentValue = XAMLRichBox.Selection.GetPropertyValue(TextElement.FontWeightProperty);
        boldButton.IsChecked = (currentValue == DependencyProperty.UnsetValue) ? false : currentValue != null && currentValue.Equals(FontWeights.Bold);

    }
0 голосов
/ 28 июня 2017

@ Sinity был близок, но это решение не работает, когда курсор вставляется в текстовый блок, только если он находится в самом конце.

В конце цикла есть две позиции: Run.ContentEnd и Run.ElementEnd. Похоже, что ContentEnd «только за пределами» цикла (поэтому любой новый введенный текст не принимает стиль выполнения), но ElementEnd «только внутри» конца цикла, и введенный текст добавляется в бегах.

Вот модифицированное решение (в качестве примера применяется отложенный стиль Bold), которое работает во всех случаях:

private bool IsBoldStylePending { get; set; }
private void RichTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    if (!IsBoldStylePending)
        return;

    rtb.BeginChange();
    Run run = new Run(e.Text, rtb.CaretPosition);  // Add the next character with style
    run.FontWeight = FontWeights.Bold;
    rtb.EndChange();

    rtb.CaretPosition = run.ElementEnd;            // Keep caret just within the run

    IsBoldStylePending = false;
    e.Handled = true;
}
...