QQ互联OAuth2.0 .NET SDK 发布和网站QQ登陆示例代码

[索引页]
[源码下载]

OAuth
OAuth(开放授权)是一个盛开标准,允许用户授权第三着网站访问他们存储于另外的劳动提供者上的音讯,而非需用用户称及密码提供给第三方网站要分享他们数据的富有内容。

稳扎稳打Silverlight(42) – 4.0控件之Viewbox, RichTextBox

QQ登录OAuth2.0:对于用户相关的OpenAPI(例如获取用户信息,动态同步,照片,日志,分享当),为了保护用户数据的平安及隐私,第三在网站访问用户数据前都亟需显式的通向用户征授权。
QQ登录OAuth2.0采用OAuth2.0标准协议来展开用户身份验证和取得用户授权,相对于前的OAuth1.0协议,其验明正身流程又简单和安全。具体参考文档
:【QQ登录】OAuth2.0开文档。

作者:webabcd

QQ互联网站已经提供了PHP,JS,Android和iOS的SDK,缺少.NET版本的SDK,春节假期期间利用部分空暇时间封装了一个有着了意义的.NET
SDK,后续将包一个应和之Windows
Phone的SDK,并开源放在http://opensns.codeplex.com
,专门搭建了一个演示网站http://www.win8charm.com/
和MSDN风格的在线帮助网站http://help.win8charm.com/
。今天马上首文章要介绍使用.NET SDK实施QQ登陆功能。

介绍
Silverlight 4.0 控件一盼:

从这里http://opensns.codeplex.com/ 下充斥最新版本的SDK,最新版本是Beta,
完成SDK的包裹,希望大家用帮忙测试,SDK依赖让Newtonsoft.Json和RestSharp两单程序集,具体可以参照使用RestSharp
库消费Restful
Service。
主要是有限个类QzoneContext(QQ登陆的上下文数据)  和 QOpenClient
(QQ互联API入口),其他类重要是范,配置类。

  • Viewbox – 一个器皿控件,其外只能有一个子元素。Viewbox
    可以控制其外的子元素如何拉伸、缩放、对共同
  • RichTextBox – 编辑器。用于展示或编辑文本、超链、图片、UI元素等 

1、你得去http://connect.qq.com/ 申请一个账号,会获一个APP ID和App
Key,这点儿独东东会在转请求的时节用到。你的去填一些资料,还要交一些材料对。

在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html

在配置文件web.config加入QQ登陆所待的一些安排参数,如下图所示:

示例
 1、Viewbox 的 Demo
ViewboxDemo.xaml

<configuration>
  <configSections>
    <sectionGroup name=”QQSectionGroup”>
      <section name=”QzoneSection”
type=”System.Configuration.NameValueSectionHandler,System,
Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089″
/>
    </sectionGroup>
  </configSections>
   <QQSectionGroup>
    <QzoneSection>
      <add key=”AppKey” value=”” />
      <add key=”AppSecret” value=”” />
      <add key=”CallBackURI” value=”” />
      <add key=”AuthorizeURL”
value=”https://graph.qq.com/oauth2.0/authorize” />
    </QzoneSection>
  </QQSectionGroup>

图片 1图片 2代码

AppKey是申请QQ登录成功后,分配为使用的appid;AppSecret是报名QQ登录成功后,分配为网站的appkey;CallBackURI是QQ登陆成功后底回调地址:AuthorizeURL是QQ互联的OAth2认证地址:

<navigation:Page x:Class=”Silverlight40.Control.ViewboxDemo” 
           xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 
           xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 
           xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
           xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
           xmlns:navigation=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation”
           Title=”ViewboxDemo Page”>
    <Grid x:Name=”LayoutRoot” Background=”White”>
        <StackPanel Background=”AntiqueWhite” HorizontalAlignment=”Left”>

2、在项目被上加三单援Newtonsoft.Json.dll、RestSharp.dll和
QConnectSDK.dll,
在页面及停按钮,打开qq登录的页面,然后登录成功以后回调您的网站的页面。此时要是用户以公的网站来账号,那便可绑定现有账号,或者新登记一个账号。如果您是新建站,也可了用qq登录来作为用户体系。

            <!– 用于演示 Viewbox.Stretch 属性 –>
            <StackPanel Margin=”5″ Width=”200″>
                <TextBlock Text=”Stretch” />
                <Button Name=”btn1″ Click=”stretchNone” Content=”None” />
                <Button Name=”btn2″ Click=”stretchFill” Content=”Fill” />
                <Button Name=”btn3″ Click=”stretchUniform” Content=”Uniform” />
                <Button Name=”btn4″ Click=”stretchUniformToFill” Content=”UniformToFill” />
            </StackPanel>

下上代码:

            <!– 用于演示 Viewbox.StretchDirection 属性 –>
            <StackPanel Margin=”5″ Width=”200″>
                <TextBlock Text=”StretchDirection” />
                <Button Name=”btn5″ Click=”stretchDirectionUpOnly” Content=”UpOnly” />
                <Button Name=”btn6″ Click=”stretchDirectionDownOnly” Content=”DownOnly” />
                <Button Name=”btn7″ Click=”stretchDirectionBoth” Content=”Both” />
            </StackPanel>

        /// <summary>
        /// QQ登陆页面
        /// </summary>

            <!– 用于演示 Viewbox.HorizontalAlignment 属性 –>
            <StackPanel Margin=”5″ Width=”200″>
                <TextBlock Text=”HorizontalAlignment” />
                <Button Name=”btn8″ Click=”horizontalAlignmentCenter” Content=”Center” />
                <Button Name=”btn9″ Click=”horizontalAlignmentLeft” Content=”Left” />
                <Button Name=”btn10″ Click=”horizontalAlignmentRight” Content=”Right” />
                <Button Name=”btn11″ Click=”horizontalAlignmentStretch” Content=”Stretch” />
            </StackPanel>

       [HttpGet]
       public ActionResult Login(string returnUrl)
       {
           this.Session[RETURNURL] = returnUrl;
           var context = new QzoneContext();
           string state = Guid.NewGuid().ToString().Replace(“-“, “”);
           Session[“requeststate”] = state;
           string scope =
“get_user_info,add_share,list_album,upload_pic,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idolist,add_idol,del_idol,add_one_blog,add_topic,get_tenpay_addr”;
           var authenticationUrl = context.GetAuthorizationUrl(state,
scope);
           return new RedirectResult(authenticationUrl);

            <!– 用于演示 Viewbox.VerticalAlignment 属性 –>
            <StackPanel Margin=”5″ Width=”200″>
                <TextBlock Text=”VerticalAlignment” />
                <Button Name=”btn12″ Click=”verticalAlignmentCenter” Content=”Center” />
                <Button Name=”btn13″ Click=”verticalAlignmentTop” Content=”Top” />
                <Button Name=”btn14″ Click=”verticalAlignmentBottom” Content=”Bottom” />
                <Button Name=”btn15″ Click=”verticalAlignmentStretch” Content=”Stretch” />
            </StackPanel>

       }   

            <!– 用于展示当前 Viewbox 的 Stretch 值,StretchDirection 值,HorizontalAlignment 值,VerticalAlignment 值 –>
            <StackPanel Margin=”5″>
                <TextBlock Name=”lblMsg” />
            </StackPanel>

        /// <summary>
        /// 回调页面
        /// </summary>

            <!– 用于演示 Viewbox 的各种力量 –>
            <StackPanel Width=”500″ Height=”300″ Background=”Black”>
                <Viewbox Name=”viewbox” Width=”500″ Height=”300″>
                    <!– 注:Viewbox 内只能发出一个子元素 –>
                    <Image Source=”/Resource/Logo.jpg” />
                </Viewbox>
            </StackPanel>
            
        </StackPanel>
    </Grid>
