Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Saturday, April 16, 2011

Datapager: Paging in RIA Application with MVVM

PagedEntitySet

This will help creating List of Entities that can be paged.

public class PagedEntitySet : INotifyPropertyChanged, INotifyCollectionChanged, IPagedCollectionView, IEnumerable
	where T : Entity, new()
{

	#region Private Members

	private IPagedCollectionView _pagingView;

	private IEnumerable Enumerable { get { return this._entityList; } }

	private EntitySet _entityList;

	#endregion

	#region IEnumerable Members

	public IEnumerator GetEnumerator()
	{
		return this._entityList.GetEnumerator();
	}

	#endregion

	#region IEnumerable Members

	IEnumerator IEnumerable.GetEnumerator()
	{
		return this.GetEnumerator();
	}

	#endregion

	#region Constructor

	public PagedEntitySet(EntitySet entityList, IPagedCollectionView delegatePagingView)
	{
		_entityList = entityList;
		INotifyCollectionChanged collectionChanged = _entityList as INotifyCollectionChanged;
		if (collectionChanged != null)
			collectionChanged.CollectionChanged += (s, e) => CollectionChanged(this, e);
		_pagingView = delegatePagingView;
		_pagingView.PageChanging += PageChanging;
		_pagingView.PageChanged += PageChanged;
		INotifyPropertyChanged propertyChanged = _pagingView as INotifyPropertyChanged;
		if (propertyChanged != null)
			propertyChanged.PropertyChanged += (s, e) => PropertyChanged(this, e);
	}

	#endregion

	#region INotifyPropertyChanged Members

	public event PropertyChangedEventHandler PropertyChanged = delegate { };

	#endregion

	#region INotifyCollectionChanged Members

	public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { };

	#endregion

	#region IPagedCollectionView Members

	public bool CanChangePage
	{
		get { return _pagingView.CanChangePage; }
	}

	public bool IsPageChanging
	{
		get { return _pagingView.IsPageChanging; }
	}

	public int ItemCount
	{
		get { return _pagingView.ItemCount; }
	}

	public bool MoveToFirstPage()
	{
		return _pagingView.MoveToFirstPage();
	}

	public bool MoveToLastPage()
	{
		return _pagingView.MoveToLastPage();
	}

	public bool MoveToNextPage()
	{
		return _pagingView.MoveToNextPage();
	}

	public bool MoveToPage(int pageIndex)
	{
		return _pagingView.MoveToPage(pageIndex);
	}

	public bool MoveToPreviousPage()
	{
		return _pagingView.MoveToPreviousPage();
	}

	public event EventHandler PageChanged = delegate { };

	public event EventHandler PageChanging = delegate { };

	public int PageIndex
	{
		get { return _pagingView.PageIndex; }
	}

	public int PageSize
	{
		get { return _pagingView.PageSize; }
		set { _pagingView.PageSize = value; }
	}

	public int TotalItemCount
	{
		get { return _pagingView.TotalItemCount; }
	}

	#endregion

}

PagedViewModelBase
This abstract class will help binding your view model to view page with paging functionality.

public abstract class PagedViewModelBase: IPagedCollectionView, INotifyPropertyChanged
{

	#region Member Properties

	private static PropertyChangedEventArgs IsPageChangingChangedEventArgs = new PropertyChangedEventArgs("IsPageChanging");

	private static PropertyChangedEventArgs ItemCountChangedEventArgs = new PropertyChangedEventArgs("ItemCount");

	private static PropertyChangedEventArgs PageIndexChangedEventArgs = new PropertyChangedEventArgs("PageIndex");

	private static PropertyChangedEventArgs PageSizeChangedEventArgs = new PropertyChangedEventArgs("PageSize");

	private static PropertyChangedEventArgs TotalItemCountChangedEventArgs = new PropertyChangedEventArgs("TotalItemCount");

	private static PropertyChangedEventArgs IsLoadingChangedEventArgs = new PropertyChangedEventArgs("IsLoading");

	private bool _isLoading;

	public bool IsLoading
	{
		get { return _isLoading; }
		set
		{
			if (_isLoading != value)
			{
				_isLoading = value;
				RaisePropertyChanged(IsLoadingChangedEventArgs);
			}
		}
	}

