Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Resolving Symbolic References in a CodeDOM (Part 7)

, 2 Dec 2012
Resolving symbolic references in a CodeDOM.
Nova.0.6.exe.zip
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
// The Nova Project by Ken Beckett.
// 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.Runtime.Remoting.Messaging;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

namespace Nova.UI
{
    /// <summary>
    /// The style of rendered text.
    /// </summary>
    [Flags]
    public enum TextStyle { Normal = 0, Bold = 1, Italic = 2, Proportional = 4, NoCache = 8 }

    /// <summary>
    /// Static helper methods for various WPF classes.
    /// </summary>
    public static class WPFUtil
    {
        #region /* STATIC HELPER METHODS */

        /// <summary>
        /// Process all pending UI events.
        /// </summary>
        public static void DoEvents()
        {
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
        }

        /// <summary>
        /// Invoke the specified action on a worker thread, then invoke the completed action on the main thread
        /// when the background operation is complete.
        /// </summary>
        public static void ExecuteActionOnThread<T>(DispatcherObject dispatcherObject, Action<T> action, T actionParameter, Action completedAction)
        {
            action.BeginInvoke(actionParameter, ExecuteActionOnThreadCallback<T>, new AsyncState(dispatcherObject, completedAction));
        }

        private static void ExecuteActionOnThreadCallback<T>(IAsyncResult result)
        {
            // Clean up the asynchronous operation, and invoke the completion action on the main UI thread
            ((Action<T>)((AsyncResult)result).AsyncDelegate).EndInvoke(result);
            AsyncState asyncState = (AsyncState)result.AsyncState;
            asyncState.DispatcherObject.Dispatcher.Invoke(asyncState.Action);
        }

        private class AsyncState
        {
            public readonly DispatcherObject DispatcherObject;
            public readonly Action Action;
            public AsyncState(DispatcherObject dispatcherObject, Action action)
            {
                DispatcherObject = dispatcherObject;
                Action = action;
            }
        }

        /// <summary>
        /// Invoke the specified action on a worker thread, then invoke the completed action on the main thread
        /// when the background operation is complete.
        /// </summary>
        public static void ExecuteActionOnThread<T, U>(DispatcherObject dispatcherObject, Action<T> action, T actionParameter, Action<U> completedAction, U completedParameter)
        {
            action.BeginInvoke(actionParameter, ExecuteActionOnThreadCallback<T, U>, new AsyncState<U>(dispatcherObject, completedAction, completedParameter));
        }

        private static void ExecuteActionOnThreadCallback<T, U>(IAsyncResult result)
        {
            // Clean up the asynchronous operation, and invoke the completion action on the main UI thread
            ((Action<T>)((AsyncResult)result).AsyncDelegate).EndInvoke(result);
            AsyncState<U> asyncState = (AsyncState<U>)result.AsyncState;
            asyncState.DispatcherObject.Dispatcher.Invoke(asyncState.Action, asyncState.Parameter);
        }

        private class AsyncState<U>
        {
            public readonly DispatcherObject DispatcherObject;
            public readonly Action<U> Action;
            public readonly U Parameter;
            public AsyncState(DispatcherObject dispatcherObject, Action<U> action, U parameter)
            {
                DispatcherObject = dispatcherObject;
                Action = action;
                Parameter = parameter;
            }
        }

        /// <summary>
        /// Add a MenuItem to a Menu or ContextMenu.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        /// <param name="header">The description (header) of the MenuItem to be added.</param>
        /// <returns>The MenuItem added.</returns>
        public static MenuItem AddMenuItem(ItemsControl menu, string header)
        {
            MenuItem item = new MenuItem { Header = header };
            menu.Items.Add(item);
            return item;
        }

        /// <summary>
        /// Add a MenuItem to a Menu or ContextMenu.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        /// <param name="header">The description (header) of the MenuItem to be added.</param>
        /// <param name="clickHandler">The click event handler.</param>
        /// <param name="enabled">True if the menu item is enabled.</param>
        /// <returns>The MenuItem added.</returns>
        public static MenuItem AddMenuItem(ItemsControl menu, string header, RoutedEventHandler clickHandler, bool enabled)
        {
            MenuItem item = AddMenuItem(menu, header);
            item.IsEnabled = enabled;
            item.Click += clickHandler;
            return item;
        }

        /// <summary>
        /// Add a checkable MenuItem to a Menu or ContextMenu.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        /// <param name="header">The description (header) of the checkable MenuItem to be added.</param>
        /// <returns>The MenuItem added.</returns>
        public static MenuItem AddCheckableMenuItem(ItemsControl menu, string header)
        {
            MenuItem item = AddMenuItem(menu, header);
            item.IsCheckable = true;
            return item;
        }

