Click here to Skip to main content
11,577,643 members (52,993 online)
Click here to Skip to main content
Add your own
alternative version

Resolving Symbolic References in a CodeDOM (Part 7)

, 2 Dec 2012 CDDL 6.2K 342 13
Resolving symbolic references in a CodeDOM.
Nova.0.6.exe.zip
Mono.Cecil.dll
Nova.CLI.exe
Nova.CodeDOM.dll
Nova.Examples.exe
Nova.Studio.exe
Nova.Test.exe
Nova.UI.dll
Nova.0.6.zip
Nova.CLI
Properties
Nova.CodeDOM
CodeDOM
Annotations
Base
Comments
Base
DocComments
CodeRef
Base
List
Name
Base
Other
Simple
CompilerDirectives
Base
Conditionals
Base
Messages
Base
Pragmas
Base
Symbols
Base
Base
Interfaces
Expressions
AnonymousMethods
Base
Operators
Base
Binary
Arithmetic
Base
Assignment
Base
Bitwise
Base
Conditional
Relational
Base
Shift
Base
Other
Base
Unary
Base
Other
References
Base
GotoTargets
Base
Methods
Namespaces
Other
Properties
Types
Base
Variables
Base
Projects
Assemblies
Namespaces
References
Base
Statements
Base
Conditionals
Base
Exceptions
Generics
Constraints
Base
Iterators
Base
Jumps
Loops
Methods
OperatorDecls
Miscellaneous
Namespaces
Properties
Base
Events
Types
Base
Variables
Base
Parsing
Base
Properties
Rendering
Resolving
Utilities
Mono.Cecil
Reflection
Nova.Examples
Properties
Nova.Studio
Images
About.png
Configuration.png
EditCopy.png
EditCut.png
EditDelete.png
EditPaste.png
EditRedo.png
EditUndo.png
Error.png
Exit.png
FileNew.png
FileOpen.png
FileSave.png
FileSaveAll.png
FileSaveAs.png
Find.png
Help.png
Info.png
Logo.png
Options.png
Print.png
PrintPreview.png
Properties.png
Todo.png
Warning.png
Objects.ico
Properties
Settings.settings
Nova.Test
Properties
Nova.UI
CodeDOM
Annotations
Base
Comments
Base
DocComments
CodeRef
Base
List
Name
Base
Other
Simple
CompilerDirectives
Base
Conditionals
Base
Messages
Base
Pragmas
Base
Symbols
Base
Base
Expressions
AnonymousMethods
Base
Operators
Base
Binary
Arithmetic
Base
Assignment
Base
Bitwise
Base
Conditional
Relational
Base
Shift
Base
Other
Base
Unary
Base
Other
References
Base
GotoTargets
Base
Methods
Namespaces
Other
Properties
Types
Base
Variables
Base
Projects
Namespaces
References
Base
Statements
Base
Conditionals
Base
Exceptions
Generics
Constraints
Base
Iterators
Base
Jumps
Loops
Methods
OperatorDecls
Miscellaneous
Namespaces
Properties
Base
Events
Types
Base
Variables
Base
Properties
Resolving
Utilties
// Nova.Studio - a GUI test framework for the Nova.CodeDOM C# object model library.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

using Nova.CodeDOM;
using Nova.UI;

namespace Nova.Studio
{
    /// <summary>
    /// Interaction logic for CodeWindow.xaml
    /// </summary>
    public partial class CodeWindow : UserControl
    {
        #region /* FIELDS */

        protected string _description;
        protected CodeObjectVM _codeVM;
        protected bool _textViewEnabled;
        protected double _windowHeight;
        protected double _verticalScrollOffset;
        protected double _fontHeight;
        protected bool _skipFirstScrollEvent = true;
        protected CodeRenderer _renderer;
        protected Dictionary<CodeObject, CodeObjectVM> _codeObject2VM = new Dictionary<CodeObject, CodeObjectVM>();

        // Save values for text view
        protected readonly GridLength _textColumnWidth;
        protected readonly Thickness _codeBorderMargin;

        #endregion

        #region /* CONSTRUCTORS */

        public CodeWindow(string description, CodeObjectVM codeVM)
        {
            InitializeComponent();
            BindCommands(Application.Current.MainWindow);
            _description = description;

            // Create a new CodeObjectVM tree, so that are changes are reflected and all VMs are added to the local dictionary
            _codeVM = CodeObjectVM.CreateVM(codeVM.CodeObject, codeVM.ParentVM, false, _codeObject2VM);

            _fontHeight = 15;  // Default - changes in Render()
            _textColumnWidth = mainGrid.ColumnDefinitions[1].Width;
            _codeBorderMargin = codeBorder.Margin;

            // WPF tooltips are an unbelievable nightmare!!  Any ToolTip set to null will inherit from the parent, and
            // doing ToolTipService.SetIsEnabled(control, false) has the SAME effect!  Stopping tooltip inheritance requires
            // both setting a non-null value, and then hacking the display so that it's off-screen!!!
            // THIS IS NO LONGER USED in favor of custom tooltips, and moved the TabItem tooltip to the Header to prevent it
            // from stupidly cascading to all controls on the tab.
            //mainGrid.ToolTip = "";
            //ToolTipService.SetVerticalOffset(mainGrid, int.MaxValue);  // Force off-screen to prevent display
        }

        #endregion

        #region /* PROPERTIES */

        public string Description
        {
            get { return _description; }
        }

        public CodeObjectVM CodeVM
        {
            get { return _codeVM; }
        }

        public bool TextViewEnabled
        {
            get { return _textViewEnabled; }
            set { _textViewEnabled = value; }
        }

        #endregion

        #region /* METHODS */

        protected static readonly GridLength ZeroGridLength = new GridLength(0);
        protected static readonly Thickness ZeroThickness = new Thickness(0);

        /// <summary>
        /// Render the code contained within this editor object.
        /// </summary>
        public void Render(double windowHeight)
        {
            using (new WaitCursor())
            {
                _windowHeight = windowHeight;
                if (_codeVM != null)
                {
                    // Reset statistics
                    Stopwatch stopWatch = new Stopwatch();
                    stopWatch.Start();

                    // Populate types combobox
                    if (_codeVM is CodeUnitVM)
                        PopulateTypesComboBox(((CodeUnitVM)_codeVM).CodeUnit);

                    // Measure and render the code into the panel
                    codePanel.Children.Clear();
                    _renderer = _codeVM.Render(codePanel, _verticalScrollOffset, _verticalScrollOffset + _windowHeight);
                    _renderer.ToolTipContextMenuOpening = codeViewer_ContextMenuOpening;
                    _renderer.CommandBindings = Application.Current.MainWindow.CommandBindings;
                    _fontHeight = CodeRenderer.CodeFontHeight;

                    // Add "end-of-file" marker
                    TextBlock textBlock = new TextBlock
                        {
                            Text = "",
                            Foreground = Brushes.Black,
                            ToolTip = "End of File",
                            FontFamily = CodeRenderer.CodeFontFamily,
                            FontSize = CodeRenderer.CodeFontSize
                        };
                    codePanel.Children.Add(textBlock);

                    if (!CodeRenderer.VirtualizeRendering)
                    {
                        // Log statistics
                        string statistics = "Render '" + _description + "', elapsed time: " + stopWatch.Elapsed.TotalSeconds.ToString("N3");
                        if (_renderer != null)
                        {
                            statistics += ", TextBlocks=" + _renderer.TextBlockCount + ", WrapPanels=" + _renderer.WrapPanelCount
                                          + ", StackPanels=" + _renderer.StackPanelCount + ", Borders=" + _renderer.BorderCount;
                        }
                        Log.WriteLine(statistics);
                    }
                }

                // Render the text view
                RenderTextView();
            }
        }

