简体   繁体   中英

WPF EditingCommands is not working when RichTextBox is just load/empty?

Here is a very simple code example:

<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>

when I run it, after typing something into the RichTextBox , I can use the ToggleButton to get the BOLD effect, and everything is fine.

But if I click ToggleButton before typing in anything into RichTextBox (no matter RichTextBox get focus or not), although ToggleButton became Checked , my RichTextBox still using the normal style (not BOLD ) until I click ToggleButton again. Is this a bug? how can I get around? Thanks!

I found a semi-solution and I thought I would share since this problem is not answered anywhere on the web and I think many people are having issues with it.

I set a Variable NewInput in the constructor. When the first input in the richTextBox will be fired, I'll just apply every formating I need to it and pass it to the control.

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);
    }
}

I then replace the carret at the right place. Like this, the formating is kept even if there is nothing in the RichTextBox.

I'm sure it'll help somebody one day.

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);

    }

@Sinity was close, but that solution does not work when the caret is placed within the text block, only if it is at the very end.

There are two positions at the end of a Run: Run.ContentEnd and Run.ElementEnd . It appears that the ContentEnd is "just outside" the run (so any new text entered does not take on the run's style), but ElementEnd is "just inside" the end of the run, and the typed text is added into the run.

Here is a modified solution (that applies a pending Bold style as an example) that seems to work in all cases:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM