views:

1388

answers:

2

When you use the FontFamily property of the RichTextBox it changes the FontFamily of the whole content inside the FlowDocument. The same way you can Execute a command like EditingCommands.ToggleBold, where it only changes the word under the caret or just the new text to be written, there should be a way to do the same thing with the FontsFamilies, and Color.

+1  A: 

You'd use a RUN inside of the RichTextBox, something like:

<RichTextBox>
   <Run FontFamily="Arial">My Arial Content</Run>
   <Run FontFamily="Times" FontWeight="Bold">My bolded Times content</Run>
   <Run>My Content that inherits Font From the RTB</Run>
</RichTextBox>

Ok, This gets to play with some low-level doo hickies. But here we go:

First, add a few ToggleButtons and a RichTextBox to a XAML Form. In the Rich Text Box, you'll give it a few Command Bindings in order to let the system know that everything works together.

Here's the XAML:

<RichTextBox Height="119" Name="RichTextBox1" Width="254" >
       <RichTextBox.CommandBindings>
            <CommandBinding Command="EditingCommands.ToggleBold" CanExecute="CommandBinding_CanExecute"   ></CommandBinding>
            <CommandBinding Command="EditingCommands.ToggleItalic" CanExecute="CommandBinding_CanExecute"   ></CommandBinding>
       </RichTextBox.CommandBindings>
</RichTextBox>
<ToggleButton MinWidth="40" Command="EditingCommands.ToggleBold"  Height="23" HorizontalAlignment="Left" Name="Button1" VerticalAlignment="Top" Width="75" CommandTarget="{Binding ElementName=RichTextBox1}" >Bold</ToggleButton>
<ToggleButton MinWidth="40" Command="EditingCommands.ToggleBold"  Height="23" HorizontalAlignment="Left"  Name="Button2" VerticalAlignment="Top" Width="75" CommandTarget="{Binding ElementName=RichTextBox1}" >Italics</ToggleButton>

Now, what's there is a RichTextbox, and two toggle buttons, and the togglebuttons are related to the commandbindings to ToggleBold/ToggleItalics individually.

In the CODE side, I have these two methods:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)      
End Sub

Private Sub CommandBinding_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
     e.CanExecute = True
End Sub

The BUTTON CLICK event handler is there because a button needs the event handler to be usable.

The CanExecute tells the button if the value is available for bolding or not (for example, you could check the length, and not attempt to bold if the RTB is empty).

Now, for really low-level control of things, you're going to have to be doing things in the RichTextFormat. Follow this link to find out more about that.

Stephen Wrighton
I wanna change it dinamically , as well as commands do. This is fine for static text. But the poing in RichTextBox is dinamically yield text with different Text properties by keyboard entries.
jmayor
Then look into RTF, and reading/writing it.http://www.devcity.net/PrintArticle.aspx?ArticleID=356
Stephen Wrighton
The issue is that the first <Run> and all the followings will inherit the textElement Properties from their container( which might be the FlowDocument behind the RichTextEditor), so when changing the Font of the Editor it changes the font of all elements referencing to it. So far I can manage that by subscribing PreviewKey down by generating new Run tags when changing the font but then I have to filter the keyboard Input. I'm sure there is a better way to do it, all EditingCommnads work doing the same with the bold,italic,fontSize, and of course the do it in a fancy way.
jmayor
There is no command for changing the Font Family or it's color.
jmayor
+1  A: 

Maybe not the neatest solution but the you can inherit from the RichTextBox and add some behavior

Declare your own Font Properties so you can bind them later with a List of Fonts

    public class CustomControl1 : RichTextBox
    {

public static readonly DependencyProperty CurrentFontFamilyProperty =
                DependencyProperty.Register("CurrentFontFamily", typeof(FontFamily), typeof  (CustomControl1), new FrameworkPropertyMetadata(new FontFamily("Tahoma"), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,new PropertyChangedCallback(OnCurrentFontChanged)));
    }

Override the OnTextInput. You can't subscribe to this event on the RichTextBox has built-in handling for the bubbling of KeyDown and KeyUp and between them the TextInput is generated

    protected override void OnTextInput(TextCompositionEventArgs e)
{
        if (fontchanged)
        {
            TextPointer tp = this.CaretPosition.GetInsertionPosition(LogicalDirection.Forward);
            Run r = new Run(e.Text, tp);
            r.FontFamily = CurrentFontFamily;
            r.Foreground = CurrentForeground;
            this.CaretPosition = r.ElementEnd;
            fontchanged = false;
        }
        else
            base.OnTextInput(e);
    }

if your CurrentFontProperty has changed get the caret position and create a new Run with the new Text Input and set the FontFamily = CurrentFontFamily. You could also change the whole word if the carret is over a word, this article might be interesting to spot the word Navigate Words in RichTextBox.

jmayor