6 changed files with 225 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||
using System; |
|||
using System.Windows.Documents; |
|||
|
|||
namespace Microsoft.Windows.Controls |
|||
{ |
|||
public interface ITextFormatter |
|||
{ |
|||
string GetText(FlowDocument document); |
|||
void SetText(FlowDocument document, string text); |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System; |
|||
using System.Windows.Documents; |
|||
|
|||
namespace Microsoft.Windows.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// Formats the RichTextBox text as plain text
|
|||
/// </summary>
|
|||
public class PlainTextFormatter : ITextFormatter |
|||
{ |
|||
public string GetText(FlowDocument document) |
|||
{ |
|||
return new TextRange(document.ContentStart, document.ContentEnd).Text; |
|||
} |
|||
|
|||
public void SetText(FlowDocument document, string text) |
|||
{ |
|||
new TextRange(document.ContentStart, document.ContentEnd).Text = text; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System; |
|||
using System.Text; |
|||
using System.Windows.Documents; |
|||
using System.IO; |
|||
using System.Windows; |
|||
|
|||
namespace Microsoft.Windows.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// Formats the RichTextBox text as RTF
|
|||
/// </summary>
|
|||
public class RtfFormatter : ITextFormatter |
|||
{ |
|||
public string GetText(FlowDocument document) |
|||
{ |
|||
TextRange tr = new TextRange(document.ContentStart, document.ContentEnd); |
|||
using (MemoryStream ms = new MemoryStream()) |
|||
{ |
|||
tr.Save(ms, DataFormats.Rtf); |
|||
return ASCIIEncoding.Default.GetString(ms.ToArray()); |
|||
} |
|||
} |
|||
|
|||
public void SetText(FlowDocument document, string text) |
|||
{ |
|||
TextRange tr = new TextRange(document.ContentStart, document.ContentEnd); |
|||
using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(text))) |
|||
{ |
|||
tr.Load(ms, DataFormats.Rtf); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Text; |
|||
using System.IO; |
|||
using System.Windows.Documents; |
|||
using System.Windows; |
|||
|
|||
namespace Microsoft.Windows.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// Formats the RichTextBox text as Xaml
|
|||
/// </summary>
|
|||
public class XamlFormatter : ITextFormatter |
|||
{ |
|||
public string GetText(System.Windows.Documents.FlowDocument document) |
|||
{ |
|||
TextRange tr = new TextRange(document.ContentStart, document.ContentEnd); |
|||
using (MemoryStream ms = new MemoryStream()) |
|||
{ |
|||
tr.Save(ms, DataFormats.Xaml); |
|||
return ASCIIEncoding.Default.GetString(ms.ToArray()); |
|||
} |
|||
} |
|||
|
|||
public void SetText(System.Windows.Documents.FlowDocument document, string text) |
|||
{ |
|||
try |
|||
{ |
|||
TextRange tr = new TextRange(document.ContentStart, document.ContentEnd); |
|||
using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(text))) |
|||
{ |
|||
tr.Load(ms, DataFormats.Xaml); |
|||
} |
|||
} |
|||
catch |
|||
{ |
|||
throw new InvalidDataException("data provided is not in the correct Xaml format."); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
using System; |
|||
using System.Windows; |
|||
using System.Windows.Data; |
|||
|
|||
namespace Microsoft.Windows.Controls |
|||
{ |
|||
public class RichTextBox : System.Windows.Controls.RichTextBox |
|||
{ |
|||
#region Private Members
|
|||
|
|||
private bool _textHasLoaded; |
|||
|
|||
#endregion //Private Members
|
|||
|
|||
#region Constructors
|
|||
|
|||
public RichTextBox() |
|||
{ |
|||
Loaded += RichTextBox_Loaded; |
|||
} |
|||
|
|||
public RichTextBox(System.Windows.Documents.FlowDocument document) |
|||
: base(document) |
|||
{ |
|||
|
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
#region Properties
|
|||
|
|||
private ITextFormatter _textFormatter; |
|||
/// <summary>
|
|||
/// The ITextFormatter the is used to format the text of the RichTextBox.
|
|||
/// Deafult formatter is the RtfFormatter
|
|||
/// </summary>
|
|||
public ITextFormatter TextFormatter |
|||
{ |
|||
get |
|||
{ |
|||
if (_textFormatter == null) |
|||
_textFormatter = new RtfFormatter(); //default is rtf
|
|||
|
|||
return _textFormatter; |
|||
} |
|||
set |
|||
{ |
|||
_textFormatter = value; |
|||
} |
|||
} |
|||
|
|||
#region Text
|
|||
|
|||
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(RichTextBox), new FrameworkPropertyMetadata(String.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTextPropertyChanged), new CoerceValueCallback(CoerceTextProperty), true, System.Windows.Data.UpdateSourceTrigger.LostFocus)); |
|||
public string Text |
|||
{ |
|||
get { return (string)GetValue(TextProperty); } |
|||
set { SetValue(TextProperty, value); } |
|||
} |
|||
|
|||
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
|||
{ |
|||
RichTextBox rtb = (RichTextBox)d; |
|||
|
|||
if (!rtb._textHasLoaded) |
|||
{ |
|||
rtb.TextFormatter.SetText(rtb.Document, (string)e.NewValue); |
|||
rtb._textHasLoaded = true; |
|||
} |
|||
} |
|||
|
|||
private static object CoerceTextProperty(DependencyObject d, object value) |
|||
{ |
|||
return value ?? ""; |
|||
} |
|||
|
|||
#endregion //Text
|
|||
|
|||
#endregion //Properties
|
|||
|
|||
#region Methods
|
|||
|
|||
private void UpdateText() |
|||
{ |
|||
//when the Text is null and the Text hasn't been loaded, it indicates that the OnTextPropertyChanged event hasn't exceuted
|
|||
//and since we are initializing the text from here, we don't want the OnTextPropertyChanged to execute, so set the loaded flag to true.
|
|||
//this prevents the cursor to jumping to the front of the textbox after the first letter is typed.
|
|||
if (!_textHasLoaded && string.IsNullOrEmpty(Text)) |
|||
_textHasLoaded = true; |
|||
|
|||
if (_textHasLoaded) |
|||
Text = TextFormatter.GetText(Document); |
|||
} |
|||
|
|||
#endregion //Methods
|
|||
|
|||
#region Event Hanlders
|
|||
|
|||
private void RichTextBox_Loaded(object sender, RoutedEventArgs e) |
|||
{ |
|||
Binding binding = BindingOperations.GetBinding(this, TextProperty); |
|||
|
|||
if (binding.UpdateSourceTrigger == UpdateSourceTrigger.Default || binding.UpdateSourceTrigger == UpdateSourceTrigger.LostFocus) |
|||
{ |
|||
LostFocus += (o, ea) => UpdateText(); |
|||
} |
|||
else |
|||
{ |
|||
TextChanged += (o, ea) => UpdateText(); |
|||
} |
|||
} |
|||
|
|||
#endregion //Event Hanlders
|
|||
} |
|||
} |
|||
Loading…
Reference in new issue