</navigation:Page>

       public ActionResult QQConnect(LoginModel model)
       {
           if (Request.Params[“code”] != null)
           {
               QOpenClient qzone = null;

ViewboxDemo.xaml.cs

               var verifier = Request.Params[“code”];
               var state = Request.Params[“state”];
               string requestState =
Session[“requeststate”].ToString();

图片 3图片 4代码

               if (state == requestState)
               {
                   qzone = new QOpenClient(verifier, state);
                   var currentUser = qzone.GetCurrentUser();
                   if (this.Session[“QzoneOauth”] == null)
                   {
                       this.Session[“QzoneOauth”] = qzone;
                   }
                   var friendlyName = currentUser.Nickname;

/*
 * Viewbox – 一个器皿控件,其外只能有一个子元素。Viewbox 可以决定其外之子元素如何拉伸、缩放、对合
 */

                   var isPersistentCookie = true;
                   SetAuthCookie(qzone.OAuthToken.OpenId,
isPersistentCookie, friendlyName);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

                   return Redirect(Url.Action(“Index”, “Home”));
               }

namespace Silverlight40.Control
{
    public partial class ViewboxDemo : Page
    {
        public ViewboxDemo()
        {
            InitializeComponent();
        }

           }
           return View();
       }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            ShowResult();
        }

面的代码是ASP.NET MVC的,项目示范运行于http://www.win8charm.com/
,下面贴个ASP.NET WebForm的代码示例:

        // 用于展示当前 Viewbox 的 Stretch 值,StretchDirection 值,HorizontalAlignment 值,VerticalAlignment 值
        private void ShowResult()
        {
            lblMsg.Text = string.Format(“Stretch: {0}, StretchDirection: {1}, HorizontalAlignment: {2}, VerticalAlignment: {3}”,
                viewbox.Stretch.ToString(),
                viewbox.StretchDirection.ToString(),
                viewbox.HorizontalAlignment.ToString(),
                viewbox.VerticalAlignment.ToString());
        }

QQ登陆页面

        /*
         * Viewbox.Stretch – 子元素以 Viewbox 内的拉伸模式 [System.Windows.Media.Stretch 枚举]
         *     Stretch.None – 不做拍卖。不做其他拉伸处理,填充内容保持原来大小
         *     Stretch.Fill – 充满。调整填充内容,以洋溢整个容器,填充内容比例改为容器比例
         *     Stretch.Uniform – 等比较适应。调整填充内容,以可容器尺寸,填充内容会召开顶比例调整(默认值)
         *         如果填充内容及容器比例不等同,那么填充内容调整的结果为:
     *       使得填充内容的财大气粗和容器的富裕顶,或者 填充内容的过人和容器的过人顶。填充内容会吃完全显示
         *     Stretch.UniformToFill – 等比较充满。调整填充内容,以适合容器尺寸,填充内容会召开顶比例调整
         *         如果填充内容以及容器比例不同等,那么填充内容调整的结果为:
     *      使得填充内容的方便和容器的方便顶,并且 填充内容的强与容器的高顶。填充内容会于做相应的剪裁
         */
        private void stretchNone(object sender, RoutedEventArgs e)
        {
            viewbox.Stretch = Stretch.None;
            ShowResult();
        }
        private void stretchFill(object sender, RoutedEventArgs e)
        {
            viewbox.Stretch = Stretch.Fill;
            ShowResult();
        }
        private void stretchUniform(object sender, RoutedEventArgs e)
        {
            viewbox.Stretch = Stretch.Uniform;
            ShowResult();
        }
        private void stretchUniformToFill(object sender, RoutedEventArgs e)
        {
            viewbox.Stretch = Stretch.UniformToFill;
            ShowResult();
        }

namespace OpenConnect.WebSample.Account
{
    public partial class LoginToQQ : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            GetRequestToken();
        }

        /*
         * Viewbox.StretchDirection – 子元素以 Viewbox 内之缩放模式 [System.Windows.Controls.StretchDirection 枚举]
         *     StretchDirection.UpOnly – 当子元素小于 Viewbox 时,子元素会加大
         *     StretchDirection.DownOnly – 当子元素大于 Viewbox 时,子元素会缩小
         *     StretchDirection.Both – 不开另外处理(默认值)
         */
        private void stretchDirectionUpOnly(object sender, RoutedEventArgs e)
        {
            viewbox.StretchDirection = StretchDirection.UpOnly;
            ShowResult();
        }
        private void stretchDirectionDownOnly(object sender, RoutedEventArgs e)
        {
            viewbox.StretchDirection = StretchDirection.DownOnly;
            ShowResult();
        }
        private void stretchDirectionBoth(object sender, RoutedEventArgs e)
        {
            viewbox.StretchDirection = StretchDirection.Both;
            ShowResult();
        }

        private void GetRequestToken()
        {
            var context = new QzoneContext();
            string state = Guid.NewGuid().ToString().Replace(“-“, “”);
            string scope =
“get_user_info,add_share,list_album,upload_pic,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idolist,add_idol,del_idol,add_one_blog,add_topic,get_tenpay_addr”;
            var authenticationUrl =
context.GetAuthorizationUrl(state,scope);
            //request token, request token secret 需要保存起来
           
//在demo演示着,直接保存在全局变量中.真实情况需要网站自己处理
            Session[“requeststate”] = state;          
            Response.Redirect(authenticationUrl);

        /*
         * Viewbox.HorizontalAlignment – 子元素于 Viewbox 内之品位方向的针对齐模式 [System.Windows.HorizontalAlignment 枚举]
         *      Center, Left, Right, Stretch(默认值)
         */
        private void horizontalAlignmentCenter(object sender, RoutedEventArgs e)
        {
            viewbox.HorizontalAlignment = HorizontalAlignment.Center;
            ShowResult();
        }
        private void horizontalAlignmentLeft(object sender, RoutedEventArgs e)
        {
            viewbox.HorizontalAlignment = HorizontalAlignment.Left;
            ShowResult();
        }
        private void horizontalAlignmentRight(object sender, RoutedEventArgs e)
        {
            viewbox.HorizontalAlignment = HorizontalAlignment.Right;
            ShowResult();
        }
        private void horizontalAlignmentStretch(object sender, RoutedEventArgs e)
        {
            viewbox.HorizontalAlignment = HorizontalAlignment.Stretch;
            ShowResult();
        }

        }
    }
}

        /*
         * Viewbox.VerticalAlignment – 子元素以 Viewbox 内之直方向的对齐模式 [System.Windows.VerticalAlignment 枚举]
         *      Center, Top, Bottom, Stretch(默认值)
         */
        private void verticalAlignmentCenter(object sender, RoutedEventArgs e)
        {
            viewbox.VerticalAlignment = VerticalAlignment.Center;
            ShowResult();
        }
        private void verticalAlignmentTop(object sender, RoutedEventArgs e)
        {
            viewbox.VerticalAlignment = VerticalAlignment.Top;
            ShowResult();
        }
        private void verticalAlignmentBottom(object sender, RoutedEventArgs e)
        {
            viewbox.VerticalAlignment = VerticalAlignment.Bottom;
            ShowResult();
        }
        private void verticalAlignmentStretch(object sender, RoutedEventArgs e)
        {
            viewbox.VerticalAlignment = VerticalAlignment.Stretch;
            ShowResult();
        }
    }
}

 

2、RichTextBox 的 Demo
RichTextBoxDemo.xaml

回调页面

图片 5图片 6代码

namespace OpenConnect.WebSample.Account
{
    public partial class QQCallback : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.Params[“code”] != null)
            {
                QOpenClient qzone = null;
                User currentUser = null;

<navigation:Page x:Class=”Silverlight40.Control.RichTextBoxDemo” 
           xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 
           xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 
           xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
           xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
           xmlns:navigation=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation”
           Title=”RichTextBoxDemo Page”>
    <StackPanel HorizontalAlignment=”Left”>
        
        <StackPanel Background=”AntiqueWhite” Orientation=”Horizontal”>
            <ComboBox x:Name=”cmbFontSize” FontSize=”{Binding SelectedItem.FontSize, RelativeSource={RelativeSource Self}}” SelectionChanged=”cmbFontSize_SelectionChanged”>
                <ComboBoxItem Content=”16″ Tag=”16″ FontSize=”16″ IsSelected=”True” />
                <ComboBoxItem Content=”48″ Tag=”48″ FontSize=”48″ />
            </ComboBox>
            <ComboBox x:Name=”cmbFontFamily” FontFamily=”{Binding SelectedItem.FontFamily, RelativeSource={RelativeSource Self}}” SelectionChanged=”cmbFontFamily_SelectionChanged”>
                <ComboBoxItem Content=”Arial” Tag=”Arial” FontFamily=”Arial” IsSelected=”True” />
                <ComboBoxItem Content=”Verdana” Tag=”Verdana” FontFamily=”Verdana” />
            </ComboBox>
            <Button Name=”btnBold” Content=”加粗” Click=”btnBold_Click” />
            <Button Name=”btnItalic” Content=”斜体” Click=”btnItalic_Click” />
            <Button Name=”btnUnderline” Content=”下划线” Click=”btnUnderline_Click” />
            <Button Name=”btnHyperlink” Content=”插入超级链接的 Demo” Click=”btnHyperlink_Click” />
            <Button Name=”btnUIElement” Content=”插入 UIElement 的 Demo” Click=”btnUIElement_Click” />
            <ToggleButton Name=”btnXaml” Content=”xaml” Checked=”btnXaml_Checked” Unchecked=”btnXaml_Checked” />
            <ToggleButton Name=”btnPreview” Content=”预览” Checked=”btnPreview_Checked” Unchecked=”btnPreview_Checked” />
            <Button Name=”btnTextPointerDemo” Content=”TextPointer 的 Demo (将光标当前四处岗位及文本结尾的文全变为绿色)” Click=”btnTextPointerDemo_Click” />
        </StackPanel>
        
        <Grid Width=”600″ Height=”400″>
            <RichTextBox Name=”richTextBox” VerticalScrollBarVisibility=”Auto”>
                <Paragraph>
                    webabcd
                </Paragraph>
                <Paragraph>
                    <Span>webabcd</Span>
                    <LineBreak />
                    <Bold>webabcd</Bold>
                    <LineBreak />
                    <Italic>webabcd</Italic>
                    <LineBreak />
                    <Underline>webabcd</Underline>
                    <LineBreak />
                    <Run FontFamily=”Arial” FontSize=”20″ FontStretch=”Normal” FontStyle=”Italic” FontWeight=”Bold” Foreground=”Red” TextDecorations=”underline” Text=”webabcd” />
                    <LineBreak />
                    <Hyperlink TargetName=”_black” NavigateUri=”http://webabcd.cnblogs.com/"&gt;webabcd&lt;/Hyperlink&gt;
                    <LineBreak />
                    <InlineUIContainer>
                        <Image Source=”/Resource/Logo.jpg” Height=”100″ Width=”100″ ToolTipService.ToolTip=”我是唤醒” />
                    </InlineUIContainer>
                </Paragraph>
            </RichTextBox>
            <TextBox Name=”txtXaml” TextWrapping=”Wrap” VerticalScrollBarVisibility=”Auto” Visibility=”Collapsed” />
        </Grid>
        
        <TextBlock Name=”lblMsg” />
        
    </StackPanel>
</navigation:Page>

                var verifier = Request.Params[“code”];
                string state = Session[“requeststate”].ToString();
                qzone = new QOpenClient(verifier, state);
                currentUser = qzone.GetCurrentUser();
                if (null != currentUser)
                {
                    this.result.Text = “成功登陆”;
                    this.Nickname.Text = currentUser.Nickname;
                    this.Figureurl.ImageUrl = currentUser.Figureurl;
                }
                Session[“QzoneOauth”] = qzone;

RichTextBoxDemo.xaml.cs

            }

图片 7图片 8代码

     }

/*
 * RichTextBox – 编辑器。用于展示或编辑文本、超链、图片、UI元素等
 */

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Media.Imaging;

这边说明一下应用QQ互联登陆是获得不交用户之QQ号的,只见面沾到用户之OpenId,OpenID和QQ号是各个对许涉及。

namespace Silverlight40.Control
{
    public partial class RichTextBoxDemo : Page
    {
        public RichTextBoxDemo()
        {
            InitializeComponent();
        }

当地测试
  • 前提准备,了解本地Host文件的企图

  • 找到C:\WINDOWS\system32\drivers\etc\hosts这个文件

  • 就此文件方式打开
  • 加一行:127.0.0.1 www.domain.com
  • 起先本地服务器
  • 启动浏览器访问 http://www.domain.com/

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            /*
             * RichTextBox 的内容结构说明如下:
             * 
             * Block – 抽象类。块级内容的基类
             *     Paragraph – 段落,包含一组外联元素。继承自 Block
             * Inline – 抽象类。内联元素的基类
             *     Run – 文本。继承自 Inline
             *     LineBreak – 换行。继承自 Inline
             *     Span – 文本。继承自 Inline
             *         Hyperlink – 超链接。继承自 Span
             *         Bold – 加粗。继承自 Span
             *         Italic – 斜体。继承自 Span
             *         Underline – 下划线。继承自 Span
             *     InlineUIContainer – 用于承载 UIElement 类型的靶子。继承自 Span
             * TextElement – TextElement是 Inline 的基类,可以对那个安如下属性
             *     FontSize – 字体大小
             *     FontFamily – 字体名称
             *     Foreground – 字体颜色(因为 xaml 属性仅支持可代表为一个字符串的属性值。所以这边只能用 SolidColorBrush,而休可知利用 LinearGradientBrush 之类的)
             *     FontWeight – 笔画粗细
             *     FontStyle – 是否斜体
             *     FontStretch – 字体的拉伸程度(需要字体支持)
             */

其他
  • 下载: http://opensns.codeplex.com/
  • 路示范:http://www.win8charm.com/ 
  • SDK 在线文档:http://help.win8charm.com/ 
  • QQ群:80767552
  • 流动:众人拾柴火焰高,欢迎各位反馈使用中的bug。
  • 报告issue请来:http://opensns.codeplex.com/workitem/list/basic
  • 站内信或者下方式
  • 微博:http://t.qq.com/geffzhang
  • 邮箱:geffzhang#qq.com
  • 博客:http://www.cnblogs.com/shanyou 

