2009-07-17 3 views
1

Когда вы используете свойство FontFamily RichTextBox, он изменяет FontFamily всего содержимого внутри FlowDocument. Точно так же вы можете выполнить команду, например EditingCommands.ToggleBold, где она меняет только слово под кареткой или только новый текст, который должен быть написан, должен быть способ сделать то же самое с FontsFamilies и Color.Как изменить FontFamily в WPF RichTextBox без изменения предыдущего текста

ответ

3

Может быть, не опрятным решением, но вы можете наследовать от RichTextBox и добавить некоторое поведение

Объявите ваши собственные свойства шрифта, так что вы можете связать их позже с помощью списка шрифтов

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 OnTextInput. Вы не можете подписаться на это событие на RichTextBox имеет встроенную обработку для барботирования KeyDown и KeyUp и между ними в TextInput генерируется

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

если ваш CurrentFontProperty изменился получить позицию курсора и создать новый Запустите с новым вводом текста и установите FontFamily = CurrentFontFamily. Вы могли бы также изменить целое слово, если carret над словом, эта статья может быть интересна, чтобы определить слово Navigate Words in RichTextBox.

1

Вы бы использовать RUN внутри RichTextBox, что-то вроде:

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

Хорошо, Это добирается, чтобы играть с некоторыми ду hickies низкого уровня. Но здесь мы идем:

Сначала добавьте несколько ToggleButtons и RichTextBox в форму XAML. В Rich Text Box вы получите несколько командных привязок, чтобы система узнала, что все работает сообща.

Вот 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> 

Теперь, что есть RichTextBox, и две кнопки-переключатели, а togglebuttons связаны с CommandBindings до ToggleBold/ToggleItalics индивидуально.

В стороне КОДА, у меня есть эти два метода:

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 

Обработчик события нажатия кнопки есть, потому что кнопка нужен обработчик событий, который будет использоваться.

CanExecute указывает кнопке, если это значение доступно для полужирного шрифта или нет (например, вы можете проверить длину и не пытаться сделать полужирным, если RTB пуст).

Теперь, для действительно низкого уровня контроля над вещами, вам придется делать что-то в RichTextFormat. Следуйте этому link, чтобы узнать больше об этом.

+0

Я хочу изменить его динамически, а также выполнять команды. Это нормально для статического текста. Но poing в RichTextBox динамически выводит текст с различными свойствами текста с помощью записей в клавиатуре. – jmayor

+0

Затем загляните в RTF и прочитайте/напишите. http://www.devcity.net/PrintArticle.aspx?ArticleID=356 –

+0

Проблема заключается в том, что первые и все последующие будут наследовать свойства TextElement из своего контейнера (который может быть FlowDocument за RichTextEditor), поэтому при изменении шрифта редактора он изменяет шрифт всех элементов, ссылающихся на него. До сих пор я могу справиться с этим, подписавшись на PreviewKey down, создав новые теги запуска при изменении шрифта, но затем мне нужно отфильтровать ввод клавиатуры. Я уверен, что есть лучший способ сделать это, все EditingCommnads работают так же, как с жирным шрифтом, курсивом, fontSize и, конечно же, делают это по-настоящему. – jmayor

2

Вот что я использовал, чтобы избежать переопределения richtextbox. Это позволяет вам изменить стиль выбора, если он есть, или изменить стиль текста, который будет добавлен после каретки. Надеюсь, поможет.

public static void SetFontSize(RichTextBox target, double value) 
    { 
     // Make sure we have a richtextbox. 
     if (target == null) 
      return; 

     // Make sure we have a selection. Should have one even if there is no text selected. 
     if (target.Selection != null) 
     { 
      // Check whether there is text selected or just sitting at cursor 
      if (target.Selection.IsEmpty) 
      { 
       // Check to see if we are at the start of the textbox and nothing has been added yet 
       if (target.Selection.Start.Paragraph == null) 
       { 
        // Add a new paragraph object to the richtextbox with the fontsize 
        Paragraph p = new Paragraph(); 
        p.FontSize = value; 
        target.Document.Blocks.Add(p); 
       } 
       else 
       { 
        // Get current position of cursor 
        TextPointer curCaret = target.CaretPosition; 
        // Get the current block object that the cursor is in 
        Block curBlock = target.Document.Blocks.Where 
         (x => x.ContentStart.CompareTo(curCaret) == -1 && x.ContentEnd.CompareTo(curCaret) == 1).FirstOrDefault(); 
        if (curBlock != null) 
        { 
         Paragraph curParagraph = curBlock as Paragraph; 
         // Create a new run object with the fontsize, and add it to the current block 
         Run newRun = new Run(); 
         newRun.FontSize = value; 
         curParagraph.Inlines.Add(newRun); 
         // Reset the cursor into the new block. 
         // If we don't do this, the font size will default again when you start typing. 
         target.CaretPosition = newRun.ElementStart; 
        } 
       } 
      } 
      else // There is selected text, so change the fontsize of the selection 
      { 
       TextRange selectionTextRange = new TextRange(target.Selection.Start, target.Selection.End); 
       selectionTextRange.ApplyPropertyValue(TextElement.FontSizeProperty, value); 
      } 
     } 
     // Reset the focus onto the richtextbox after selecting the font in a toolbar etc 
     target.Focus(); 
    } 
Смежные вопросы