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

Wrap Panel Virtualization

Rate me:
Please Sign up or sign in to vote.
4.95/5 (18 votes)
2 Jan 2012CPOL2 min read 53.4K   5.6K   41  
WrapPanel doesn't support virtualization. But we can improve the performance by simulating virtualization.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Dokan;
using MediaAssistant.DAL;
using MediaAssistant.DAL.Constants;

namespace MediaFS
{
    class MediaFSOperations : DokanOperations
    {
        private int count_;
        private Dictionary<string, string> FilePathMap { get; set; }
        private Dictionary<string, LibraryItem> LibraryItemPathMap { get; set; }
        public MediaFSOperations()
        {
            count_ = -1;
            FilePathMap=new Dictionary<string, string>();
            LibraryItemPathMap=new Dictionary<string, LibraryItem>();
        }
        public int Cleanup(string filename, DokanFileInfo info)
        {
            return 0;
        }

        public int CloseFile(string filename, DokanFileInfo info)
        {
            return 0;
        }

        public int CreateDirectory(string filename, DokanFileInfo info)
        {
            return -1;
        }

        public int CreateFile(string filename, FileAccess access, FileShare share, FileMode mode, FileOptions options, DokanFileInfo info)
        {
            info.Context = count_++;
            var path = GetPath(filename);
            if (string.IsNullOrEmpty(path))
                return -1;
            if (File.Exists(path))
            {
                return 0;
            }
            info.IsDirectory = true;
            return 0;
        }

        public int DeleteDirectory(string filename, DokanFileInfo info)
        {
            return -1;
        }

        public int DeleteFile(string filename, DokanFileInfo info)
        {
            return -1;
        }

        public int FlushFileBuffers(string filename, DokanFileInfo info)
        {
            return -1;
        }

        public int FindFiles(string filename, ArrayList files, DokanFileInfo info)
        {
            Debug.WriteLine(string.Format("FindFiles {0}", filename));
            lock (DatabaseManager.LockObject)
            {
                if (filename == "\\")
                {
                    foreach (var item in DatabaseManager.Instance.GetRootLibraryItems())
                    {
                        AddFileInfo(item.Title, FileAttributes.Directory, files);
                    }
                    return 0;
                }
                var libraryItem = GetLibraryItem(filename);
                AddFileInfo(libraryItem, files);
            }
            return 0;
        }

        private static void AddFileInfo(LibraryItem item, ArrayList files)
        {
            lock (DatabaseManager.LockObject)
            {
                foreach (var libraryItem in item.Children)
                {
                    AddFileInfo(libraryItem.Title, FileAttributes.Directory, files);
                }
                AddMovieFiles(files, item.Movies);
                foreach (var music in item.Musics.Where(m => string.IsNullOrWhiteSpace(m.FullPath) == false))
                {
                    AddFileInfo(music.FileName, FileAttributes.Normal, files);
                }
                var SelectedProfile = MediaFSManager.Instance.SelectedProfile;
                switch (item.Type)
                {
                    case LibraryItemType.ProcessingLibrary:
                        AddMovieFiles(files, DatabaseManager.Instance.UpdateProcessingMovies());
                        break;
                    case LibraryItemType.FailedLibrary:
                        AddMovieFiles(files, DatabaseManager.Instance.GetFailedMovies());
                        break;
                    case LibraryItemType.UnreadMovieLibrary:
                        if (SelectedProfile != null)
                        {
                            AddMovieFiles(files, DatabaseManager.Instance.GetNewMovies(SelectedProfile));
                        }
                        break;
                    case LibraryItemType.WatchListLibrary:
                        if (SelectedProfile != null)
                        {
                            AddMovieFiles(files, DatabaseManager.Instance.GetWatchedMovies(SelectedProfile));
                        }
                        break;
                    case LibraryItemType.WishListLibrary:
                        if (SelectedProfile != null)
                        {
                            AddMovieFiles(files, DatabaseManager.Instance.GetWishListMovie(SelectedProfile));
                        }
                        break;
                    case LibraryItemType.StaredMovieLibrary:
                        if (SelectedProfile != null)
                        {
                            AddMovieFiles(files, DatabaseManager.Instance.GetStarMovies(SelectedProfile));
                        }
                        break;
                    case LibraryItemType.RecommendedMovieLibrary:
                        if (SelectedProfile != null)
                        {
                            AddMovieFiles(files, DatabaseManager.Instance.GetStarMovies(SelectedProfile));
                        }
                        break;
                    case LibraryItemType.RecentlyPlayedMovieLibrary:
                        if (SelectedProfile != null)
                        {
                            AddMovieFiles(files, DatabaseManager.Instance.GetRecentlyPlayedMovies(SelectedProfile));
                        }
                        break;
                }
            }
        }

        private static void AddMovieFiles(ArrayList files, IEnumerable<Movie> movies)
        {
            foreach (var movie in movies.Where(m => string.IsNullOrWhiteSpace(m.FullPath) == false))
            {
                AddFileInfo(movie.FileName, FileAttributes.Normal, files);
            }
        }

        private static void AddFileInfo(string fileName, FileAttributes fileAttributes, ArrayList files)
        {
            var finfo = new FileInformation
            {
                FileName = fileName,
                Attributes = fileAttributes,
                LastAccessTime = DateTime.Now,
                LastWriteTime = DateTime.Now,
                CreationTime = DateTime.Now
            };
            files.Add(finfo);
        }