            /* 
             * Paragraph.Inlines – 段落所包含的内联元素的成团
             * RichTextBox.Blocks – RichTextBox 中之块级元素的集合
             * RichTextBox.Xaml – RichTextBox 中之情节的 xaml 代码
             */

            Bold bold = new Bold();
            bold.Inlines.Add(“web”);

            LineBreak lineBreak = new LineBreak();

            Run run = new Run();
            run.Text = “abcd”;
            
            Paragraph paragraph = new Paragraph();
            paragraph.Inlines.Add(bold);
            paragraph.Inlines.Add(lineBreak);
            paragraph.Inlines.Add(run);

            richTextBox.Blocks.Add(paragraph);
        }

        /*
         * RichTextBox.Selection – 获取 RichTextBox 中的入选内容,返回一个 TextSelection 类型的目标
         * TextSelection.ApplyPropertyValue(DependencyProperty formattingProperty,    Object value) – 为当选的情节指定其格式的性质与价值
         *     DependencyProperty formattingProperty – 格式的特性
         *     Object value – 格式的属性之价值
         * TextSelection.Text – 选中的情被之纯文本内容
         * TextSelection.Xaml – 选中的内容的 xaml 代码
         * TextSelection.Insert() – 把当下选中的情替换成指定的 TextElement
         * 以下分别举例如何设置选中文本的字体大小、字体名称、加多少、斜体、下划线
         */
        private void cmbFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (richTextBox != null && richTextBox.Selection.Text.Length > 0)
            {
                richTextBox.Selection.ApplyPropertyValue(Run.FontSizeProperty, double.Parse((cmbFontSize.SelectedItem as ComboBoxItem).Tag.ToString()));
            }
        }
        private void cmbFontFamily_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (richTextBox != null && richTextBox.Selection.Text.Length > 0)
            {
                richTextBox.Selection.ApplyPropertyValue(Run.FontFamilyProperty, new FontFamily((cmbFontFamily.SelectedItem as ComboBoxItem).Tag.ToString()));
            }
        }
        private void btnBold_Click(object sender, RoutedEventArgs e)
        {
            if (richTextBox.Selection.Text.Length > 0)
            {
                if (richTextBox.Selection.GetPropertyValue(Run.FontWeightProperty) is FontWeight && ((FontWeight)richTextBox.Selection.GetPropertyValue(Run.FontWeightProperty)) == FontWeights.Normal)
                    richTextBox.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold);
                else
                    richTextBox.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal);
            }
        }
        private void btnItalic_Click(object sender, RoutedEventArgs e)
        {
            if (richTextBox.Selection.Text.Length > 0)
            {
                if (richTextBox.Selection.GetPropertyValue(Run.FontStyleProperty) is FontStyle && ((FontStyle)richTextBox.Selection.GetPropertyValue(Run.FontStyleProperty)) == FontStyles.Normal)
                    richTextBox.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Italic);
                else
                    richTextBox.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Normal);
            }
        }
        private void btnUnderline_Click(object sender, RoutedEventArgs e)
        {
            if (richTextBox.Selection.Text.Length > 0)
            {
                if (richTextBox.Selection.GetPropertyValue(Run.TextDecorationsProperty) == null)
                    richTextBox.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline);
                else
                    richTextBox.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, null);
            }
        }

        /*
         * TextSelection.Insert() – 把当前选中的情替换成指定的 TextElement
         * Hyperlink – 一个用来展示过链接的内联元素。Hyperlink继承自Span,Span继承自Inline,Inline继承自TextElement
         * 以下举例如何插入超链接(要于 RichTextBox 使超链接有效,需要将 RichTextBox 设置也展示状态)
         */
        private void btnHyperlink_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink hyperlink = new Hyperlink();
            hyperlink.TargetName = “_blank”;
            hyperlink.NavigateUri = new Uri(“http://webabcd.cnblogs.com/”);
            hyperlink.Inlines.Add(“webabcd blog”);
            richTextBox.Selection.Insert(hyperlink);
        }

        /*
         * InlineUIContainer – 一个容器,可以承接任何 UIElement 类型的目标。InlineUIContainer继承自Inline
         * 以下举例如何插入图片
         */
        private void btnUIElement_Click(object sender, RoutedEventArgs e)
        {
            Image img = new Image();
            img.Source = new BitmapImage(new Uri(“/Resource/Logo.jpg”, UriKind.Relative));
            img.Width = 100;
            img.Height = 100;

            InlineUIContainer container = new InlineUIContainer();
            container.Child = img;

            richTextBox.Selection.Insert(container);
        }

        /*
         * RichTextBox.Xaml – RichTextBox 中之情节之 xaml 代码
         * 以下举例如何在“显示模式”和“代码模式”之间切换
         */
        private void btnXaml_Checked(object sender, RoutedEventArgs e)
        {
            if (btnXaml.IsChecked.Value)
            {
                txtXaml.Text = richTextBox.Xaml;
                txtXaml.Visibility = Visibility.Visible;
            }
            else
            {
                richTextBox.Xaml = txtXaml.Text;
                txtXaml.Visibility = Visibility.Collapsed;
            }
        }

        /*
         * RichTextBox.IsReadOnly – 指定是否好当 RichTextBox 中修内容
         *     true – 显示模式
         *     false – 编辑模式(此模式下足经过快捷键的艺术来支持取消 Ctrl+Z 和重做 Ctrl+Y 操作)
         * 以下举例如何预览 RichTextBox 中的内容(注:只有以亮模式中超链接才生效)
         */
        private void btnPreview_Checked(object sender, RoutedEventArgs e)
        {
            richTextBox.IsReadOnly = btnPreview.IsChecked.Value;
        }

        private void btnTextPointerDemo_Click(object sender, RoutedEventArgs e)
        {
            /*
             * TextPointer – 代表 RichTextBox 中的一个职位
             * 插入位置(Insertion Position)的定义:
             *     TextPointer 出现于情节中的字符中虽然为插入职
             *     TextPointer 出现在概念内容结构的要素标记之间,则这岗位不是插位置。例如,两单相邻段落标记(即前一个段的了断标记和下一个段落的开端标记)之间的职位就是是一个可行的 TextPointer 位置,但无是插位置
             * TextPointer.CompareTo(TextPointer tp) – 当前 TextPointer 位于指定的 TextPointer 之前则也 -1,之后则也 1,相同则为 0
             * TextPointer.IsAtInsertionPosition – 当前 TextPointer 是否是一个插位置
             * TextPointer.GetNextInsertionPosition(LogicalDirection direction) – 获取当前 TextPointer 的准指定的逻辑方向的下一个插位置
             *     LogicalDirection – 逻辑方向 [System.Windows.Documents.LogicalDirection 枚举]
             *         LogicalDirection.Forward – 向前
             *         LogicalDirection.Backward – 向后
             * TextPointer.GetPositionAtOffset(int offset, LogicalDirection direction) – 获取当前 TextPointer 的仍指定的逻辑方向偏移了依定值的 TextPointer
             * TextPointer.Parent – 包含当前 TextPointer 的器皿。比如,文字的 Parent 是 run ;RichTextBox.ContentEnd 的 Parent 是 RichTextBox
             * 
             * RichTextBox.ContentStart – RichTextBox 内容之初始的 TextPointer(肯定不是插位置)
             * RichTextBox.ContentEnd – RichTextBox 内容之尾声的 TextPointer(肯定不是插位置)
             * RichTextBox.GetPositionFromPoint(Point point) – 获取离指定 Point 最近的插位置
             * RichTextBox.Selection – 获取 RichTextBox 中的入选内容,返回一个 TextSelection 类型的目标
             * TextSelection.Start – 选中内容之初步 TextPointer
             * TextSelection.End – 选中内容的上马 TextPointer
             * TextSelection.Select(TextPointer tp1, TextPointer tp2) – 指定两独 TextPointer 来更新选中内容
             * 
             * 在 RichTextBox 中叫视为一个标志的发生:TextElement 的发端或结标记;InlineUIContainer 中之 UIElement 元素;Run 中的字符
             */

            // 将光标当前所在岗位及文本结尾的字全变为绿色
            TextPointer currentPointer = richTextBox.Selection.Start;
            TextPointer endPointer = richTextBox.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
            richTextBox.Selection.Select(currentPointer, endPointer);
            richTextBox.Selection.ApplyPropertyValue(Run.ForegroundProperty, Colors.Green);

            // 将光标当前各地岗位及文本结尾的契消息输出到页面上
            while (currentPointer.CompareTo(endPointer) == -1)
            {
                string currentChar = “”;

                TextPointer nextPointer = currentPointer.GetNextInsertionPosition(LogicalDirection.Forward);
                if (nextPointer != null)
                {
                    richTextBox.Selection.Select(currentPointer, nextPointer);
                    if (richTextBox.Selection.Text.Length != 0)
                        currentChar = richTextBox.Selection.Text;
                }

                lblMsg.Text += currentChar;

                currentPointer = currentPointer.GetNextInsertionPosition(LogicalDirection.Forward);
            }
        }
    }
}

OK
[源码下载]