How to set RichTextBox Font for the next text to be written?

后端 未结 3 2268
耶瑟儿~
耶瑟儿~ 2020-12-10 03:58

I need to set the font family for the next text to be written in a RichTextBox. I tried setting that with...



        
3条回答
  •  南笙
    南笙 (楼主)
    2020-12-10 04:36

    In order to set the FontFamily based on the cursor position you need to define a custom control with a dependency property that helps insert a new Run section by overriding the OnTextInput method.

    I included most of the code, you'll need to modify the namespaces to fit your development environment.

    The code uses a ViewModel to manage the available fonts and manage if the font changed. This code is only a prototype and does not deal with focusing issues between the two controls.

    To use this code:
    1- Type some text in the RichTectBox.
    2- Change the font in the ComboBox.
    3- Tab back to the RichTextBox.
    4- Type some more text.

    Here is the custom RichTextBox control:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    
    namespace RichTextboxFont.Views
    {
      public class RichTextBoxCustom : RichTextBox
      {
        public static readonly DependencyProperty CurrentFontFamilyProperty =
                DependencyProperty.Register("CurrentFontFamily", 
                typeof(FontFamily), typeof  
                (RichTextBoxCustom), 
                new FrameworkPropertyMetadata(new FontFamily("Tahoma"), 
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                new PropertyChangedCallback(OnCurrentFontChanged)));
    
        public FontFamily CurrentFontFamily
        {
           get
           {
             return (FontFamily)GetValue(CurrentFontFamilyProperty);
           }
           set
           {
             SetValue(CurrentFontFamilyProperty, value);
           }
        }
    
        private static void OnCurrentFontChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {}
    
        protected override void OnTextInput(TextCompositionEventArgs e)
        {
          ViewModels.MainViewModel mwvm = this.DataContext as ViewModels.MainViewModel;
          if ((mwvm != null) && (mwvm.FontChanged))
          {
            TextPointer textPointer = this.CaretPosition.GetInsertionPosition(LogicalDirection.Forward);
            Run run = new Run(e.Text, textPointer);
            run.FontFamily = this.CurrentFontFamily;
            this.CaretPosition = run.ElementEnd;
            mwvm.FontChanged = false;
          }
          else
          {
             base.OnTextInput(e);
          }
        }
      } 
    }
    

    Here is the XAML:

    
      
        
            
                
                
            
    
            
            
        
      
    
    

    Here is the ViewModel: If you do not use view models, let me know and I'll add the base class code too; otherwise, google/stackoverflow can help you too.

    using System.Collections.ObjectModel;
    using System.Windows.Media;
    
    namespace RichTextboxFont.ViewModels
    {
      public class MainViewModel : ViewModelBase
      {
        #region Constructor
    
        public MainViewModel()
        {
           FontFamily f1 = new FontFamily("Georgia");
           _fonts.Add(f1);
           FontFamily f2 = new FontFamily("Tahoma");
           _fonts.Add(f2);
        }
    
        private ObservableCollection _fonts = new ObservableCollection();
        public ObservableCollection Fonts
        {
          get
          {
             return _fonts;
          }
          set
          {
            _fonts = value;
            OnPropertyChanged("Fonts");
          }
        }
    
        private FontFamily _selectedFont = new FontFamily("Tahoma");
        public FontFamily SelectedFont
        {
          get
          {
            return _selectedFont;
          }
          set
          {
            _selectedFont = value;
            FontChanged = true;
            OnPropertyChanged("SelectedFont");
          }
        }
    
        private bool _fontChanged = false;
        public bool FontChanged
        {
          get
          {
             return _fontChanged;
          }
          set
          {
            _fontChanged = value;
            OnPropertyChanged("FontChanged");
          }
        }
    
      #endregion
      }
    }
    

    Here is the Window code-behind where I initialise the ViewModel:

    using System.Windows;
    
    namespace RichTextboxFont.Views
    {
      public partial class MainView : Window
      {
        public MainView()
        {
          InitializeComponent();
          this.DataContext = new ViewModels.MainViewModel();
        }
      }
    }
    

提交回复
热议问题