Click here to Skip to main content
15,896,348 members
Articles / Desktop Programming / WPF

CodeBox 2: An Extended and Improved Version of the CodeBox with Line Numbers

Rate me:
Please Sign up or sign in to vote.
4.83/5 (20 votes)
10 Oct 2009CPOL9 min read 141.2K   3.4K   65  
A WPF textbox supporting line numbering, highlighting, underlines, and strikethroughs.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Markup;
namespace ColoredWordPad
{
    /// <summary>
    /// Class came from http://agsmith.wordpress.com/2008/09/19/accessing-enum-members-in-xaml/
    /// Markup extension that provides a list of the members of a given enum.
    /// </summary>
    public class EnumListExtension : MarkupExtension
    {
        #region Member Variables


        private Type _enumType;
        private bool _asString;


        #endregion //Member Variables


        #region Constructor
        /// <summary>
        /// Initializes a new EnumListExtension"
        /// </summary>
        public EnumListExtension()
        {
        }


        /// <summary>
        /// Initializes a new EnumListExtension
        /// </summary>
        /// <param name="enumType">The type of enum whose members are to be returned.</param>
        public EnumListExtension(Type enumType)
        {
            this.EnumType = enumType;
        }
        #endregion //Constructor




        #region Properties
        /// <summary>
        /// Gets/sets the type of enumeration to return 
        /// </summary>
        public Type EnumType
        {
            get { return this._enumType; }
            set
            {
                if (value != this._enumType)
                {
                    if (null != value)
                    {
                        Type enumType = Nullable.GetUnderlyingType(value) ?? value;


                        if (enumType.IsEnum == false)
                            throw new ArgumentException("Type must be for an Enum.");
                    }


                    this._enumType = value;
                }
            }
        }


        /// <summary>
        /// Gets/sets a value indicating whether to display the enumeration members as strings using the Description on the member if available.
        /// </summary>
        public bool AsString
        {
            get { return this._asString; }
            set { this._asString = value; }
        }
        #endregion //Properties


        #region Base class overrides
        /// <summary>
        /// Returns a list of items for the specified <see cref=”EnumType”/>. Depending on the <see cref=”AsString”/> property, the 
        /// items will be returned as the enum member value or as strings.
        /// </summary>
        /// <param name="serviceProvider">An object that provides services for the markup extension.</param>
        /// <returns></returns>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (null == this._enumType)
                throw new InvalidOperationException("The EnumType must be specified.");


            Type actualEnumType = Nullable.GetUnderlyingType(this._enumType) ?? this._enumType;
            Array enumValues = Enum.GetValues(actualEnumType);


            // if the object itself is to be returned then just use GetValues
            // 
            if (this._asString == false)
            {
                if (actualEnumType == this._enumType)
                    return enumValues;


                Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
                enumValues.CopyTo(tempArray, 1);
                return tempArray;
            }


            List<string> items = new List<string>();


            if (actualEnumType != this._enumType)
                items.Add(null);


            // otherwise we must process the list
            foreach (object item in Enum.GetValues(this._enumType))
            {
                string itemString = item.ToString();
                FieldInfo field = this._enumType.GetField(itemString);
                object[] attribs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);


                if (null != attribs && attribs.Length > 0)
                    itemString = ((DescriptionAttribute)attribs[0]).Description;


                items.Add(itemString);
            }


            return items.ToArray();
        }
        #endregion //Base class overrides
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Written software for what seems like forever. I'm currenly infatuated with WPF. Hopefully my affections are returned.

Comments and Discussions