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.
views:
1388answers:
2You'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.
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.