Click here to Skip to main content
15,896,278 members
Articles / Programming Languages / C#

CodeDOM Classes for Solution and Project Files (Part 5)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (12 votes)
30 Nov 2012CDDL7 min read 30.1K   1.2K   18  
CodeDOM objects for VS Solution and Project files.
// 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)


Written By
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).

Comments and Discussions