        /// <summary>
        /// Render the text view of the code.
        /// </summary>
        public void RenderTextView()
        {
            if (_textViewEnabled)
            {
                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();
                textView.Text = (_codeVM != null ? _codeVM.CodeObject.AsText() : null);
                textView.FontFamily = CodeRenderer.CodeFontFamily;
                textView.FontSize = CodeRenderer.CodeFontSize;
                codeBorder.Margin = _codeBorderMargin;
                mainGridSplitter.Visibility = Visibility.Visible;
                mainGrid.ColumnDefinitions[1].Width = _textColumnWidth;
                Log.WriteLine("Text Render '" + _description + "', elapsed time: " + stopWatch.Elapsed.TotalSeconds.ToString("N3"));
            }
            else
            {
                textView.Text = null;
                codeBorder.Margin = ZeroThickness;
                mainGridSplitter.Visibility = Visibility.Collapsed;
                mainGrid.ColumnDefinitions[1].Width = ZeroGridLength;
            }
        }

        /// <summary>
        /// Select the specified code object within the editor (scroll until it's visible if necessary, and highlight it).
        /// </summary>
        public void SelectCodeObject(CodeObject codeObject)
        {
            if (_renderer == null) return;
            _renderer.CloseToolTip();

            // Get the corresponding VM for the code object
            CodeObjectVM codeObjectVM;
            if (_codeObject2VM.TryGetValue(codeObject, out codeObjectVM))
            {
                // Do a layout so that the dimensions are updated
                codeScrollViewer.UpdateLayout();

                // Scroll the VM into view if necessary so it will be rendered
                double newScrollOffset = -1;
                if (codeObjectVM is CodeUnitVM)
                {
                    if (codeScrollViewer.VerticalOffset > 0)
                        newScrollOffset = 0;
                }
                else
                {
                    const double margin = 10;
                    double absoluteY = codeObjectVM.GetAbsoluteY();
                    if (absoluteY < codeScrollViewer.VerticalOffset + margin)
                    {
                        newScrollOffset = absoluteY - margin;
                        if (newScrollOffset < 0)
                            newScrollOffset = 0;
                    }
                    else if (absoluteY > codeScrollViewer.VerticalOffset + codeScrollViewer.ViewportHeight - margin - _fontHeight)
                        newScrollOffset = absoluteY - (codeScrollViewer.ViewportHeight - margin - _fontHeight);
                }
                if (newScrollOffset >= 0)
                {
                    codeScrollViewer.ScrollToVerticalOffset(newScrollOffset);
                    _skipFirstScrollEvent = false;

                    // Process pending events from the scroll so that UI objects are generated before accessing them below
                    WPFUtil.DoEvents();
                }

                // Highlight the primary UI object of the VM with an animation (skip if it's a CodeUnit)
                if (!(codeObjectVM is CodeUnitVM))
                {
                    if (codeObjectVM.FrameworkElement != null)
                    {
                        FrameworkElement frameworkElement = codeObjectVM.GetSelectionElement();

                        // Bring into view (horizontal scrolling might be required)
                        frameworkElement.BringIntoView();

                        // Create a centered scale transform for the element
                        ScaleTransform scaleTransform = new ScaleTransform();
                        frameworkElement.RenderTransform = scaleTransform;
                        frameworkElement.RenderTransformOrigin = new Point(0.5, 0.5);

                        // Create scaling animations, starting at 2X for Y so the layout gives extra room from the edge of the view.
                        // Repeat 2.5 times, so it ends at 1X.  Scale Y more than X, because scaling X too much can send text behind
                        // following text that has a higher Z order.
                        DoubleAnimation animationX = new DoubleAnimation(1.2, 1.0, new Duration(new TimeSpan(0, 0, 0, 0, 200)))
                            { AutoReverse = true, RepeatBehavior = new RepeatBehavior(2.5), FillBehavior = FillBehavior.Stop };
                        DoubleAnimation animationY = new DoubleAnimation(2.0, 1.0, new Duration(new TimeSpan(0, 0, 0, 0, 200)))
                            { AutoReverse = true, RepeatBehavior = new RepeatBehavior(2.5), FillBehavior = FillBehavior.Stop };
                        scaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, animationX);
                        scaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, animationY);
                    }
                    else
                    {
                        // If no UI element was found, it's probably a hidden VM, such as the VarTypeRefVM for a ParameterDeclVM with
                        // an inferred type (the VM is still generated because it's used to determine the color of the parent text), so
                        // recursively call this routine for the parent VM to display that instead.
                        SelectCodeObject(codeObject.Parent);
                    }
                }
            }
        }

        public void ResetToolTipTimer()
        {
            _renderer.ResetToolTipTimer();
        }

        public void CloseToolTip()
        {
            _renderer.CloseToolTip();
        }

        #endregion

        #region /* EVENTS */

        protected void codeViewer_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            bool isToolTipContextMenu = sender is Popup;
            if (!isToolTipContextMenu)
                _renderer.CloseToolTip();

            ContextMenu contextMenu = new ContextMenu();

            // Add context specific menu items here
            object source = e.Source;
            if (source is Run)
                source = ((Run)source).Parent;
            FrameworkElement frameworkElement = source as FrameworkElement;
            if (frameworkElement != null)
            {
                CodeObject target = GetReferenceTarget(frameworkElement);
                if (target != null)
                {
                    object targetObject = (target is SymbolicRef ? ((SymbolicRef)target).Reference : target);
                    if (targetObject is CodeObject && !(targetObject is Namespace) && (target is SymbolicRef || isToolTipContextMenu))
                        WPFUtil.AddMenuItemCommand(contextMenu, GoToDeclarationCommand, frameworkElement);
                }
            }

            // Add general menu items:
            if (!isToolTipContextMenu)
            {
                WPFUtil.AddMenuItemCommand(contextMenu, ApplicationCommands.Close, this);
                WPFUtil.AddMenuItemCommand(contextMenu, ApplicationCommands.Save, this);
                WPFUtil.AddSeparator(contextMenu);
                WPFUtil.AddCheckableMenuItemCommand(contextMenu, TextViewCommand, this, _textViewEnabled);

                MenuItem optionsMenu = new MenuItem { Header = "Display Options" };
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, CodeRenderer.ShowBordersCommand, this, CodeRenderer.ShowBorders);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, CodeRenderer.ShowBackgroundColorsCommand, this, CodeRenderer.ShowBackgroundColors);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, CodeRenderer.UseShadingCommand, this, CodeRenderer.UseShading);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, CodeRenderer.HalfHeightBlankLinesCommand, this, CodeRenderer.HalfHeightBlankLines);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, BlockVM.TinyBracesCommand, this, BlockVM.TinyBraces);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, BlockVM.HideBracesCommand, this, BlockVM.HideBraces);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, StatementVM.HideTerminatorsCommand, this, StatementVM.HideTerminators);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, StatementVM.HideStatementParensCommand, this, StatementVM.HideStatementParens);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, MethodDeclBaseVM.HideMethodParensCommand, this, MethodDeclBaseVM.HideMethodParens);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, NewObjectVM.HideEmptyParensCommand, this, NewObjectVM.HideEmptyParens);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, WhileVM.DisplayAsDoIfNullConditionCommand, this, WhileVM.DisplayAsDoIfNullCondition);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, OperatorVM.AlternativeDisplayCommand, this, OperatorVM.UseAlternativeDisplay);
                WPFUtil.AddCheckableMenuItemCommand(optionsMenu, CodeRenderer.MaximizeBordersCommand, this, CodeRenderer.MaximizeBorders);
                {
                    MenuItem commentsMenu = new MenuItem { Header = "Comments" };
                    WPFUtil.AddCheckableMenuItemCommand(commentsMenu, CommentBaseVM.HideDelimitersCommand, this, CommentBaseVM.HideDelimiters);
                    WPFUtil.AddCheckableMenuItemCommand(commentsMenu, CommentBaseVM.HideAllCommand, this, CommentBaseVM.HideAll);
                    WPFUtil.AddCheckableMenuItemCommand(commentsMenu, CommentVM.UseProportionalFontCommand, this, CommentVM.UseProportionalFont);
                    WPFUtil.AddCheckableMenuItemCommand(commentsMenu, DocCommentVM.UseProportionalFontCommand, this, DocCommentVM.UseProportionalFont);
                    WPFUtil.AddCheckableMenuItemCommand(commentsMenu, DocCommentVM.AlternativeFormatCommand, this, DocCommentVM.UseAlternativeFormat);
                    optionsMenu.Items.Add(commentsMenu);

                    MenuItem literalsMenu = new MenuItem { Header = "Literals" };
                    WPFUtil.AddCheckableMenuItemCommand(literalsMenu, LiteralVM.CommasInNumericsCommand, this, LiteralVM.CommasInNumerics);
                    WPFUtil.AddCheckableMenuItemCommand(literalsMenu, LiteralVM.NoEscapesCommand, this, LiteralVM.NoEscapes);
                    WPFUtil.AddCheckableMenuItemCommand(literalsMenu, LiteralVM.VisibleSpacesCommand, this, LiteralVM.VisibleSpaces);
                    WPFUtil.AddCheckableMenuItemCommand(literalsMenu, LiteralVM.HideQuotesCommand, this, LiteralVM.HideQuotes);
                    optionsMenu.Items.Add(literalsMenu);
                }
                contextMenu.Items.Add(optionsMenu);
            }

            contextMenu.IsOpen = contextMenu.HasItems;
            ((FrameworkElement)sender).ContextMenu = contextMenu;
            e.Handled = true;
        }

        protected static CodeObject GetReferenceTarget(FrameworkElement frameworkElement)
        {
            // Get the object associated with the FrameworkElement, handling hidden refs
            CodeObjectVM targetVM = frameworkElement.Tag as CodeObjectVM;
            if (targetVM != null)
            {
                CodeObject codeObject = targetVM.CodeObject;
                if (!(codeObject is INamedCodeObject || codeObject is SymbolicRef))
                    codeObject = codeObject.HiddenRef;
                return codeObject;
            }
            return null;
        }

        protected void textView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            ContextMenu contextMenu = new ContextMenu { IsOpen = true };

            // Add context specific menu items here

            // Add general menu items
            WPFUtil.AddMenuItemCommand(contextMenu, ApplicationCommands.Copy, this);
            WPFUtil.AddSeparator(contextMenu);
            WPFUtil.AddCheckableMenuItemCommand(contextMenu, TextViewCommand, this, _textViewEnabled);

            ((FrameworkElement)sender).ContextMenu = contextMenu;
            e.Handled = true;
        }

        protected void codeViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            _renderer.CloseToolTip();
            _windowHeight = e.ViewportHeight;
            _verticalScrollOffset = e.VerticalOffset;

            // Skip the first scroll event, since all necessary rendering will have already been done.
            // Otherwise, render any newly visible objects (and free those that are no longer visible).
            if (CodeRenderer.VirtualizeRendering && !_skipFirstScrollEvent)
            {
                _renderer.StartY = _verticalScrollOffset;
                _renderer.EndY = _verticalScrollOffset + _windowHeight;
                try
                {
                    _codeVM.RenderVisible(_renderer, CodeObjectVM.RenderFlags.None);
                }
                catch { }
            }

            _skipFirstScrollEvent = false;
            e.Handled = true;
        }

        private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (!IsVisible)
                _renderer.CloseToolTip();
        }

        #endregion

        #region /* TYPES/MEMBERS COMBOBOXES */

        protected void PopulateTypesComboBox(CodeUnit codeUnit)
        {
            List<TypeDeclWrapper> typeDeclWrappers = new List<TypeDeclWrapper>();
            foreach (TypeDecl typeDecl in codeUnit.GetTypeDecls(true, true))
                typeDeclWrappers.Add(new TypeDeclWrapper(typeDecl));
            typeDeclWrappers.Sort();
            typesComboBox.ItemsSource = typeDeclWrappers;
            if (typeDeclWrappers.Count == 1)
                typesComboBox.SelectedIndex = 0;
        }

        protected void PopulateMembersComboBox(TypeDeclWrapper typeDeclWrapper)
        {
            List<NamedCodeObjectWrapper> namedCodeObjectWrappers = new List<NamedCodeObjectWrapper>();
            foreach (INamedCodeObject member in typeDeclWrapper.TypeDecl.GetMemberDecls(true))
                namedCodeObjectWrappers.Add(new NamedCodeObjectWrapper(member, typeDeclWrapper.Name));
            namedCodeObjectWrappers.Sort();
            membersComboBox.ItemsSource = namedCodeObjectWrappers;
        }

        private void typesComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            TypeDeclWrapper typeDeclWrapper = typesComboBox.SelectedItem as TypeDeclWrapper;
            if (typeDeclWrapper != null)
            {
                SelectCodeObject(typeDeclWrapper.TypeDecl);
                PopulateMembersComboBox(typeDeclWrapper);
            }
        }

        private void membersComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            NamedCodeObjectWrapper namedCodeObjectWrapper = membersComboBox.SelectedItem as NamedCodeObjectWrapper;
            if (namedCodeObjectWrapper != null)
                SelectCodeObject(namedCodeObjectWrapper.NamedCodeObject as CodeObject);
        }

        protected class TypeDeclWrapper : IComparable<TypeDeclWrapper>
        {
            public TypeDecl TypeDecl;
            public string Name;
            public TypeDeclWrapper(TypeDecl typeDecl)
            {
                TypeDecl = typeDecl;
                Name = typeDecl.GetFullName(true);
            }
            public int CompareTo(TypeDeclWrapper other) { return string.Compare(Name, other.Name); }
            public override string ToString() { return Name; }
        }

        protected class NamedCodeObjectWrapper : IComparable<NamedCodeObjectWrapper>
        {
            public INamedCodeObject NamedCodeObject;
            public string Name;
            public NamedCodeObjectWrapper(INamedCodeObject namedCodeObject, string parentTypeName)
            {
                NamedCodeObject = namedCodeObject;
                Name = namedCodeObject.GetFullName(true).Substring(parentTypeName.Length + 1);
            }
            public int CompareTo(NamedCodeObjectWrapper other) { return string.Compare(Name, other.Name); }
            public override string ToString() { return Name; }
        }

        #endregion

        #region /* COMMANDS */

        public static readonly RoutedCommand GoToDeclarationCommand = new RoutedCommand("Go To Declaration", typeof(CodeWindow));
        public static readonly RoutedCommand TextViewCommand = new RoutedCommand("Text View", typeof(CodeWindow));

        public void BindCommands(Window window)
        {
            WPFUtil.AddCommandBinding(window, GoToDeclarationCommand, goToDeclaration_Executed);
            WPFUtil.AddCommandBinding(window, TextViewCommand, textView_Executed);
        }

        protected static void goToDeclaration_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
            FrameworkElement frameworkElement = e.OriginalSource as FrameworkElement;
            if (frameworkElement != null)
            {
                // Get the target object, and navigate to it (or the referenced object if it's a SymbolicRef)
                CodeObject targetCodeObject = GetReferenceTarget(frameworkElement);
                CodeObject codeObject = (targetCodeObject is SymbolicRef ? ((SymbolicRef)targetCodeObject).Reference as CodeObject : targetCodeObject);
                mainWindow.SelectCodeObject(codeObject);
            }
        }

        protected static void textView_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CodeWindow codeWindow = (CodeWindow)e.Source;
            codeWindow._textViewEnabled = !codeWindow._textViewEnabled;
            codeWindow.RenderTextView();
            e.Handled = true;
        }

        #endregion
    }
}

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 Common Development and Distribution License (CDDL)

Share

About the Author

KenBeckett
Software Developer (Senior)
United States United States
I've been writing software since the late 70's, currently focusing mainly on C#.NET. I also like to travel around the world, and I own a Chocolate Factory (sadly, none of my employees are oompa loompas).

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 2 Dec 2012
Article Copyright 2012 by KenBeckett
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid