Not too long ago, someone asked me why they couldn't use their mouse to select and copy text from their favorite Silverlight application to paste into other applications they use on a daily basis, like Word or Excel. "I can do it on other web applications, why not yours?" is what I kept hearing during the course of the project. So, because of my desire to make the user happy, along with the fact that I would never hear the end of it if I didn't come up with a solution, I started looking for a way to make our fancy new "Rich Internet Application" behave more like, here it comes... a web page! Ironic, isn't it.
Take a look at this innocent looking Silverlight application with a couple of paragraphs of text:

They might look the same (minus the smiley faces), but the Custom TextBlock allows the user to select some or all of the text content for copy-and-paste operations, using CTRL+C. Here it is in action:

Unfortunately, the TextBlock class is sealed, so I derived the CustomTextBlock control from a TextBox and predefined some settings that would make it appear like a TextBlock. This probably could have easily been done through a Style or a custom ControlTemplate, but I chose to keep all of the property settings in the .cs file for the purposes of this post. Please feel free to use this as is, or offer any feedback or suggestions in the comments.
XAML:
<UserControl x:Class="ControlSamples.MainPage"
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:cs="clr-namespace:ControlSamples"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
>
<Grid x:Name="LayoutRoot" Background="SteelBlue">
<StackPanel Width="500" Margin="30">
<TextBlock Text="Standard TextBlock :(" FontSize="15" FontWeight="Bold" />
<TextBlock TextWrapping="Wrap">
Lorem ipsum dolor sit amet, consectetur adipiscing elit...
</TextBlock>
<Border Height="1" BorderThickness="1" BorderBrush="Black" Margin="0,20" />
<TextBlock Text="Custom TextBlock :)" FontSize="15" FontWeight="Bold" />
<cs:CustomTextBlock>
<cs:CustomTextBlock.Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit...
</cs:CustomTextBlock.Text>
</cs:CustomTextBlock>
</StackPanel>
</Grid>
</UserControl>
CS:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace ControlSamples
{
public class CustomTextBlock : TextBox
{
private Border MouseOverBorder;
private Border ReadOnlyBorder;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var zeroThickness = new Thickness(0);
var transparent = new SolidColorBrush(Colors.Transparent);
var contentElement = GetTemplateChild("ContentElement") as ScrollViewer;
MouseOverBorder = contentElement.Parent as Border;
ReadOnlyBorder = ((Grid) MouseOverBorder.Parent).Children[0] as Border;
ReadOnlyBorder.Background = transparent;
ReadOnlyBorder.BorderThickness = zeroThickness;
Background = transparent;
BorderThickness = zeroThickness;
Padding = zeroThickness;
TextWrapping = TextWrapping.Wrap;
IsReadOnly = true;
}
}
}
UPDATE: I just came across an old forum post that shows how to do something similar using a ControlTemplate: http://forums.silverlight.net/forums/p/30789/98642.aspx
Enjoy!
Bobby