        private LibraryItem GetLibraryItem(string filename)
        {
            if(LibraryItemPathMap.ContainsKey(filename))
            {
                return LibraryItemPathMap[filename];
            }
            var tokens = filename.Split("\\".ToCharArray()).Where(t => string.IsNullOrWhiteSpace(t) == false);
            var items = DatabaseManager.Instance.GetRootLibraryItems();
            var item = items.FirstOrDefault();
            foreach (var token in tokens)
            {
                string title = token;
                var temp = items.FirstOrDefault(o => o.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase));
                if (temp == null)
                    break;
                item = temp;
                items = item.Children;
            }
            if(item!=null)
            {
                LibraryItemPathMap.Add(filename,item);
            }
            return item;
        }


        public int GetFileInformation(string filename, FileInformation fileinfo, DokanFileInfo info)
        {
            if (filename == "\\")
            {
                fileinfo.Attributes = FileAttributes.Directory;
                fileinfo.LastAccessTime = DateTime.Now;
                fileinfo.LastWriteTime = DateTime.Now;
                fileinfo.CreationTime = DateTime.Now;
                return 0;
            }
            var path = GetPath(filename);
            if(string.IsNullOrEmpty(path)==false)
            {
                var actualFileInfo = new FileInfo(path);
                fileinfo.Attributes = actualFileInfo.Attributes;
                fileinfo.LastAccessTime = actualFileInfo.LastAccessTime;
                fileinfo.LastWriteTime = actualFileInfo.LastWriteTime;
                fileinfo.CreationTime = actualFileInfo.CreationTime;
                fileinfo.Length = actualFileInfo.Length;
                fileinfo.FileName = actualFileInfo.Name;
                return 0;
            }
            if(path==filename)
            {
                fileinfo.Attributes = FileAttributes.Directory;
                fileinfo.LastAccessTime = DateTime.Now;
                fileinfo.LastWriteTime = DateTime.Now;
                fileinfo.CreationTime = DateTime.Now;
                return 0;
            }
            return -1;
        }

        public int LockFile(string filename, long offset, long length, DokanFileInfo info)
        {
            return 0;
        }

        public int MoveFile(string filename, string newname, bool replace, DokanFileInfo info)
        {
            return -1;
        }

        public int OpenDirectory(string filename, DokanFileInfo info)
        {
            return 0;
        }

        public int ReadFile(string filename, byte[] buffer, ref uint readBytes, long offset, DokanFileInfo info)
        {
            try
            {
                var path = GetPath(filename);
                if (string.IsNullOrEmpty(path))
                    return -1;
                var fs = File.OpenRead(path);
                fs.Seek(offset, SeekOrigin.Begin);
                readBytes = (uint)fs.Read(buffer, 0, buffer.Length);
                return 0;
            }
            catch (Exception)
            {
                return -1;
            }
        }

        private string GetPath(string filename)
        {
            if(FilePathMap.ContainsKey(filename)==false)
            {
                lock (DatabaseManager.LockObject)
                {
                    var fileInfo = new FileInfo(filename);
                    var libraryItem = GetLibraryItem(filename);
                    if (Utility.IsMusicFile(filename))
                    {
                        var music = libraryItem.Musics.FirstOrDefault(m => m.FileName.Equals(fileInfo.Name, StringComparison.InvariantCultureIgnoreCase));
                        FilePathMap.Add(filename,music.FullPath);
                    }
                    else if (Utility.IsMovieFile(filename))
                    {
                        var movie = libraryItem.Movies.FirstOrDefault(m => m.FileName.Equals(fileInfo.Name, StringComparison.InvariantCultureIgnoreCase));
                        FilePathMap.Add(filename, movie.FullPath);
                    }
                    else if(libraryItem!=null)
                        FilePathMap.Add(filename, filename);
                    else
                    {
                        FilePathMap.Add(filename, string.Empty);
                    }
                }    
            }
            return FilePathMap[filename];
        }

        public int SetEndOfFile(string filename, long length, DokanFileInfo info)
        {
            return -1;
        }

        public int SetAllocationSize(string filename, long length, DokanFileInfo info)
        {
            return -1;
        }

        public int SetFileAttributes(string filename, FileAttributes attr, DokanFileInfo info)
        {
            return -1;
        }

        public int SetFileTime(string filename, DateTime ctime, DateTime atime, DateTime mtime, DokanFileInfo info)
        {
            return -1;
        }

        public int UnlockFile(string filename, long offset, long length, DokanFileInfo info)
        {
            return 0;
        }

        public int Unmount(DokanFileInfo info)
        {
            return 0;
        }

        public int GetDiskFreeSpace(ref ulong freeBytesAvailable, ref ulong totalBytes, ref ulong totalFreeBytes, DokanFileInfo info)
        {
            freeBytesAvailable = 512 * 1024 * 1024;
            totalBytes = 1024 * 1024 * 1024;
            totalFreeBytes = 512 * 1024 * 1024;
            return 0;
        }

        public int WriteFile(string filename, byte[] buffer, ref uint writtenBytes, long offset, DokanFileInfo info)
        {
            return -1;
        }
    }
}

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
Software Developer (Senior) KAZ Software Limited
Bangladesh Bangladesh
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions