Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / AccessText.cs / 1 / AccessText.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System.Collections;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Markup;
using System.Diagnostics;
using System.Xml;
using MS.Internal;
namespace System.Windows.Controls
{
///
/// AccessText Element - Register an accesskey specified after the underscore character in the text.
///
[ContentProperty("Text")]
public class AccessText : FrameworkElement, IAddChild
{
//-------------------------------------------------------------------
//
// IContentHost Members
//
//-------------------------------------------------------------------
#region IAddChild members
///
/// Called to Add the object as a Child.
///
///
/// Object to add as a child
///
void IAddChild.AddChild(Object value)
{
((IAddChild)TextBlock).AddChild(value);
}
///
/// Called when text appears under the tag in markup.
///
///
/// Text to Add to the Object
///
void IAddChild.AddText(string text)
{
((IAddChild)TextBlock).AddText(text);
}
#endregion IAddChild members
//--------------------------------------------------------------------
//
// LogicalTree
//
//-------------------------------------------------------------------
#region LogicalTree
///
/// Returns enumerator to logical children.
///
protected internal override IEnumerator LogicalChildren
{
get
{
return new RangeContentEnumerator(TextContainer.Start, TextContainer.End);
}
}
#endregion LogicalTree
//--------------------------------------------------------------------
//
// Constructors
//
//--------------------------------------------------------------------
#region Constructors
///
/// AccessText constructor.
///
public AccessText() : base()
{
}
#endregion Constructors
//-------------------------------------------------------------------
//
// Public Properties
//
//--------------------------------------------------------------------
#region Public Properties
///
/// Read only access to the key after the first underline character
///
public char AccessKey
{
get
{
//
return (_accessKey != null && _accessKey.Text.Length > 0) ? _accessKey.Text[0] : (char)0;
}
}
#endregion Public Properties
//-------------------------------------------------------------------
//
// Public Dynamic Properties
//
//-------------------------------------------------------------------
#region Public Dynamic Properties
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(AccessText),
new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextChanged)));
///
/// The Text property defines the text to be displayed.
///
[DefaultValue("")]
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontFamilyProperty =
TextElement.FontFamilyProperty.AddOwner(typeof(AccessText));
///
/// The FontFamily property specifies the name of font family.
///
[Localizability(
LocalizationCategory.Font,
Modifiability = Modifiability.Unmodifiable
)]
public FontFamily FontFamily
{
get { return (FontFamily) GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontStyleProperty =
TextElement.FontStyleProperty.AddOwner(typeof(AccessText));
///
/// The FontStyle property requests normal, italic, and oblique faces within a font family.
///
public FontStyle FontStyle
{
get { return (FontStyle) GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontWeightProperty =
TextElement.FontWeightProperty.AddOwner(typeof(AccessText));
///
/// The FontWeight property specifies the weight of the font.
///
public FontWeight FontWeight
{
get { return (FontWeight) GetValue(FontWeightProperty); }
set { SetValue(FontWeightProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontStretchProperty =
TextElement.FontStretchProperty.AddOwner(typeof(AccessText));
///
/// The FontStretch property selects a normal, condensed, or extended face from a font family.
///
public FontStretch FontStretch
{
get { return (FontStretch) GetValue(FontStretchProperty); }
set { SetValue(FontStretchProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontSizeProperty =
TextElement.FontSizeProperty.AddOwner(typeof(AccessText));
///
/// The FontSize property specifies the size of the font.
///
[TypeConverter(typeof(FontSizeConverter))]
[Localizability(LocalizationCategory.None)]
public double FontSize
{
get { return (double) GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty ForegroundProperty =
TextElement.ForegroundProperty.AddOwner(typeof(AccessText));
///
/// The Foreground property specifies the foreground brush of an element's text content.
///
public Brush Foreground
{
get { return (Brush) GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty BackgroundProperty =
TextElement.BackgroundProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The Background property defines the brush used to fill the content area.
///
public Brush Background
{
get { return (Brush) GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextDecorationsProperty =
Inline.TextDecorationsProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
new FreezableDefaultValueFactory(TextDecorationCollection.Empty),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextDecorations property specifies decorations that are added to the text of an element.
///
public TextDecorationCollection TextDecorations
{
get { return (TextDecorationCollection) GetValue(TextDecorationsProperty); }
set { SetValue(TextDecorationsProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextEffectsProperty =
TextElement.TextEffectsProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
new FreezableDefaultValueFactory(TextEffectCollection.Empty),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextEffects property specifies effects that are added to the text of an element.
///
public TextEffectCollection TextEffects
{
get { return (TextEffectCollection) GetValue(TextEffectsProperty); }
set { SetValue(TextEffectsProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty LineHeightProperty =
Block.LineHeightProperty.AddOwner(typeof(AccessText));
///
/// The LineHeight property specifies the height of each generated line box.
///
[TypeConverter(typeof(LengthConverter))]
public double LineHeight
{
get { return (double) GetValue(LineHeightProperty); }
set { SetValue(LineHeightProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty LineStackingStrategyProperty =
Block.LineStackingStrategyProperty.AddOwner(typeof(AccessText));
///
/// The LineStackingStrategy property specifies how lines are placed
///
public LineStackingStrategy LineStackingStrategy
{
get { return (LineStackingStrategy)GetValue(LineStackingStrategyProperty); }
set { SetValue(LineStackingStrategyProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextAlignmentProperty =
Block.TextAlignmentProperty.AddOwner(typeof(AccessText));
///
/// The TextAlignment property specifies horizontal alignment of the content.
///
public TextAlignment TextAlignment
{
get { return (TextAlignment) GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextTrimmingProperty =
TextBlock.TextTrimmingProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
TextTrimming.None,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextTrimming property specifies the trimming behavior situation
/// in case of clipping some textual content caused by overflowing the line's box.
///
public TextTrimming TextTrimming
{
get { return (TextTrimming) GetValue(TextTrimmingProperty); }
set { SetValue(TextTrimmingProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextWrappingProperty =
TextBlock.TextWrappingProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
TextWrapping.NoWrap,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextWrapping property controls whether or not text wraps
/// when it reaches the flow edge of its containing block box.
///
public TextWrapping TextWrapping
{
get { return (TextWrapping) GetValue(TextWrappingProperty); }
set { SetValue(TextWrappingProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty BaselineOffsetProperty =
TextBlock.BaselineOffsetProperty.AddOwner(typeof(AccessText), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPropertyChanged)));
///
/// The BaselineOffset property provides an adjustment to baseline offset
///
public double BaselineOffset
{
get { return (double) GetValue(BaselineOffsetProperty); }
set { SetValue(BaselineOffsetProperty, value); }
}
#endregion Public Dynamic Properties
//-------------------------------------------------------------------
//
// Protected Methods
//
//--------------------------------------------------------------------
#region Protected Methods
///
/// Content measurement.
///
/// Constraint size.
/// Computed desired size.
protected sealed override Size MeasureOverride(Size constraint)
{
TextBlock.Measure(constraint);
return TextBlock.DesiredSize;
}
///
/// Content arrangement.
///
/// Size that element should use to arrange itself and its children.
protected sealed override Size ArrangeOverride(Size arrangeSize)
{
TextBlock.Arrange(new Rect(arrangeSize));
return arrangeSize;
}
#endregion Protected Methods
//-------------------------------------------------------------------
//
// Internal Methods
//
//--------------------------------------------------------------------
#region Internal Methods
internal static bool HasCustomSerialization(object o)
{
Run accessKey = o as Run;
return accessKey != null && HasCustomSerializationStorage.GetValue(accessKey);
}
#endregion Internal methods
//--------------------------------------------------------------------
//
// Internal Properties
//
//-------------------------------------------------------------------
#region Internal Properties
internal TextBlock TextBlock
{
get
{
if (_textBlock == null)
CreateTextBlock();
return _textBlock;
}
}
internal static char AccessKeyMarker
{
get { return _accessKeyMarker; }
}
#endregion Internal Properties
//--------------------------------------------------------------------
//
// Private Methods
//
//-------------------------------------------------------------------
#region Private Methods
private TextContainer TextContainer
{
get
{
if (_textContainer == null)
CreateTextBlock();
return _textContainer;
}
}
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AccessText)d).TextBlock.SetValue(e.Property, e.NewValue);
}
///
/// CreateTextBlock - Creates a text block, adds as visual child, databinds properties and sets up appropriate event listener.
///
private void CreateTextBlock()
{
_textContainer = new TextContainer(this, false /* plainTextOnly */);
_textBlock = new TextBlock();
AddVisualChild(_textBlock);
_textBlock.IsContentPresenterContainer = true;
_textBlock.SetTextContainer(_textContainer);
InitializeTextContainerListener();
}
///
/// Gets the Visual children count of the AccessText control.
///
protected override int VisualChildrenCount
{
get { return 1; }
}
///
/// Gets the Visual child at the specified index.
///
protected override Visual GetVisualChild(int index)
{
if (index != 0)
{
throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange));
}
return TextBlock;
}
// Provides custom serialization for this element
internal static void SerializeCustom(XmlWriter xmlWriter, object o)
{
Run inlineScope = o as Run;
if (inlineScope != null)
{
xmlWriter.WriteString(AccessKeyMarker + inlineScope.Text);
}
}
private static Style AccessKeyStyle
{
get
{
if (_accessKeyStyle == null)
{
Style accessKeyStyle = new Style(typeof(Run));
Trigger trigger = new Trigger();
trigger.Property = KeyboardNavigation.ShowKeyboardCuesProperty;
trigger.Value = true;
trigger.Setters.Add(new Setter(TextDecorationsProperty, System.Windows.TextDecorations.Underline));
accessKeyStyle.Triggers.Add(trigger);
accessKeyStyle.Seal();
_accessKeyStyle = accessKeyStyle;
}
return _accessKeyStyle;
}
}
///
/// UpdateAccessKey - Scans forward in the tree looking for the access key marker, replacing it with access key element. We only support one find.
///
private void UpdateAccessKey()
{
TextPointer navigator = new TextPointer(TextContainer.Start);
while (!_accessKeyLocated && navigator.CompareTo(TextContainer.End) < 0 )
{
TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);
switch (symbolType)
{
case TextPointerContext.Text:
string text = navigator.GetTextInRun(LogicalDirection.Forward);
int index = FindAccessKeyMarker(text);
if(index != -1 && index < text.Length - 1)
{
TextPointer keyStart = navigator.GetPositionAtOffset(index + 1);
TextPointer keyEnd = keyStart.GetNextInsertionPosition(LogicalDirection.Forward);
int accessKeyLength = keyStart.GetOffsetToPosition(keyEnd);
_accessKey = new Run(text.Substring(index + 1, accessKeyLength));
_accessKey.Style = AccessKeyStyle;
RegisterAccessKey();
HasCustomSerializationStorage.SetValue(_accessKey, true);
_accessKeyLocated = true;
UninitializeTextContainerListener();
TextContainer.BeginChange();
try
{
TextPointer underlineStart = new TextPointer(navigator, index);
TextRangeEdit.DeleteInlineContent(underlineStart, keyEnd);
_accessKey.RepositionWithContent(underlineStart);
}
finally
{
TextContainer.EndChange();
InitializeTextContainerListener();
}
}
break;
}
navigator.MoveToNextContextPosition(LogicalDirection.Forward);
}
// Convert double _ to single _
navigator = new TextPointer(TextContainer.Start);
string accessKeyMarker = AccessKeyMarker.ToString();
string doubleAccessKeyMarker = accessKeyMarker + accessKeyMarker;
while (navigator.CompareTo(TextContainer.End) < 0)
{
TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);
switch (symbolType)
{
case TextPointerContext.Text:
string text = navigator.GetTextInRun(LogicalDirection.Forward);
string nexText = text.Replace(doubleAccessKeyMarker, accessKeyMarker);
if (text != nexText)
{
TextPointer keyStart = new TextPointer(navigator, 0);
TextPointer keyEnd = new TextPointer(navigator, text.Length);
UninitializeTextContainerListener();
TextContainer.BeginChange();
try
{
keyEnd.InsertTextInRun(nexText);
TextRangeEdit.DeleteInlineContent(keyStart, keyEnd);
}
finally
{
TextContainer.EndChange();
InitializeTextContainerListener();
}
}
break;
}
navigator.MoveToNextContextPosition(LogicalDirection.Forward);
}
}
// Returns the index of _ marker.
// _ can be escaped by double _
private static int FindAccessKeyMarker(string text)
{
int lenght = text.Length;
int startIndex = 0;
while (startIndex < lenght)
{
int index = text.IndexOf(AccessKeyMarker, startIndex);
if (index == -1)
return -1;
// If next char exist and different from _
if (index + 1 < lenght && text[index + 1] != AccessKeyMarker)
return index;
startIndex = index + 2;
}
return -1;
}
internal static string RemoveAccessKeyMarker(string text)
{
if (!string.IsNullOrEmpty(text))
{
int index = FindAccessKeyMarker(text);
if (index >=0 && index < text.Length - 1)
return text.Remove(index, 1);
}
return text;
}
private void RegisterAccessKey()
{
if (_currentlyRegistered != null)
{
AccessKeyManager.Unregister(_currentlyRegistered, this);
_currentlyRegistered = null;
}
string key = _accessKey.Text;
if (!string.IsNullOrEmpty(key))
{
AccessKeyManager.Register(key, this);
_currentlyRegistered = key;
}
}
//-------------------------------------------------------------------
// Text helpers
//-------------------------------------------------------------------
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AccessText) d).UpdateText((string) e.NewValue);
}
private void UpdateText(string text)
{
if (text == null)
text = string.Empty;
_accessKeyLocated = false;
_accessKey = null;
TextContainer.BeginChange();
try
{
TextContainer.DeleteContentInternal((TextPointer)TextContainer.Start, TextContainer.End);
Run run = Inline.CreateImplicitRun(this);
((TextPointer)TextContainer.End).InsertTextElement(run);
run.Text = text;
}
finally
{
TextContainer.EndChange();
}
}
// ------------------------------------------------------------------
// Setup event handler.
// -----------------------------------------------------------------
private void InitializeTextContainerListener()
{
TextContainer.Changed += new TextContainerChangedEventHandler(OnTextContainerChanged);
}
// ------------------------------------------------------------------
// Clear event handler.
// ------------------------------------------------------------------
private void UninitializeTextContainerListener()
{
TextContainer.Changed -= new TextContainerChangedEventHandler(OnTextContainerChanged);
}
// -----------------------------------------------------------------
// Handler for TextContainer.Changed notification.
// ------------------------------------------------------------------
private void OnTextContainerChanged(object sender, TextContainerChangedEventArgs args)
{
// Skip changes that only affect properties.
if (args.HasContentAddedOrRemoved)
{
UpdateAccessKey();
}
}
#endregion Private methods
//-------------------------------------------------------------------
//
// Private Fields
//
//-------------------------------------------------------------------
#region Private Fields
//---------------------------------------------------------------
// Text container for actual content
//----------------------------------------------------------------
private TextContainer _textContainer;
//---------------------------------------------------------------
// Visual tree text block
//----------------------------------------------------------------
private TextBlock _textBlock;
//----------------------------------------------------------------
// Visual tree Run - created internally if _ is found
//---------------------------------------------------------------
private Run _accessKey;
//----------------------------------------------------------------
// Flag indicating whether the access key element has been located
//---------------------------------------------------------------
private bool _accessKeyLocated;
//---------------------------------------------------------------
// Defines the charecter to be used in fron of the access key
//---------------------------------------------------------------
private const char _accessKeyMarker = '_';
//----------------------------------------------------------------
// Stores the default Style applied on the internal Run
//---------------------------------------------------------------
private static Style _accessKeyStyle;
//----------------------------------------------------------------
// Flag that indicates if access key is registered with this AccessText
//----------------------------------------------------------------
private string _currentlyRegistered;
//---------------------------------------------------------------
// Flag that indicates that internal Run should have a custom serialization
//----------------------------------------------------------------
private static readonly UncommonField HasCustomSerializationStorage = new UncommonField();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System.Collections;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Markup;
using System.Diagnostics;
using System.Xml;
using MS.Internal;
namespace System.Windows.Controls
{
///
/// AccessText Element - Register an accesskey specified after the underscore character in the text.
///
[ContentProperty("Text")]
public class AccessText : FrameworkElement, IAddChild
{
//-------------------------------------------------------------------
//
// IContentHost Members
//
//-------------------------------------------------------------------
#region IAddChild members
///
/// Called to Add the object as a Child.
///
///
/// Object to add as a child
///
void IAddChild.AddChild(Object value)
{
((IAddChild)TextBlock).AddChild(value);
}
///
/// Called when text appears under the tag in markup.
///
///
/// Text to Add to the Object
///
void IAddChild.AddText(string text)
{
((IAddChild)TextBlock).AddText(text);
}
#endregion IAddChild members
//--------------------------------------------------------------------
//
// LogicalTree
//
//-------------------------------------------------------------------
#region LogicalTree
///
/// Returns enumerator to logical children.
///
protected internal override IEnumerator LogicalChildren
{
get
{
return new RangeContentEnumerator(TextContainer.Start, TextContainer.End);
}
}
#endregion LogicalTree
//--------------------------------------------------------------------
//
// Constructors
//
//--------------------------------------------------------------------
#region Constructors
///
/// AccessText constructor.
///
public AccessText() : base()
{
}
#endregion Constructors
//-------------------------------------------------------------------
//
// Public Properties
//
//--------------------------------------------------------------------
#region Public Properties
///
/// Read only access to the key after the first underline character
///
public char AccessKey
{
get
{
//
return (_accessKey != null && _accessKey.Text.Length > 0) ? _accessKey.Text[0] : (char)0;
}
}
#endregion Public Properties
//-------------------------------------------------------------------
//
// Public Dynamic Properties
//
//-------------------------------------------------------------------
#region Public Dynamic Properties
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(AccessText),
new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnTextChanged)));
///
/// The Text property defines the text to be displayed.
///
[DefaultValue("")]
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontFamilyProperty =
TextElement.FontFamilyProperty.AddOwner(typeof(AccessText));
///
/// The FontFamily property specifies the name of font family.
///
[Localizability(
LocalizationCategory.Font,
Modifiability = Modifiability.Unmodifiable
)]
public FontFamily FontFamily
{
get { return (FontFamily) GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontStyleProperty =
TextElement.FontStyleProperty.AddOwner(typeof(AccessText));
///
/// The FontStyle property requests normal, italic, and oblique faces within a font family.
///
public FontStyle FontStyle
{
get { return (FontStyle) GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontWeightProperty =
TextElement.FontWeightProperty.AddOwner(typeof(AccessText));
///
/// The FontWeight property specifies the weight of the font.
///
public FontWeight FontWeight
{
get { return (FontWeight) GetValue(FontWeightProperty); }
set { SetValue(FontWeightProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontStretchProperty =
TextElement.FontStretchProperty.AddOwner(typeof(AccessText));
///
/// The FontStretch property selects a normal, condensed, or extended face from a font family.
///
public FontStretch FontStretch
{
get { return (FontStretch) GetValue(FontStretchProperty); }
set { SetValue(FontStretchProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty FontSizeProperty =
TextElement.FontSizeProperty.AddOwner(typeof(AccessText));
///
/// The FontSize property specifies the size of the font.
///
[TypeConverter(typeof(FontSizeConverter))]
[Localizability(LocalizationCategory.None)]
public double FontSize
{
get { return (double) GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty ForegroundProperty =
TextElement.ForegroundProperty.AddOwner(typeof(AccessText));
///
/// The Foreground property specifies the foreground brush of an element's text content.
///
public Brush Foreground
{
get { return (Brush) GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty BackgroundProperty =
TextElement.BackgroundProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The Background property defines the brush used to fill the content area.
///
public Brush Background
{
get { return (Brush) GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextDecorationsProperty =
Inline.TextDecorationsProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
new FreezableDefaultValueFactory(TextDecorationCollection.Empty),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextDecorations property specifies decorations that are added to the text of an element.
///
public TextDecorationCollection TextDecorations
{
get { return (TextDecorationCollection) GetValue(TextDecorationsProperty); }
set { SetValue(TextDecorationsProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextEffectsProperty =
TextElement.TextEffectsProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
new FreezableDefaultValueFactory(TextEffectCollection.Empty),
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextEffects property specifies effects that are added to the text of an element.
///
public TextEffectCollection TextEffects
{
get { return (TextEffectCollection) GetValue(TextEffectsProperty); }
set { SetValue(TextEffectsProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty LineHeightProperty =
Block.LineHeightProperty.AddOwner(typeof(AccessText));
///
/// The LineHeight property specifies the height of each generated line box.
///
[TypeConverter(typeof(LengthConverter))]
public double LineHeight
{
get { return (double) GetValue(LineHeightProperty); }
set { SetValue(LineHeightProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty LineStackingStrategyProperty =
Block.LineStackingStrategyProperty.AddOwner(typeof(AccessText));
///
/// The LineStackingStrategy property specifies how lines are placed
///
public LineStackingStrategy LineStackingStrategy
{
get { return (LineStackingStrategy)GetValue(LineStackingStrategyProperty); }
set { SetValue(LineStackingStrategyProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextAlignmentProperty =
Block.TextAlignmentProperty.AddOwner(typeof(AccessText));
///
/// The TextAlignment property specifies horizontal alignment of the content.
///
public TextAlignment TextAlignment
{
get { return (TextAlignment) GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextTrimmingProperty =
TextBlock.TextTrimmingProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
TextTrimming.None,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextTrimming property specifies the trimming behavior situation
/// in case of clipping some textual content caused by overflowing the line's box.
///
public TextTrimming TextTrimming
{
get { return (TextTrimming) GetValue(TextTrimmingProperty); }
set { SetValue(TextTrimmingProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty TextWrappingProperty =
TextBlock.TextWrappingProperty.AddOwner(
typeof(AccessText),
new FrameworkPropertyMetadata(
TextWrapping.NoWrap,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnPropertyChanged)));
///
/// The TextWrapping property controls whether or not text wraps
/// when it reaches the flow edge of its containing block box.
///
public TextWrapping TextWrapping
{
get { return (TextWrapping) GetValue(TextWrappingProperty); }
set { SetValue(TextWrappingProperty, value); }
}
///
/// DependencyProperty for property.
///
public static readonly DependencyProperty BaselineOffsetProperty =
TextBlock.BaselineOffsetProperty.AddOwner(typeof(AccessText), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPropertyChanged)));
///
/// The BaselineOffset property provides an adjustment to baseline offset
///
public double BaselineOffset
{
get { return (double) GetValue(BaselineOffsetProperty); }
set { SetValue(BaselineOffsetProperty, value); }
}
#endregion Public Dynamic Properties
//-------------------------------------------------------------------
//
// Protected Methods
//
//--------------------------------------------------------------------
#region Protected Methods
///
/// Content measurement.
///
/// Constraint size.
/// Computed desired size.
protected sealed override Size MeasureOverride(Size constraint)
{
TextBlock.Measure(constraint);
return TextBlock.DesiredSize;
}
///
/// Content arrangement.
///
/// Size that element should use to arrange itself and its children.
protected sealed override Size ArrangeOverride(Size arrangeSize)
{
TextBlock.Arrange(new Rect(arrangeSize));
return arrangeSize;
}
#endregion Protected Methods
//-------------------------------------------------------------------
//
// Internal Methods
//
//--------------------------------------------------------------------
#region Internal Methods
internal static bool HasCustomSerialization(object o)
{
Run accessKey = o as Run;
return accessKey != null && HasCustomSerializationStorage.GetValue(accessKey);
}
#endregion Internal methods
//--------------------------------------------------------------------
//
// Internal Properties
//
//-------------------------------------------------------------------
#region Internal Properties
internal TextBlock TextBlock
{
get
{
if (_textBlock == null)
CreateTextBlock();
return _textBlock;
}
}
internal static char AccessKeyMarker
{
get { return _accessKeyMarker; }
}
#endregion Internal Properties
//--------------------------------------------------------------------
//
// Private Methods
//
//-------------------------------------------------------------------
#region Private Methods
private TextContainer TextContainer
{
get
{
if (_textContainer == null)
CreateTextBlock();
return _textContainer;
}
}
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AccessText)d).TextBlock.SetValue(e.Property, e.NewValue);
}
///
/// CreateTextBlock - Creates a text block, adds as visual child, databinds properties and sets up appropriate event listener.
///
private void CreateTextBlock()
{
_textContainer = new TextContainer(this, false /* plainTextOnly */);
_textBlock = new TextBlock();
AddVisualChild(_textBlock);
_textBlock.IsContentPresenterContainer = true;
_textBlock.SetTextContainer(_textContainer);
InitializeTextContainerListener();
}
///
/// Gets the Visual children count of the AccessText control.
///
protected override int VisualChildrenCount
{
get { return 1; }
}
///
/// Gets the Visual child at the specified index.
///
protected override Visual GetVisualChild(int index)
{
if (index != 0)
{
throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange));
}
return TextBlock;
}
// Provides custom serialization for this element
internal static void SerializeCustom(XmlWriter xmlWriter, object o)
{
Run inlineScope = o as Run;
if (inlineScope != null)
{
xmlWriter.WriteString(AccessKeyMarker + inlineScope.Text);
}
}
private static Style AccessKeyStyle
{
get
{
if (_accessKeyStyle == null)
{
Style accessKeyStyle = new Style(typeof(Run));
Trigger trigger = new Trigger();
trigger.Property = KeyboardNavigation.ShowKeyboardCuesProperty;
trigger.Value = true;
trigger.Setters.Add(new Setter(TextDecorationsProperty, System.Windows.TextDecorations.Underline));
accessKeyStyle.Triggers.Add(trigger);
accessKeyStyle.Seal();
_accessKeyStyle = accessKeyStyle;
}
return _accessKeyStyle;
}
}
///
/// UpdateAccessKey - Scans forward in the tree looking for the access key marker, replacing it with access key element. We only support one find.
///
private void UpdateAccessKey()
{
TextPointer navigator = new TextPointer(TextContainer.Start);
while (!_accessKeyLocated && navigator.CompareTo(TextContainer.End) < 0 )
{
TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);
switch (symbolType)
{
case TextPointerContext.Text:
string text = navigator.GetTextInRun(LogicalDirection.Forward);
int index = FindAccessKeyMarker(text);
if(index != -1 && index < text.Length - 1)
{
TextPointer keyStart = navigator.GetPositionAtOffset(index + 1);
TextPointer keyEnd = keyStart.GetNextInsertionPosition(LogicalDirection.Forward);
int accessKeyLength = keyStart.GetOffsetToPosition(keyEnd);
_accessKey = new Run(text.Substring(index + 1, accessKeyLength));
_accessKey.Style = AccessKeyStyle;
RegisterAccessKey();
HasCustomSerializationStorage.SetValue(_accessKey, true);
_accessKeyLocated = true;
UninitializeTextContainerListener();
TextContainer.BeginChange();
try
{
TextPointer underlineStart = new TextPointer(navigator, index);
TextRangeEdit.DeleteInlineContent(underlineStart, keyEnd);
_accessKey.RepositionWithContent(underlineStart);
}
finally
{
TextContainer.EndChange();
InitializeTextContainerListener();
}
}
break;
}
navigator.MoveToNextContextPosition(LogicalDirection.Forward);
}
// Convert double _ to single _
navigator = new TextPointer(TextContainer.Start);
string accessKeyMarker = AccessKeyMarker.ToString();
string doubleAccessKeyMarker = accessKeyMarker + accessKeyMarker;
while (navigator.CompareTo(TextContainer.End) < 0)
{
TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);
switch (symbolType)
{
case TextPointerContext.Text:
string text = navigator.GetTextInRun(LogicalDirection.Forward);
string nexText = text.Replace(doubleAccessKeyMarker, accessKeyMarker);
if (text != nexText)
{
TextPointer keyStart = new TextPointer(navigator, 0);
TextPointer keyEnd = new TextPointer(navigator, text.Length);
UninitializeTextContainerListener();
TextContainer.BeginChange();
try
{
keyEnd.InsertTextInRun(nexText);
TextRangeEdit.DeleteInlineContent(keyStart, keyEnd);
}
finally
{
TextContainer.EndChange();
InitializeTextContainerListener();
}
}
break;
}
navigator.MoveToNextContextPosition(LogicalDirection.Forward);
}
}
// Returns the index of _ marker.
// _ can be escaped by double _
private static int FindAccessKeyMarker(string text)
{
int lenght = text.Length;
int startIndex = 0;
while (startIndex < lenght)
{
int index = text.IndexOf(AccessKeyMarker, startIndex);
if (index == -1)
return -1;
// If next char exist and different from _
if (index + 1 < lenght && text[index + 1] != AccessKeyMarker)
return index;
startIndex = index + 2;
}
return -1;
}
internal static string RemoveAccessKeyMarker(string text)
{
if (!string.IsNullOrEmpty(text))
{
int index = FindAccessKeyMarker(text);
if (index >=0 && index < text.Length - 1)
return text.Remove(index, 1);
}
return text;
}
private void RegisterAccessKey()
{
if (_currentlyRegistered != null)
{
AccessKeyManager.Unregister(_currentlyRegistered, this);
_currentlyRegistered = null;
}
string key = _accessKey.Text;
if (!string.IsNullOrEmpty(key))
{
AccessKeyManager.Register(key, this);
_currentlyRegistered = key;
}
}
//-------------------------------------------------------------------
// Text helpers
//-------------------------------------------------------------------
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AccessText) d).UpdateText((string) e.NewValue);
}
private void UpdateText(string text)
{
if (text == null)
text = string.Empty;
_accessKeyLocated = false;
_accessKey = null;
TextContainer.BeginChange();
try
{
TextContainer.DeleteContentInternal((TextPointer)TextContainer.Start, TextContainer.End);
Run run = Inline.CreateImplicitRun(this);
((TextPointer)TextContainer.End).InsertTextElement(run);
run.Text = text;
}
finally
{
TextContainer.EndChange();
}
}
// ------------------------------------------------------------------
// Setup event handler.
// -----------------------------------------------------------------
private void InitializeTextContainerListener()
{
TextContainer.Changed += new TextContainerChangedEventHandler(OnTextContainerChanged);
}
// ------------------------------------------------------------------
// Clear event handler.
// ------------------------------------------------------------------
private void UninitializeTextContainerListener()
{
TextContainer.Changed -= new TextContainerChangedEventHandler(OnTextContainerChanged);
}
// -----------------------------------------------------------------
// Handler for TextContainer.Changed notification.
// ------------------------------------------------------------------
private void OnTextContainerChanged(object sender, TextContainerChangedEventArgs args)
{
// Skip changes that only affect properties.
if (args.HasContentAddedOrRemoved)
{
UpdateAccessKey();
}
}
#endregion Private methods
//-------------------------------------------------------------------
//
// Private Fields
//
//-------------------------------------------------------------------
#region Private Fields
//---------------------------------------------------------------
// Text container for actual content
//----------------------------------------------------------------
private TextContainer _textContainer;
//---------------------------------------------------------------
// Visual tree text block
//----------------------------------------------------------------
private TextBlock _textBlock;
//----------------------------------------------------------------
// Visual tree Run - created internally if _ is found
//---------------------------------------------------------------
private Run _accessKey;
//----------------------------------------------------------------
// Flag indicating whether the access key element has been located
//---------------------------------------------------------------
private bool _accessKeyLocated;
//---------------------------------------------------------------
// Defines the charecter to be used in fron of the access key
//---------------------------------------------------------------
private const char _accessKeyMarker = '_';
//----------------------------------------------------------------
// Stores the default Style applied on the internal Run
//---------------------------------------------------------------
private static Style _accessKeyStyle;
//----------------------------------------------------------------
// Flag that indicates if access key is registered with this AccessText
//----------------------------------------------------------------
private string _currentlyRegistered;
//---------------------------------------------------------------
// Flag that indicates that internal Run should have a custom serialization
//----------------------------------------------------------------
private static readonly UncommonField HasCustomSerializationStorage = new UncommonField();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlAttributeCache.cs
- HostedHttpContext.cs
- HierarchicalDataSourceControl.cs
- smtpconnection.cs
- MultipartIdentifier.cs
- MinMaxParagraphWidth.cs
- Ppl.cs
- Panel.cs
- DiscoveryOperationContextExtension.cs
- DbConnectionPoolGroup.cs
- ColumnCollection.cs
- StringUtil.cs
- InputScopeNameConverter.cs
- DataGridTextBox.cs
- RangeBaseAutomationPeer.cs
- Vector3D.cs
- ImageCodecInfo.cs
- DownloadProgressEventArgs.cs
- SqlReorderer.cs
- DocumentEventArgs.cs
- DocumentApplicationJournalEntryEventArgs.cs
- LinearGradientBrush.cs
- ReadWriteObjectLock.cs
- RoutedPropertyChangedEventArgs.cs
- CookieProtection.cs
- HttpConfigurationContext.cs
- UnsafeNativeMethods.cs
- ObjectPropertyMapping.cs
- WindowsAuthenticationModule.cs
- WindowsScrollBar.cs
- CreateUserWizardAutoFormat.cs
- ListViewEditEventArgs.cs
- BCLDebug.cs
- PointF.cs
- SecurityPermission.cs
- SqlLiftIndependentRowExpressions.cs
- TrustManager.cs
- CollectionContainer.cs
- EntityConnectionStringBuilderItem.cs
- SecurityTokenProviderContainer.cs
- DBSchemaRow.cs
- TextCompositionManager.cs
- FormViewUpdateEventArgs.cs
- BigInt.cs
- AnonymousIdentificationModule.cs
- FilePrompt.cs
- BaseDataBoundControl.cs
- XmlExpressionDumper.cs
- DataGridViewRow.cs
- XmlElement.cs
- TdsParserSessionPool.cs
- CodeTypeDeclaration.cs
- RTLAwareMessageBox.cs
- ChangeInterceptorAttribute.cs
- WebPartRestoreVerb.cs
- ColorTransformHelper.cs
- LoggedException.cs
- LassoSelectionBehavior.cs
- TrackingMemoryStream.cs
- Cursors.cs
- Encoder.cs
- RemotingSurrogateSelector.cs
- Compiler.cs
- TraceHandler.cs
- AutoGeneratedFieldProperties.cs
- OpenFileDialog.cs
- BinaryParser.cs
- CodeTypeConstructor.cs
- ElementAction.cs
- UTF8Encoding.cs
- DefaultMemberAttribute.cs
- ExtractorMetadata.cs
- DoubleConverter.cs
- IgnoreSection.cs
- ColorInterpolationModeValidation.cs
- RichTextBoxConstants.cs
- Size3D.cs
- ImmutableObjectAttribute.cs
- RegionInfo.cs
- HttpRawResponse.cs
- HuffmanTree.cs
- DataGridViewButtonCell.cs
- DataGridViewElement.cs
- BamlReader.cs
- ProgressBar.cs
- DetailsViewDeletedEventArgs.cs
- AxWrapperGen.cs
- Classification.cs
- SiteMembershipCondition.cs
- TextFormattingConverter.cs
- MessageQueue.cs
- SqlCacheDependency.cs
- Material.cs
- XmlEncoding.cs
- BitmapSizeOptions.cs
- CalendarDay.cs
- ipaddressinformationcollection.cs
- AutomationPatternInfo.cs
- ToolboxItemFilterAttribute.cs
- ItemMap.cs