Click here to Skip to main content
15,891,976 members
Articles / Desktop Programming / WPF

A (Mostly) Declarative Framework for Building Simple WPF-based Wizards

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
7 Mar 2011LGPL322 min read 19.3K   229   15  
A declarative framework for building WPF wizards.
/*
* Olbert.Utilities.Misc
* miscellaneous items for simplifying .NET programming
* Copyright (C) 2011  Mark A. Olbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published 
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections.ObjectModel;
using System.Collections;
using System.Text.RegularExpressions;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace Olbert.Utilities
{
    /// <summary>
    /// a class, derived from ResourceDirectory, which defines a virtual ResourceDirectory representing
    /// a zip file archive within an SourceAssembly.
    /// </summary>
    public class ResourceZipFile : ResourceDirectory
    {
        private ZipInputStream zipStream;

        /// <summary>
        /// Initializes an instance and assigns it to a ResourceDirectory object. Parses the contents
        /// of the zip file resource in the SourceAssembly and loads the resulting hierarchy into the
        /// Children property.
        /// </summary>
        /// <param name="parent">the ResourceDirectory to which the object belongs</param>
        /// <param name="name">the name of the ResourceDirectory, which must be unique within the
        /// owning ResourceDirectory</param>
        public ResourceZipFile( ResourceDirectory parent, string name )
            : base(parent, name)
        {
            zipStream = new ZipInputStream(this.Stream);

            ParseZipFile();
        }

        /// <summary>
        /// Initializes an instance and assigns it to a ResourceDirectory object.
        /// <para>This constructor is intended to be called internally when the zip file resource is
        /// parsed as part of the process creating the hierarchy of virtual ResourceFiles contained
        /// within the zip archive.</para>
        /// </summary>
        /// <param name="parent">the ResourceDirectory to which the object belongs</param>
        /// <param name="name">the name of the ResourceDirectory, which must be unique within the
        /// owning ResourceDirectory</param>
        /// <param name="zipStream">the ZipInputStream to the underlying zip file resource</param>
        public ResourceZipFile( ResourceDirectory parent, string name, ZipInputStream zipStream )
            : base(parent, name)
        {
            this.zipStream = zipStream;
        }

        /// <summary>
        /// Walks the file hierarchy in the zip file and creates a ResourceDirectory/ResourceFile hierarchy
        /// of the zip file contents. Creates ResourceSqlFile objects for archived files which have an
        /// 'sql' extension (case-insensitive). All other archived files are created as plain ResourceFile
        /// objects.
        /// </summary>
        protected void ParseZipFile()
        {
            MemoryStream curEntryStream;
            byte[] buffer = new byte[4096];
            int bytesRead = 0;

            ZipEntry curEntry = zipStream.GetNextEntry();

            Stack<ResourceDirectory> dirStack = new Stack<ResourceDirectory>();

            while( curEntry != null )
            {
                if( curEntry.IsDirectory )
                {
                    // it's a directory, so recurse into it and then add it to our children
                    ResourceZipFile subDir = new ResourceZipFile(this, curEntry.Name, zipStream);

                    Children.Add(subDir);
                }
                else
                {
                    // it's a plain old file, so extract its contents and add it to our children
                    curEntryStream = new MemoryStream();

                    do
                    {
                        bytesRead = zipStream.Read(buffer, 0, buffer.Length);

                        if( bytesRead > 0 ) curEntryStream.Write(buffer, 0, bytesRead);
                    } while( bytesRead > 0 );

                    // add the extracted file to the Children collection, checking to see
                    // if the ResourceFile that got created is actually a ResourceDirectory (which it
                    // will be if, for example, the extracted file is a zip file) because in that case we want
                    // to add the >>children<< of the newly-created object to the Children collection
                    ResourceFile newFile = FileTypes.Create(this, curEntry.Name, curEntryStream);
                    ResourceDirectory newDir = newFile as ResourceDirectory;

                    if( newDir == null ) Children.Add(newFile);
                    else Children.AddRange(newDir.Children);
                }
            }
        }
    }
}

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 GNU Lesser General Public License (LGPLv3)


Written By
Jump for Joy Software
United States United States
Some people like to do crossword puzzles to hone their problem-solving skills. Me, I like to write software for the same reason.

A few years back I passed my 50th anniversary of programming. I believe that means it's officially more than a hobby or pastime. In fact, it may qualify as an addiction Smile | :) .

I mostly work in C# and Windows. But I also play around with Linux (mostly Debian on Raspberry Pis) and Python.

Comments and Discussions