当RichTextBox只是加载/空时,WPF编辑命令不起作用?

时间:2011-09-16 18:58:42

标签: c# wpf richtextbox togglebutton

这是一个非常简单的代码示例:

<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成为CheckedRichTextBox仍然使用正常样式(不是 BOLD ),直到我再次点击ToggleButton。 这是一个错误吗?我该怎么走?谢谢!

3 个答案:

答案 0 :(得分:3)

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

    }

答案 1 :(得分:3)

我找到了一个半解决方案,我想我会分享,因为这个问题在网络的任何地方都没有得到解答,我认为很多人都遇到了问题。

我在构造函数中设置了一个变量 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);
    }
}
然后我在正确的位置更换了carret。像这样,即使RichTextBox中没有任何内容,也会保留格式化。

我确定有一天能帮助别人。

答案 2 :(得分:0)

@Sinity很接近,但是当插入符号放在文本块中时,该解决方案不起作用,只有当它位于最后时。

在运行结束时有两个位置:Run.ContentEndRun.ElementEnd。似乎ContentEnd是&#34;就在外面&#34;运行(因此输入的任何新文本都不会采用运行的样式),但ElementEnd是&#34;只是在&#34;运行结束,键入的文本将添加到运行中。

这是一个修改过的解决方案(以待处理的粗体样式为例),似乎适用于所有情况:

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