WPF应用 - 实现可上下标的文本框

2017-05-14 11:44:05来源:CSDN作者:wujingang人点击

System.Windows.Controls.RichTextBox

首先考虑使用这个控件

上下标设置

var textrange = new TextRange(rtb.Selection.Start, rtb.Selection.End);textrange.ApplyPropertyValue(Run.BaselineAlignmentProperty, BaselineAlignment.Superscript); //上标textrange.ApplyPropertyValue(Run.BaselineAlignmentProperty, BaselineAlignment.Subscript); //下标

上下标的设置没有问题,显示也没有问题,但当把RichTextBox中的内容存取时,问题出现了:
1. 保存的rtf格式中上下标信息丢失;
2. 对RichTextBox的文本信息进行右键复制,粘贴到word中,上下标信息丢失

相关代码如下:

    public static class Extend    {        public static string GetText(this RichTextBox rtb, string dataformat)        {            if (null == rtb)                return "";            var range = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);            using (var ms = new MemoryStream())            {                range.Save(ms, dataformat);                ms.Seek(0, SeekOrigin.Begin);                using (var sr = new StreamReader(ms))                    return sr.ReadToEnd();            }        }        public static void SetText(this RichTextBox rtb, string text, string dataformat)        {            if (null == rtb || null == text)                return;            var range = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(text)))            {                range.Load(ms, dataformat);            }        }    }

保存rtf格式上下标信息丢失

dataformat传递的是DataFormats.Rtf。网上搜寻答案,以另外一种格式存取没有问题,即传递dataformat为DataFormats.Xaml

Copy to Word上下标信息丢失

找到了另外一种设置上下标的方式,即Typography.Variants
在WPF中设置该属性,显示如下:
这里写图片描述
Copy To Word后显示:
这里写图片描述
显示的结果与使用BaselineAlignment的结果正好相反。Good! 找到解决方案了,Wpf上显示的时候使用BaseLineAlignment,而在后台保存时使用Typography.Variants

代码如下

    public static class TextRangeExtend    {        public static string GetText(this TextRange tr, string dataformat)        {            if (null == tr)                return "";            using (var ms = new MemoryStream())            {                tr.Save(ms, dataformat);                ms.Seek(0, SeekOrigin.Begin);                using (var sr = new StreamReader(ms))                    return sr.ReadToEnd();            }        }        public static void SetText(this TextRange tr, string val, string dataformat)        {            if (null == tr)                return;            if (string.IsNullOrEmpty(val))            {                tr.Text = "";                return;            }            using (var ms = new MemoryStream(Encoding.Default.GetBytes(val)))            {                tr.Load(ms, dataformat);            }        }        public static string GetTextRtf(this TextRange tr)        {            if (null == tr)                return "";            var xamlstr1 = tr.GetText(DataFormats.Xaml);            var xamlstr2 = xamlstr1.Replace("BaselineAlignment", "Typography.Variants");            var tbTemp = new RichTextBox();            var trTemp = new TextRange(tbTemp.Document.ContentStart, tbTemp.Document.ContentEnd);            trTemp.SetText(xamlstr2, DataFormats.Xaml);            return trTemp.GetText(DataFormats.Rtf);        }        public static void SetTextRtf(this TextRange tr, string rtfstr)        {            if (null == tr)                return;            if (string.IsNullOrEmpty(rtfstr))            {                tr.SetText(null, null);                return;            }            var tbTemp = new RichTextBox();            var trTemp = new TextRange(tbTemp.Document.ContentStart, tbTemp.Document.ContentEnd);            trTemp.SetText(rtfstr, DataFormats.Rtf);            var xamlstr2 = trTemp.GetText(DataFormats.Xaml);            var regex = new Regex("Typography.Variants(?=(=/"(Superscript|Subscript)/"))");            var xamlstr1 = regex.Replace(xamlstr2, "BaselineAlignment");            tr.SetText(xamlstr1, DataFormats.Xaml);        }        public static TextRange TextRangeAll(this RichTextBox rtb)        {            if (null != rtb)                return new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);            return null;        }        public static TextRange TextRangeAll(this TextBlock tb)        {            if (null != tb)                return new TextRange(tb.ContentStart, tb.ContentEnd);            return null;        }    }

注:当然,这里只是解决了正确保存rtf的问题,右键复制RichTextBox再粘贴到Word中显示错误的问题仍然没有解决,但至少已经可以通过代码向Word中添加正确的上下标字符信息了。

使用System.Windows.Forms.RichTextBox

在wpf中使用这个控件时,需要使用WinFormHost,具体的设置上下标,保存获取代码相当简单,且Copy To Word也没有任何问题。

设置上下标

richTextBox.SelectionCharOffset = 6; //设置上标richTextBox.SelectionCharOffset = -6; //设置下标

rtf格式可在加载

strign val = richTextBox.Rtf; //获取rtf格式的文本richTextBox.Rtf = val; //设置rtf格式的文本

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台