Monday, January 2, 2012

Lazy list box in Windows phone 7.5 (Mango)

Most phone users are concerned about network usage. Network traffic comes at a premium, and a user's perception of the quality of your app depends a lot on its responsiveness. When it comes to fetching data from a network service, it should be done in the most efficient manner possible. Making the user wait while your app downloads giant reams of data doesn't cut it. It should, instead, be done in bite-sized chunks.
To make this easy for you, I have created a ScrollViewerMonitor which uses an Attached Property to monitor a ListBox and fetch data as the user needs it. It's as simple as adding an Attached Property to a control which contains a ScrollViewer, such as a ListBox, as shown in the following example:
<ListBox ItemsSource="{Binding Items}"
         u:ScrollViewerMonitor.AtEndCommand="{Binding FetchMoreDataCommand}" />
Notice the AtEndCommand. That's an Attached Property that allows you to specify a command to be executed when the user scrolls to the end of the list.

Source help to write this blog:
Lazy Loading

Use the following code to achieve and modify according to your Model class:

In c#:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DanielVaughan.WindowsPhone7Unleashed;
using System.Collections.Generic;
using SnapDeal;
using System.Linq;
using System.Threading;
using System.Collections.ObjectModel;
using System.ComponentModel;
using SnapDeal.ViewModels;
using Microsoft.Phone.Controls;

namespaceLazy
{
    public class OptimizedListBox : ListBox, INotifyPropertyChanged
    {
        /// <summary>
        /// Max items to display in only scroll
        /// </summary>
        public int MaxCount { get; set; }

        public delegate void FetchDataEventHandler(object sender, ResponseArgs args);
        public event FetchDataEventHandler FetchData;

        public static readonly DependencyProperty ListProperty =
           DependencyProperty.Register(
               "ListItems",
               typeof(IDataModel),
               typeof(OptimizedListBox),
               null);


        public OptimizedListBox()
        {
            fetchMoreDataCommand = new DelegateCommand(
                obj =>
                {
                    if (busy)
                    {
                       return;
                    }
                    Busy = true;
                    if (FetchData != null)
                        FetchData(this, null);
                    else
                        Busy = false;
                });
            ScrollViewerMonitor.SetAtEndCommand(this, FetchMoreDataCommand);          
        }

        /// <summary>
        /// Actual items of list
        /// </summary>
        public IDataModel ListItems
        {
            get { return GetValue(ListProperty) as IDataModel; }
            set { SetValue(ListProperty, value); }
        }

        public void FetchCompleted(bool isUpdateNeeded)
        {
            Busy = false;

            if (!isUpdateNeeded)
                return;

            if (this.ListItems != null)
            {
                int start = this.Items.Count;
                int end = start + Constant.kMaxLoadItemCount;
                if (this.ListItems.GetType() == typeof(Zone))
                {
                    Zone loadedItems = this.ListItems as Zone;
                    if (end > loadedItems.Count() - 1)
                        end = loadedItems.Count();
                    for (int i = start; i < end; i++)
                    {
                        this.Items.Add(loadedItems[i]);
                    }
                }
            }
        }

        readonly DelegateCommand fetchMoreDataCommand;
        public ICommand FetchMoreDataCommand
        {
            get { return fetchMoreDataCommand; }
        }
            
        bool busy;
        public bool Busy
        {
            get { return busy; }
            set
            {
                if (busy != value)
                {
                    busy = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("Busy"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, e);
            }
        }
    }
}


In XAML:

 <local:OptimizedListBox x:Name="TodaysDealList" ListItems="{Binding TodaysDealList}" SelectionChanged="OnSelectDealItem" ItemContainerStyle="{StaticResource ListboxStretchStyle}" Margin="5, 0, 0,0"/>

To display the progress indicator just use the following line:

 <TextBlock Text="Loading..." Grid.Row="1" Style="{StaticResource LoadingStyle}" Foreground="White"
                               Visibility="{Binding Busy, ElementName=TodaysDealList,
                      Converter={StaticResource BooleanToVisibilityConverter}}"/>
The Max count indicates the how many items u want to load on each scroll, list items indicates  your actual items of list.(Hope you know about converters)
May be it will helpful for you.

-Mahantesh

Friday, July 8, 2011

unzip the file in wp7

How to unzip the file in wp7?

Hi, this is my first post about the programming and i dont want to explain theory things .. Just i want to post the c# code to unzip file .
the following code doesn't require the third party like sharpziplib.

using System.IO;
using System.Text;
using System.Collections.Generic;
using System.IO.IsolatedStorage;

namespace WP7UnzipFile
{
    public class UnZipper
    {
        internal void UnzipFile(string filePath)
        {
            StreamResourceInfo fileInfo = App.GetResourceStream(new Uri(filePath, UriKind.Relative));
            UnzipFile(ref fileInfo);
        }


        internal void UnzipFile(ref StreamResourceInfo fileInfo)
        {
            string[] fileNames = GetFileNamesFromZip(fileInfo.Stream);
            foreach (string fileName in fileNames)
            {
                StreamResourceInfo audioFile = App.GetResourceStream(fileInfo, new Uri(fileName, UriKind.Relative));
                if (audioFile != null)
                    SaveFile(audioFile.Stream, fileName);
            }
        }


        private void SaveFile(Stream stream, string relativefilePath)
        {
            //int lastSlashPos = relativefilePath.LastIndexOf('/');
            //int substringLen = relativefilePath.Length - relativefilePath.LastIndexOf('/');
            //string fileName = relativefilePath.Substring(lastSlashPos + 1, substringLen - 1);
            using (var appStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (appStore.FileExists(relativefilePath))
                    appStore.DeleteFile(relativefilePath);

                CreateDirectory(appStore, relativefilePath);
                using (IsolatedStorageFileStream isoStream = appStore.CreateFile(relativefilePath))
                {
                    byte[] buffer = new byte[stream.Length];
                    using (BinaryWriter fileWriter = new BinaryWriter(isoStream))
                    {
                        stream.Read(buffer, 0, (int)stream.Length);
                        fileWriter.Write(buffer);
                    }
                }
            }
        }

        private void CreateDirectory(IsolatedStorageFile appStore, string relativefilePath)
        {
            if (relativefilePath.Contains("/"))
            {
                int lastSlashPos = relativefilePath.LastIndexOf('/');
                int substringLen = relativefilePath.Length - relativefilePath.LastIndexOf('/');

                string directoryName = relativefilePath.Remove(lastSlashPos, substringLen);
                if (!string.IsNullOrEmpty(directoryName))
                    appStore.CreateDirectory(directoryName);
            }
        }

        /// <summary>
        /// Reads the file names from the header of the zip file
        /// </summary>
        /// <param name="zipStream">The stream to the zip file</param>
        /// <returns>An array of file names stored within the zip file. These file names may also include relative paths.</returns>
        private string[] GetFileNamesFromZip(System.IO.Stream zipStream)
        {
            List<string> names = new List<string>();
            BinaryReader reader = new BinaryReader(zipStream);
            while (reader.ReadUInt32() == 0x04034b50)
            {
                // Skip the portions of the header we don't care about
                reader.BaseStream.Seek(14, SeekOrigin.Current);
                uint compressedSize = reader.ReadUInt32();
                uint uncompressedSize = reader.ReadUInt32();
                int nameLength = reader.ReadUInt16();
                int extraLength = reader.ReadUInt16();
                byte[] nameBytes = reader.ReadBytes(nameLength);
                names.Add(Encoding.UTF8.GetString(nameBytes, 0, nameLength));
                reader.BaseStream.Seek(extraLength + compressedSize, SeekOrigin.Current);

            }
            // Move the stream back to the begining
            zipStream.Seek(0, SeekOrigin.Begin);
            return names.ToArray();

        }
    }

}


if written code creates any problem in Ur app.. Dont blame me..