	#endregion

	#region Member Functions

	public abstract void LoadData();

	#endregion

	#region INotifyPropertyChanged Members

	public event PropertyChangedEventHandler PropertyChanged;

	protected void RaisePropertyChanged(PropertyChangedEventArgs args)
	{
		if (PropertyChanged != null)
			PropertyChanged(this, args);
	}

	#endregion

	#region IPagedCollectionView Members

	public bool CanChangePage
	{
		get { return true; }
	}

	bool isPageChanging;

	public bool IsPageChanging
	{
		get { return isPageChanging; }
		private set
		{
			if (isPageChanging != value)
			{
				isPageChanging = value;
				RaisePropertyChanged(IsPageChangingChangedEventArgs);
			}

		}
	}

	int itemCount;

	public int ItemCount
	{
		get { return itemCount; }
		set
		{
			if (itemCount != value)
			{
				itemCount = value;
				RaisePropertyChanged(ItemCountChangedEventArgs);
			}
		}
	}

	public bool MoveToFirstPage()
	{
		return MoveToPage(0);
	}

	public bool MoveToLastPage()
	{
		return MoveToPage(TotalItemCount / PageSize);
	}

	public bool MoveToNextPage()
	{
		return MoveToPage(PageIndex + 1);
	}

	public bool MoveToPage(int index)
	{
		if (index == PageIndex || index < 0 || index > TotalItemCount / PageSize)
		{
			return false;
		}
		PageChangingEventArgs args = new PageChangingEventArgs(index);
		try
		{
			IsPageChanging = true;
			PageChanging(this, args);
			if (!args.Cancel)
			{
				pageIndex = index;
				LoadData();
				RaisePropertyChanged(PageIndexChangedEventArgs);
				PageChanged(this, EventArgs.Empty);
				return true;
			}
			return false;
		}
		finally
		{
			IsPageChanging = false;
		}
	}

	public bool MoveToPreviousPage()
	{
		return MoveToPage(PageIndex - 1);
	}

	public event EventHandler<EventArgs> PageChanged = delegate { };

	public event EventHandler<PageChangingEventArgs> PageChanging = delegate { };

	int pageIndex;

	public int PageIndex
	{
		get { return pageIndex; }
		set
		{
			if (pageIndex < 0 || pageIndex > totalItemCount / PageSize)
			{
				throw new ArgumentOutOfRangeException("PageIndex must be greater than or equal to 0 and less than the page count");
			}
			MoveToPage(value);
		}
	}

	int pageSize = 10; //default page size to 10

	public int PageSize
	{
		get { return pageSize; }
		set
		{
			if (pageSize != value)
			{
				pageSize = value;
				RaisePropertyChanged(PageSizeChangedEventArgs);
			}
		}
	}

	int totalItemCount;

	public int TotalItemCount
	{
		get { return totalItemCount; }
		set
		{
			if (totalItemCount != value)
			{
				totalItemCount = value;
				RaisePropertyChanged(TotalItemCountChangedEventArgs);
			}
		}
	}
	
	#endregion
}

This both Class will help you to easily bind your datagrid and datapager.
Just use PagedEntitySet type for binding data in your viewmodel for both datagrid and datapager.
Use constructor to initialize data in it.

This is the easiest way I find. If you have some more smart code please share it. Hope this will save a lot of your time. Happy Coding..

Tuesday, April 12, 2011

Implementing RelayCommand in easiest way

public class RelayCommand<T> : ICommand
{
        Action<T> _TargetExecuteMethod;

        Func<T, bool> _TargetCanExecuteMethod;

        public RelayCommand(Action<T> executeMethod)
        {
            _TargetExecuteMethod = executeMethod;
        }

        public RelayCommand(Action<T> executeMethod, Func<T,bool> canExecuteMethod)
        {
            _TargetExecuteMethod = executeMethod;
            _TargetCanExecuteMethod = canExecuteMethod;
        }

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }

        #region ICommand Members
        bool ICommand.CanExecute(object parameter)
        {
            if (_TargetCanExecuteMethod != null)
            {
                T tparm = (T)parameter;

                return _TargetCanExecuteMethod(tparm);
            }

            if (_TargetExecuteMethod != null)
            {
                return true;
            }

            return false;
        }

        // Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command

        // Prism commands solve this in their implementation

        public event EventHandler CanExecuteChanged = delegate { };

        void ICommand.Execute(object parameter)
        {
            if (_TargetExecuteMethod != null)
            {
               _TargetExecuteMethod((T)parameter);
            }
        }
        #endregion

}

Saturday, October 23, 2010

Why to use MVVM patterns with Silverlight and WPF development

To begin with, there are numerous and varied ways in implementing methodologies like MVVM, most of which are used based on personal preference. To a novice trying to educate themselves, this leads to disparity in information. Complicating this factor is that many of the articles or videos that attempt to describe the MVVM pattern also include components of other architectural patterns. This adds unnecessary complexity to understanding the MVVM pattern because of the inconsistencies in the pattern being described.

A great artical by Kim Schmidt. Here is the link

Saturday, September 25, 2010

How to Debug WCF Services in Silverlight

check out this new SilverlightTV video, going over some of the common errors you may encounter when using WCF services from Silverlight:

Get Microsoft Silverlight
Silverlight TV 46: What's Wrong with my WCF Service?
Direct link

Thursday, September 23, 2010

5+ Ways to Reduce .Xap Size in Silverlight

Being Silverlight developer means that we are also kind of web developers. From this point of view, we also have to think about the web traffic that our applications generate. We need to reduce it as much as possible. So basically we need to reduce the size of the application's output - the .xap file.

Understanding the Xap

In order to reduce the size of a xap file, we should first be aware of its structure. Basically it can contain only 4 things:
  • AppManifest.xaml - xaml file that identifies the packaged assemblies and the application entry point
  • Application Assembly - the one that contains the Application class.
  • Library assemblies.
  • Resource files - like images and videos
So we can smaller its size by reducing the code and resources of our assemblies, load assemblies on demand (exclude them from the xap) or minify some of the compiled library assemblies.

Start with the Resources

You should carefully think about the resources (Images, Videos...) - how you use and manage them! You have 3 options to choose from - embed them into assembly, add them as a content in the xap or leave them on the server as web content. Note that the last option can reduce the xap significantly. You have to check their "Build Action" and choose the correct one:
  • Resource - The resource gets embedded into the assembly, so respectively in the xap.
  • Content - The resource gets embedded into the xap. 
  • None - The resource won't be embedded into the assembly nor the xap. But you can "Copy it to the Output Directory", so use it as web resource, thus Load it on Demand.
You can read more about Silverlight resource files here.

Application Library Caching

It allows you to exclude assemblies form the xap with just a single click option, mark them as external parts and make them ready to be cached by the browser. I'm not going to dive into Assembly Caching, since Evan made a great post about it. Just read it and consider using it.

Load assemblies on Demand

This trick is possible due to the Silverlight API, that allows us to load assemblies into the AppDomain. We need to download one using simple WebClient, load it and use Reflection to use its types and resources. Although this is tricky and kind of obsolete (thanks to the Prism), one can find it interesting and implement it on his/her own. You can read more about this approach.

Modularity with Prism

Prism is probably the best approach out there for Silvrelight application development. The architecture allows us to slice the application into Moduls. Each module can be easily configured to be Loaded On Demand | When Available and On the Background.  So the resulting application consist of a lot of xaps and some of them are delayed and downloaded during run-time, which can significantly reduce the initial download time and respectively enhance the overall user experience. Download the latest binaries and play with the modularity example projects.
Note that if a Module reference assembly that is loaded with the main module, you can set its CopyLocal = False attribute, which means that the assembly won't be included into the xap. But since it will be already loaded into the AppDomain, everything is ok.

Dead-code removing - Minification

Although the Prism give us so much flexibility and great features, it can't fix one problem that comes with using already compiled assemblies. The abstract problem is that it doesn't matter how much code or features you use from one assembly - you get it as a whole. This problem was addressed long time ago and the solution is named "Minification" (the process of removing all unnecessary characters from source code, without changing its functionality). This is very popular trick in the JavaScript world (and it obviously makes sense - to reduce the size of a web page, by removing unused JS code). In the Telerik's Silverlight world the solution is called Assembly Minifier. It reduces the compiled assemblies size by removing the controls (code and resources) that your application doesn't need during run-time. The result is smaller assemblies, smaller xap, which results in faster download time and faster application loading. You can read my post for more information on how to use the tool.

Some more Tricks

  • Re-zip your xap package using higher compression ratio. Read the full story by Valeri Hristov.
  • Configure long expiration date on your IIS, so the xap will be cached by the user's browser, thus downloaded only once.
  • Create nice looking and professional SplashScreen that will reduce the bad experience from downloading big xap package. 
Source: Telerik Blog

Thursday, August 12, 2010

Advanced Encryption in Silverlight and .NET Applications

AES encryption is implemented in both Silverlight and .NET run times, using exact same set of classes, primary one being AesManaged class.

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
 
namespace Encryption
{
    public static class EncryptionUtility
    {
        public static string Encrypt(string input, string password)
        {
 
            byte[] utfData = UTF8Encoding.UTF8.GetBytes(input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);
            string encryptedString = string.Empty;
            using (AesManaged aes = new AesManaged())
            {
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);
 
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
 
                using (ICryptoTransform encryptTransform = aes.CreateEncryptor())
                {
                    using (MemoryStream encryptedStream = new MemoryStream())
                    {
                        using (CryptoStream encryptor = 
                            new CryptoStream(encryptedStream, encryptTransform, CryptoStreamMode.Write))
                        {
                            encryptor.Write(utfData, 0, utfData.Length);
                            encryptor.Flush();
                            encryptor.Close();
 
                            byte[] encryptBytes = encryptedStream.ToArray();
                            encryptedString = Convert.ToBase64String(encryptBytes);
                        }
                    }
                }
            }
            return encryptedString;
        }
 
        public static string Decrypt(string input, string password)
        {
 
            byte[] encryptedBytes = Convert.FromBase64String(input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);
            string decryptedString = string.Empty;
            using (var aes = new AesManaged())
            {
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
 
                using (ICryptoTransform decryptTransform = aes.CreateDecryptor())
                {
                    using (MemoryStream decryptedStream = new MemoryStream())
                    {
                        CryptoStream decryptor = 
                            new CryptoStream(decryptedStream, decryptTransform, CryptoStreamMode.Write);
                        decryptor.Write(encryptedBytes, 0, encryptedBytes.Length);
                        decryptor.Flush();
                        decryptor.Close();
 
                        byte[] decryptBytes = decryptedStream.ToArray();
                        decryptedString = 
                            UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
                    }
                }
            }
 
            return decryptedString;
        }
    }
}

Create a Path Using Path Markup Language Silverlight 4 - Video Tutorial

Silverlight supports a powerful and complex mini-language that you can use to describe geometric paths. You use this mini-language when setting a property of type Geometry, such as the Clip property of a UIElement or the Data property of a Path element. In this video, Todd Miranda demonstrates how to manually create a path using Path Markup Language.

http://www.silverlight.net/learn/videos/all/create-a-path-using-path-markup-language/

Source: silverlight.net

Wednesday, April 21, 2010

The Basic Difference between Silverlight and WPF

Silverlight and Windows Presentation Foundation (WPF) are 2 different products from Microsoft, but has lot of overlap. Silverlight is a sub set of WPF in terms of features and functionality.

Silverlight is a Microsoft technology, competing with Adobes Flash and is meant for developing rich browser based internet applications.

Silverlight’s architecture is interesting. It includes parts of Windows Presentation Foundation (WPF), but runs on more operating systems.

WPF and Silverlight are both XAML based platforms but there are some important functionality and implementation differences between the two.

WPF is a Microsoft technology meant for developing enhanced graphics applications for desktop platform. In addition, WPF applications can be hosted on web browsers which offers rich graphics features for web applications. Web Browser Appliactions (WBA) developed on WPF technology uses XAML to host user interface for browser applications. XAML stands for eXtended Application Markup Language which is a new declarative programming model from Microsoft. XAML files are hosted as descrete files in the Web server, but are downloaded to the browsers and converted to user interface by the .NET runtime in the client browsers.

WPF runs on .NET runtime and developers can take advantage of the rich .NET Framework and WPF libraries to build really cool windows applications. WPF supports 3-D graphics, complex animations, hardware acceleration etc.