简体   繁体   中英

RichTextbox > Insert xaml at caret position

I am trying to find this out for days already without luck, what i want to achieve is to add flowdocument xaml code from string. String like:

string test = "<Paragraph><Run>Text</Run></Paragraph>";

But i want to add it not at the end of the block or document, but at current caret position. I need it to be able to enable copying of UIElements across my RichTextbox.

Thanks for help !

The XAML text like <Paragraph><Run>Text</Run></Paragraph> can't be inserted to the FlowDocument directly.

It should be converted to proper Flow Related Classes .

In your case create the Paragraph object and insert it on the current caret position:

The MainWindows.xaml :

<Window x:Class="WpfApp12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        
        mc:Ignorable="d"
        Topmost="True"
        Title="MainWindow" Height="350" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ToolBar Margin="0,0,0,0">
            <Menu VerticalAlignment="Center" Background="Transparent">                
                <MenuItem Header="Code Block" Click="InsertBlock_Click"/>                
            </Menu>
        </ToolBar>
        <Grid Grid.Row="1">
            <RichTextBox x:Name="rtb" Margin="5" IsDocumentEnabled="True">
                <FlowDocument>
                    <Paragraph Margin="0" Padding="0" FontSize="14" FontWeight="Bold">RichTextBox</Paragraph>                    
                    <Paragraph>A RichTextBox is a better choice when it is necessary for the user to edit formatted text, images, tables, or other rich content.</Paragraph>
                </FlowDocument>
            </RichTextBox>            
        </Grid>
    </Grid>
</Window>

The MainWindow.xaml.cs :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void InsertBlock_Click(object sender, RoutedEventArgs e)
    {
        // <Paragraph><Run>Text</Run></Paragraph>
        var paragraph = new Paragraph();
        paragraph.Inlines.Add(new Run("Text"));

        if (rtb.CaretPosition.IsEndOfBlock())
        {
            rtb.Document.Blocks.InsertAfter(rtb.CaretPosition.Paragraph, paragraph);
        }
        else
        {
            if (rtb.CaretPosition.IsAtLineStartPosition)
            {
                rtb.Document.Blocks.InsertBefore(rtb.CaretPosition.Paragraph, paragraph);
            }
            else
            {    
                rtb.Document.Blocks.InsertBefore(rtb.CaretPosition.InsertParagraphBreak().Paragraph, paragraph);
            }
        }
        rtb.Focus();
    }

    // Implementation of the `IsEndOfBlock()` extension method 
    public static class TextRangeExt
    {
        public static bool IsEndOfBlock(this TextPointer position)
        {
            for (; position != null; position = position.GetNextContextPosition(LogicalDirection.Forward))
            {
                switch (position.GetPointerContext(LogicalDirection.Forward))
                {
                    case TextPointerContext.ElementEnd:
                        if (position.GetAdjacentElement(LogicalDirection.Forward) is Paragraph) return true;
                        break;    
                    default:
                        return false;  
                }
            }
            return false;
        }
    }
}

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