using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Documents;
namespace System.Windows.Forms
{
///
/// Specifies how text in a is horizontally aligned.
///
public enum TextAlign
{
///
/// The text is aligned to the left.
///
Left,
///
/// The text is aligned to the right.
///
Right,
///
/// The text is aligned in the center.
///
Center,
///
/// The text is justified.
///
Justify
}
public class RichTextBox : Control
{
protected new System.Windows.Controls.RichTextBox control { get; }
public string Rtf
{
get
{
using (var stream = new MemoryStream())
{
SaveFile(stream, RichTextBoxStreamType.RichText);
return Encoding.UTF8.GetString(stream.ToArray());
}
}
set
{
var documentBytes = Encoding.UTF8.GetBytes(value);
using (var stream = new MemoryStream(documentBytes))
{
stream.Position = 0;
LoadFile(stream, RichTextBoxStreamType.RichText);
}
}
}
private RichTextBoxScrollBars scrollBars;
public RichTextBoxScrollBars ScrollBars
{
get => scrollBars;
set
{
scrollBars = value;
control.HorizontalScrollBarVisibility = value == RichTextBoxScrollBars.Horizontal || value == RichTextBoxScrollBars.Both ?
Windows.Controls.ScrollBarVisibility.Visible : Windows.Controls.ScrollBarVisibility.Hidden;
control.VerticalScrollBarVisibility = value == RichTextBoxScrollBars.Vertical || value == RichTextBoxScrollBars.Both ?
Windows.Controls.ScrollBarVisibility.Visible : Windows.Controls.ScrollBarVisibility.Hidden;
}
}
public bool ReadOnly
{
get => control.IsReadOnly;
set => control.IsReadOnly = value;
}
public bool AcceptsTab
{
get => control.AcceptsTab;
set => control.AcceptsTab = value;
}
public int BulletIndent { get; set; } // TODO?
public bool DetectUrls { get; set; } // TODO?
public bool HideSelection
{
get => !control.IsInactiveSelectionHighlightEnabled;
set => control.IsInactiveSelectionHighlightEnabled = !value;
}
public Font SelectionFont
{
get
{
object tmp = control.Selection.GetPropertyValue(Inline.FontFamilyProperty);
var family = tmp == DependencyProperty.UnsetValue ? this.control.FontFamily : (Media.FontFamily)tmp;
tmp = control.Selection.GetPropertyValue(Inline.FontSizeProperty);
var size = tmp == DependencyProperty.UnsetValue ? this.control.FontSize : (double)tmp;
tmp = control.Selection.GetPropertyValue(Inline.FontStyleProperty); ;
var style = tmp == DependencyProperty.UnsetValue ? this.control.FontStyle : (FontStyle)tmp;
tmp = control.Selection.GetPropertyValue(Inline.FontWeightProperty);
var weight = tmp == DependencyProperty.UnsetValue ? this.control.FontWeight : (FontWeight)tmp;
tmp = control.Selection.GetPropertyValue(Inline.TextDecorationsProperty);
bool underline = false;
bool strikeout = false;
if (tmp is TextDecorationCollection deco)
{
underline = deco.Where(c => c.Location == TextDecorationLocation.Underline).Any();
strikeout = deco.Where(c => c.Location == TextDecorationLocation.Strikethrough).Any();
}
return Helper.GetFont(DpiScale, family, size, style, weight, underline, strikeout);
}
set
{
Helper.SetFont(value, DpiScale, out var family, out var size, out var style, out var weight, out var deco);
control.Selection.ApplyPropertyValue(Inline.FontFamilyProperty, family);
control.Selection.ApplyPropertyValue(Inline.FontSizeProperty, size);
control.Selection.ApplyPropertyValue(Inline.FontStyleProperty, style);
control.Selection.ApplyPropertyValue(Inline.FontWeightProperty, weight);
control.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, deco);
}
}
public Color SelectionColor
{
get
{
object tmp = control.Selection.GetPropertyValue(Inline.ForegroundProperty);
var color = tmp == DependencyProperty.UnsetValue ? this.control.Foreground : (System.Windows.Media.Brush)tmp;
return Helper.GetColor(color);
}
set
{
control.Selection.ApplyPropertyValue(Inline.ForegroundProperty, Helper.GetBrush(value));
}
}
public int SelectionCharOffset
{
get
{
object tmp = control.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);
var baseline = tmp == DependencyProperty.UnsetValue ? BaselineAlignment.Baseline : (BaselineAlignment)tmp;
if (baseline == BaselineAlignment.Subscript)
return -4;
if (baseline == BaselineAlignment.Superscript)
return 4;
return 0;
}
set
{
var baseline = BaselineAlignment.Baseline;
if (value == -4)
baseline = BaselineAlignment.Subscript;
else if (value == 4)
baseline = BaselineAlignment.Superscript;
control.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, baseline);
}
}
public bool SelectionBullet
{
get
{
var list = control.Document.Blocks
.Where(x => x.ContentStart.CompareTo(control.Selection.End) != 1 && x.ContentEnd.CompareTo(control.Selection.Start) != -1)
.FirstOrDefault() as List;
if (list != null)
return list.MarkerStyle != TextMarkerStyle.None;
return false;
}
set
{
EditingCommands.ToggleBullets.Execute(null, control);
}
}
public TextAlign SelectionAlignment
{
get
{
object tmp = control.Selection.GetPropertyValue(Paragraph.TextAlignmentProperty);
var textAlign = tmp == DependencyProperty.UnsetValue ? TextAlignment.Left : (TextAlignment)tmp;
return (TextAlign)textAlign;
}
set
{
control.Selection.ApplyPropertyValue(Paragraph.TextAlignmentProperty, (TextAlignment)value);
}
}
public string SelectedText
{
get => control.Selection.Text;
set => control.Selection.Text = value;
}
public bool Modified { get; set; }
public event EventHandler SelectionChanged;
private string GetFormat(RichTextBoxStreamType fileType)
{
return fileType switch
{
RichTextBoxStreamType.RichText => DataFormats.Rtf,
RichTextBoxStreamType.RichNoOleObjs => DataFormats.Rtf,
RichTextBoxStreamType.UnicodePlainText => DataFormats.UnicodeText,
_ => DataFormats.Text
};
}
protected virtual void OnSelectionChanged(EventArgs e) => SelectionChanged?.Invoke(this, e);
public void LoadFile(Stream stream, RichTextBoxStreamType fileType)
{
control.SelectAll();
control.Selection.Load(stream, GetFormat(fileType));
control.Selection.Select(control.Selection.End, control.Selection.End);
}
public void LoadFile(string path, RichTextBoxStreamType fileType)
{
using (var fs = File.OpenRead(path))
LoadFile(fs, fileType);
}
public void LoadFile(string path) => LoadFile(path, RichTextBoxStreamType.RichText);
public void SaveFile(Stream stream, RichTextBoxStreamType fileType)
{
control.SelectAll();
control.Selection.Save(stream, GetFormat(fileType));
}
public void SaveFile(string path, RichTextBoxStreamType fileType)
{
using (var fs = File.OpenWrite(path))
SaveFile(fs, fileType);
}
public void SaveFile(string path) => SaveFile(path, RichTextBoxStreamType.RichText);
public void Undo() => control.Undo();
public void Redo() => control.Redo();
public void SetSelectionFont(string fontName)
{
control.Selection.ApplyPropertyValue(Inline.FontFamilyProperty, fontName);
}
public void SetSelectionSize(int fontSize)
{
control.Selection.ApplyPropertyValue(Inline.FontSizeProperty, fontSize * 96 / 72.0);
}
public void SetSelectionBold(bool value)
{
control.Selection.ApplyPropertyValue(Inline.FontWeightProperty, value ? FontWeights.Bold : FontWeights.Normal);
}
public void SetSelectionItalic(bool value)
{
control.Selection.ApplyPropertyValue(Inline.FontStyleProperty, value ? FontStyles.Italic : FontStyles.Normal);
}
public void SetSelectionUnderline(bool value)
{
control.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, value ? TextDecorations.Underline : new TextDecorationCollection());
}
public void SelectAll() => control.SelectAll();
public RichTextBox()
{
control = new();
SetControl(control);
control.SelectionChanged += (s, e) => OnSelectionChanged(e);
control.TextChanged += (s, e) =>
{
OnTextChanged(e);
Modified = true;
};
control.PreviewDragEnter += (s, e) => OnDragEnter(Helper.GetDragEventArgs(control, e));
control.PreviewDragLeave += (s, e) => OnDragLeave(Helper.GetDragEventArgs(control, e));
control.PreviewDragOver += (s, e) =>
{
var args = Helper.GetDragEventArgs(control, e);
args.Effect = DragDropEffects.None;
OnDragOver(args);
e.Effects = (Windows.DragDropEffects)args.Effect;
e.Handled = true;
};
}
}
}