        /// <summary>
        /// Add a command to a Menu or ContextMenu.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        /// <param name="command">The command to be added.</param>
        /// <param name="target">The target of the command.</param>
        /// <returns>The MenuItem added.</returns>
        public static MenuItem AddMenuItemCommand(ItemsControl menu, RoutedCommand command, IInputElement target)
        {
            MenuItem item = new MenuItem { Header = command.Name, Command = command, CommandTarget = target };
            menu.Items.Add(item);
            return item;
        }

        /// <summary>
        /// Add a command to a Menu or ContextMenu with a '...' button.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        /// <param name="header">The description (header) of the MenuItem to be added.</param>
        /// <param name="command">The command to be added.</param>
        /// <param name="target">The target of the command.</param>
        /// <returns>The MenuItem added.</returns>
        public static MenuItem AddMenuItemCommandWithButton(ItemsControl menu, string header, RoutedCommand command, IInputElement target)
        {
            WrapPanel wrapPanel = new WrapPanel();
            TextBlock textBlock = new TextBlock { Text = header + "   " };
            wrapPanel.Children.Add(textBlock);
            Button button = new Button { Content = " . . . ", Height = 18, Command = command, CommandTarget = target, CommandParameter = "..." };
            wrapPanel.Children.Add(button);
            MenuItem item = new MenuItem { Header = wrapPanel, Command = command, CommandTarget = target };
            menu.Items.Add(item);
            return item;
        }

        /// <summary>
        /// Add a checkable command to a Menu or ContextMenu.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        /// <param name="command">The command to be added.</param>
        /// <param name="target">The target of the command.</param>
        /// <param name="isChecked">The current checked state.</param>
        /// <returns>The MenuItem added.</returns>
        public static MenuItem AddCheckableMenuItemCommand(ItemsControl menu, RoutedCommand command, IInputElement target, bool isChecked)
        {
            MenuItem item = AddMenuItemCommand(menu, command, target);
            item.IsCheckable = true;
            item.IsChecked = isChecked;
            return item;
        }

        /// <summary>
        /// Add a Separator to a Menu or ContextMenu.
        /// </summary>
        /// <param name="menu">The Menu or ContextMenu.</param>
        public static void AddSeparator(ItemsControl menu)
        {
            menu.Items.Add(new Separator());
        }

        /// <summary>
        /// Add a command binding to a Window.
        /// </summary>
        /// <param name="window">The Window.</param>
        /// <param name="command">The command to be bound.</param>
        /// <param name="executed">The executed event handler for the command.</param>
        public static void AddCommandBinding(Window window, ICommand command, ExecutedRoutedEventHandler executed)
        {
            window.CommandBindings.Add(new CommandBinding(command, executed));
        }

        /// <summary>
        /// Add a command binding to a Window.
        /// </summary>
        /// <param name="window">The Window.</param>
        /// <param name="command">The command to be bound.</param>
        /// <param name="executed">The executed event handler for the command.</param>
        /// <param name="canExecute">The can-execute event handler for the command.</param>
        public static void AddCommandBinding(Window window, ICommand command, ExecutedRoutedEventHandler executed, CanExecuteRoutedEventHandler canExecute)
        {
            window.CommandBindings.Add(new CommandBinding(command, executed, canExecute));
        }

        /// <summary>
        /// Scroll the ListView so that the last item is visible.
        /// </summary>
        public static void ShowLastItem(ListView listView)
        {
            // Setup a call back, so we can scroll the item into view after the UI has updated
            listView.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action<ListView>(ShowLastListViewItem), listView);
        }

        private static void ShowLastListViewItem(ListView listView)
        {
            if (listView.Items.Count > 0)
                listView.ScrollIntoView(listView.Items[listView.Items.Count - 1]);
        }

        /// <summary>
        /// Scroll the control to the top, so the ScrollViewer doesn't retain its state.
        /// </summary>
        public static void ScrollToTop(ItemsControl itemsControl)
        {
            // Scroll the stupid ScrollViewer to the top so it doesn't retain its state if the
            // collection is cleared or otherwise updated (WPF bug!?).
            // Note that this code is dependent upon the specific control template in use!
            itemsControl.UpdateLayout();
            if (VisualTreeHelper.GetChildrenCount(itemsControl) > 0)
            {
                DependencyObject outer = VisualTreeHelper.GetChild(itemsControl, 0);
                if (outer != null)  // Might be a Border or a ListBoxChrome
                {
                    ScrollViewer scrollViewer = VisualTreeHelper.GetChild(outer, 0) as ScrollViewer;
                    if (scrollViewer != null)
                        scrollViewer.ScrollToTop();
                }
            }
        }

        /// <summary>
        /// Clear the control's items, also resetting the ScrollViewer so it doesn't retain its state.
        /// </summary>
        public static void Clear(ItemsControl itemsControl)
        {
            ScrollToTop(itemsControl);
            itemsControl.Items.Clear();
        }

        #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).

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 2 Dec 2012
Article Copyright 2012 by KenBeckett
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid