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

MPP Viewer

Rate me:
Please Sign up or sign in to vote.
4.75/5 (13 votes)
15 Jun 2011CPOL3 min read 104K   4.1K   41  
MPP Viewer is a simple viewer for Microsoft Project files. I works well with 2000/2003/2007 file formats.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Diagnostics;
using System.Reflection;

namespace Ricciolo.Controls
{
    public class TreeGridViewRowPresenter : GridViewRowPresenter
    {

        public static DependencyProperty FirstColumnIndentProperty = DependencyProperty.Register("FirstColumnIndent", typeof(Double), typeof(TreeGridViewRowPresenter), new PropertyMetadata(0d));
        public static DependencyProperty ExpanderProperty = DependencyProperty.Register("Expander", typeof(UIElement), typeof(TreeGridViewRowPresenter), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnExpanderChanged)));

        private UIElementCollection childs;

        private static PropertyInfo ActualIndexProperty = typeof(GridViewColumn).GetProperty("ActualIndex", BindingFlags.NonPublic | BindingFlags.Instance);
        private static PropertyInfo DesiredWidthProperty = typeof(GridViewColumn).GetProperty("DesiredWidth", BindingFlags.NonPublic | BindingFlags.Instance);

        public TreeGridViewRowPresenter()
        {
            childs = new UIElementCollection(this, this);
        }

        public Double FirstColumnIndent
        {
            get { return (Double)this.GetValue(FirstColumnIndentProperty); }
            set { this.SetValue(FirstColumnIndentProperty, value); }
        }

        public UIElement Expander
        {
            get { return (UIElement)this.GetValue(ExpanderProperty); }
            set { this.SetValue(ExpanderProperty, value); }
        }

        protected override Size ArrangeOverride(Size arrangeSize)
        {
            Size s = base.ArrangeOverride(arrangeSize);

            if (this.Columns == null || this.Columns.Count == 0) return s;
            UIElement expander = this.Expander;

            double current = 0;
            double max = arrangeSize.Width;
            for (int x = 0; x < this.Columns.Count; x++)
            {
                try
                {
                    GridViewColumn column = this.Columns[x];
                    // Actual index needed for column reorder
                    UIElement uiColumn = (UIElement)base.GetVisualChild((int)ActualIndexProperty.GetValue(column, null));

                    // Compute column width
                    double w = Math.Min(max, (Double.IsNaN(column.Width)) ? (double)DesiredWidthProperty.GetValue(column, null) : column.Width);

                    // First column indent
                    if (x == 0 && expander != null)
                    {
                        double indent = FirstColumnIndent + expander.DesiredSize.Width;
                        uiColumn.Arrange(new Rect(current + indent, 0, w - indent, arrangeSize.Height));
                    }
                    else
                        uiColumn.Arrange(new Rect(current, 0, w, arrangeSize.Height));
                    max -= w;
                    current += w;

                }
                catch
                {
                    continue;
                }
            }

            // Show expander
            if (expander != null)
            {
                expander.Arrange(new Rect(this.FirstColumnIndent, 0, expander.DesiredSize.Width, expander.DesiredSize.Height));
            }

            return s;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            Size s = base.MeasureOverride(constraint);

            // Measure expander
            UIElement expander = this.Expander;
            if (expander != null)
            {
                // Compute max measure
                expander.Measure(constraint);
                s.Width = Math.Max(s.Width, expander.DesiredSize.Width);
                s.Height = Math.Max(s.Height, expander.DesiredSize.Height);
            }

            return s;
        }

        protected override System.Windows.Media.Visual GetVisualChild(int index)
        {
            // Last element is always the expander
            // called by render engine
            if (index < base.VisualChildrenCount)
                return base.GetVisualChild(index);
            else
                return this.Expander;
        }

        protected override int VisualChildrenCount
        {
            get
            {
                // Last element is always the expander
                if (this.Expander != null)
                    return base.VisualChildrenCount + 1;
                else
                    return base.VisualChildrenCount;
            }
        }

        private static void OnExpanderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Use a second UIElementCollection so base methods work as original
            TreeGridViewRowPresenter p = (TreeGridViewRowPresenter)d;

            p.childs.Remove(e.OldValue as UIElement);
            p.childs.Add((UIElement)e.NewValue);
        }

    }
}

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
Architect
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions