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