2

Before I start hacking in a really crude solution, I thought I'd see if someone could give me a little nudge in the right direction.

What I really want to do is let a user select some text in a RichTextBox, click a button, and convert that text into a custom rendered control. Convert it to a Button containing the text they had selected, for instance.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72

2 Answers2

2

You can do this with Command and CommandParameter

First, bind the button to an ICommand, like:

<Button Content="Go" Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=myRichTextBox, Path=Selection}" />
<RichTextBox Name="myRichTextBox" />

Then in your ViewModel or Controller or Code-behind or wherever, you expose the ICommand as a property,and point it to a method to do the work, like...

public ICommand MyCommand
{
    get
    {
        if (_queryCommand == null)
        {
            _queryCommand = new RelayCommand<TextSelection>(DoWork);
        }
        return _queryCommand;
    }
}

private void DoWork(TextSelection param)
{
    string selectedText = param.Text;

    // Build your control here...
    // probably put it in an ObservableCollection<Control> which is bound by an Items Control, like a ListBox
}

Note: I have used the RelayCommand from Josh Smith's excellent MVVM Foundation, but you could equally use a RoutedUICommand for example (which would add the extra benefit of letting you associate input gestures to your command)

kiwipom
  • 7,639
  • 37
  • 37
  • Sorry, as an addition... I just tried and failed to bind to the Selection.Path of the RTB control, but if I set Path=Selection, and make my RelayCommand of type System.Windows.Documents.TextSelection (and make my handler take a parameter of the same type) it works fine... I'll update the code above to show you what I mean :) – kiwipom Aug 27 '09 at 09:53
0

You'll need to write some code that takes your selection and wraps it in an InlineUIContainer - that's how you get controls inside a rich text box:

<RichTextBox>
    <FlowDocument>
        <Paragraph>
            <Run>Fo</Run>
            <InlineUIContainer>
                <Button IsEnabled="True">oB</Button>
            </InlineUIContainer>
            <Run>ar</Run>
        </Paragraph>
    </FlowDocument>
</RichTextBox>
Rob Fonseca-Ensor
  • 15,510
  • 44
  • 57
  • Hey Rob :) Huh.. it never occurred to me he might want the control actually *in* the RichTextBox... nice answer :) – kiwipom Aug 27 '09 at 09:57
  • I guess I wasn't clear enough on my question. This is obviously trivial in XAML, but my question was how to programatically go from the the user selecting 'oB' when there's just one containing "FooBar", to the resulting document you've shown here. –  Aug 27 '09 at 14:11