Sunday, April 22, 2012

Set TargetDirectory of Assembly Using Post-build event command line

Step 1 : open project properties window.

Step 2 : select Build Events tab.


Step 3 : Click Edit Post-build... Button, Post-build command line window will open


write below line into opened window.

xcopy "$(TargetDir) <You Assembly Name>" "<You Assembly Target Path>" /Y

Now onwards when you build assembly it will automatically to target location, no need to copy and paste.

Saturday, April 21, 2012

Silverlight : Change Images In Specific Time Interval in Different Thread

In Silverlight or Windows Phone 7, sometimes you may have requirement to change ImageSource in time interval.

User have need to Rotating Images one by one every 1 minutes.

To Rotate Image, we need to create Timer and we have to set Image source in another thread that not afftect the current thread.

Below is code snippet.

   private Timer timer;
   private object locker = new object();
   private int count = 0;

   private void StartTimer()
   {
       timer = new Timer(ChangeImage, null, 0, 1000);
   }
   private void ChangeImage(object state)
   {
      try
      {
          lock (locker)
          {
              string imgString = string.Empty;
              switch (count)
              {
                   case 1:
                      imgString = "/MyApplication;component/Images/First.png";
                      break;
                   case 2:
                      imgString = "/MyApplication;component/Images/Second.png";
                      break;
                   case 3:
                      imgString = "/MyApplication;component/Images/Third.png";
                      break;
              }
              Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
              {
                   Uri uri = new Uri(imgString, UriKind.Relative);
                   ImageSource imgSource = new BitmapImage(uri);
                   NearImage.Source = imgSource;
                   count = count + 1;
                   if (count == 4) count = 1;
              }));
          }
      }
      catch (Exception)
      {

      }
   }

In abovo source, i am changing image source every 1 minutes and converting String to ImageSource.

Windows phone 7 : Using Page Navigation in MVVM

Microsoft provides development environment for develop windows mobile application.

To develop application in WP7, we require to install Windows Phone SDK (it includes Developer tool,Visual Studio 2010 Express for Windows Phone, Windows Phone Emulator).

Click Windows Phone SDK 7.1 to Download SDK 

When we are using MVVM pattern in WP7, navigation between pages is sticky task for developer because we don't have NavigationContext in ViewModel.

I am going to focus on how to implement Page Navigation in WP7 using MVVM.


As shown in above screen, when I click on Buy Product button it will navigate to Product Page using MVVM.

For MVVM, I have used GalaSoft.MvvmLight toolkit.

I am going to Explain step by step.

Step 1 : Create Interface that contains method for navigation.

    public interface INavigationService
    {
        void Navigate(string uri);
        void Navigate(string uri, IDictionary<string, string> parameters);
    }

Method with one string parameter will navigate page to passed Uri.

Method with two parameters will pass query string parameter with Uri and navigate to page.

Step 2 : Implements Methods of INavigationService Interface
 
 public class NavigationService : INavigationService
 {
    public void Navigate(string uri)
    {
        PhoneApplicationFrame rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
        rootFrame.Navigate(new Uri(uri, UriKind.RelativeOrAbsolute));    
    }
    public void Navigate(string uri, IDictionary<string, string> parameters)
    {
       PhoneApplicationFrame rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
       if (rootFrame != null)
       {
          StringBuilder fullUri = new StringBuilder();
          fullUri.Append(uri);
          if (parameters != null && parameters.Count > 0)
          {
              fullUri.Append("?");
              bool isAppendAmp = false;
              foreach (KeyValuePair<string, string> keyValuePair in parameters)
              {
                 if (isAppendAmp)
                 {
                            fullUri.Append("&");
                 }
                 fullUri.AppendFormat("{0}={1}", keyValuePair.Key, keyValuePair.Value);
                 isAppendAmp = true;
              }
          }
          uri = fullUri.ToString();
          rootFrame.Navigate(new Uri(uri, UriKind.RelativeOrAbsolute));
       }
    }
 }

As shown in above code, i have created NavigationService class which implements INavigationServiceInteface.

To Navigate one page to another page we are using PhoneApplicationFrame and will navigate page to this frame.

If we have paremeters, we can pass using querystring append with Uri.

For IDictionary, we need to add System.Collections.Generic namespace into class.

Step 3 : Create Method in BaseViewModel that return NavigationContext.

   public class BaseViewModel : ViewModelBase
    {
        public T GetService() where T : class
        {
            if (typeof(T) == typeof(INavigationService))
            {
                return new NavigationService() as T;
            }
            return null;
        }
    }
  
This will return current INavigationService Interface object.

Step 4 : Calling Navigate Method from Page

Suppose, I have ProductViewModel and I want to navigate my page from ProductView to OrderView, I am executing command from ViewModel.


  private void BuyProductCommand_Execute()
  {
     Dictionary<string, string> parameters = new Dictionary<string, string>();
     INavigationService navigationService = this.GetService<INavigationService>();
     navigationService.Navigate("/PageNavigationMVVM_WP7;component/Views/OrderView.xaml", parameters);
  }

as described in above code, i am creating KeyValuepair object to pass parameter.

this.GetService method will get current NavigationService object.

 using this object we can navigate page by passing Uri information.

Step 5 :Create Command in View

First add two namespaces; one for Interactivity, one for GalaSoft.MvvmLight Command.

  xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7"

Place Button control in Page and modify as below.

    <Button Content="Buy Product">
       <Interactivity:Interaction.Triggers>
          <Interactivity:EventTrigger EventName="Click">
             <command:EventToCommand Command="{Binding BuyProductCommand}" />
          </Interactivity:EventTrigger>
       </Interactivity:Interaction.Triggers>
    </Button>

System.windows.Interactivity namespace is used to add Behavior to attached Object, fire trigger on specific event and many more.


Conclusion

when you are using MVVM and going for page navigation this source is useful for you. and you can navigate page with same namespace or different namespace.

Click MVVMPageNavigationInWP7 To Download Souce

Friday, April 13, 2012

Using IsolatedStorage in Silverlight

Isolated Storage is a data storage mechanism that provides facility to store data in a file.

Storage location of IsolatedStorge is based on  application and user identity. each application have separate store.

With isolated storage, data is always isolated by user and by assembly.

System.IO.IsolatedStorage namespace contains types that allow user to create/update and use isolated store.

In Silverlight, there is no concept of Cookies to store information, so IsolatedStorage is great replacement of Cookies in Silverlight application.

In this post, i am going to show you how Create IsolatedStore and save information into it.

First you have to add System.IO.IsolatedStorage namespce.


There are two ways to save Information into IsolatedStorage.

Scenario 1: StoreForSite

 private IsolatedStorageFile isolatedStorage;
 private readonly String applicationDirectory;
 private readonly String settingsFilePath;
 
 this.isolatedStorage = IsolatedStorageFile.GetUserStoreForSite();
 this.applicationDirectory = "UserSettingsDirectory";
 this.settingsFilePath = String.Format("{0}\\settings.xml", this.applicationDirectory);  
 
    public void WriteSettingsData(String content)
    {
       if (this.isolatedStorage == null)
       {
          return false;
       }
       if (!this.isolatedStorage.DirectoryExists(this.applicationDirectory))
       {
           this.isolatedStorage.CreateDirectory(this.applicationDirectory);
       }
       using (IsolatedStorageFileStream fileStream =
         this.isolatedStorage.OpenFile(this.settingsFilePath, 
             System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
       using (StreamWriter streamWriter = new StreamWriter(fileStream))
       {
         streamWriter.Write(content);
       }
    }

In above code, first of all create object of IsolatedStorageFile.
The IsolatedStorageFile class provides functionality to obtain, delete and manage isolated storage.

Then write information into IsolatedStorage using IsolatedStoageFileStream using StreamWriter.
IsolatedStorageFileStream class handles reading and writing files data into store.

Scenario 2: StoreForApplication

   public class LoginInfo
   {
      public string Username { get; set; }
      public string Password { get; set; }
      public bool RememberCredentials { get; set; }
   }
   private void Save_Click(object sender, RoutedEventArgs e)
   {
      
      LoginInfo LoginInformation = new LoginInfo();
      LoginInformation.Username = UserNameTextBox.Text;
      LoginInformation.Password = PasswordTextBox.Text;

      IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForApplication();
      using (IsolatedStorageFileStream fileStream = 
          appStore.OpenFile("hirenlog.log", FileMode.Create))
      {
          var serializer = new DataContractSerializer(typeof(LoginInfo));
          if (fileStream != null)
          {
             serializer.WriteObject(fileStream, LoginInformation);
          }
      }          
      UserNameTextBox.Text = "";
      PasswordTextBox.Text = "";
      
     }

you can also store whole Data contract/Generic class information into IsolatedStore.

As shown in above code, i have created Object of IsolatedStorageFile from StoreForApplication.
After that create file using IsolatedStorageFileStream and give FileName to save.
Then Serialize you Entity using DataContractSerializer and write information.

Now, how get data from IsolatedStorage.



For scenario 1 

  public String GetSettingsData()
  {
     if (this.isolatedStorage == null)
     {
         return String.Empty;
     }
     if (this.isolatedStorage.FileExists(this.settingsFilePath))
     {
         using (IsolatedStorageFileStream fileStream = 
           this.isolatedStorage.OpenFile(this.settingsFilePath, 
               System.IO.FileMode.Open, System.IO.FileAccess.Read))
         using (StreamReader streamReader = new StreamReader(fileStream))
         {
             return streamReader.ReadToEnd();
         }
     }
     return string.Empty;
  }
 

For scenario 2

  private void GetDataContract_Click(object sender, RoutedEventArgs e)
  {
     LoginInfo result = new LoginInfo();
     IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForApplication();
     if (appStore.FileExists("hirenlog.log"))
     {
        using (IsolatedStorageFileStream fileStream = 
             appStore.OpenFile("hirenlog.log", FileMode.Open))
        {
            var serializer = new DataContractSerializer(typeof(LoginInfo));
            if (fileStream != null)
            {
                 result = (LoginInfo)serializer.ReadObject(fileStream);
            }
        }
     }
  }

So, this way you can get data from IsolatedStorage using StreamReader for simple text data and Serializer for DataContract.

Click IsolatedStorageInSilverlight To Download Source.

Thursday, April 12, 2012

Creating and Using Custom UniformGrid Control in Silverlight

Silverlight is a powerful development tool for creating Rich UI Application.

Silverlight delivers richest set of capabilities available to developer through a web browser plug-in.

Silverlight provides Animation, Styles, Media experience and control customization.

In this post we will go through how to customize Listbox and creating custom UniformGrid control to change the layout of Listbox control.



Above Image represents the output of my demo application contains customized Listbox control in HorizontalScrollViewer including UnformGrid for arrange controls in Rows and Columns.

Lets walk-Through scenario.

Step 1 : Create UniformGrid Class for Arrange controls in Rows/Columns.


    public class UnifromGrid : Panel
    {
        public UnifromGrid()
        {

        }
        private int ComputedRows { get; set; }
        private int ComputedColumns { get; set; }

        public int FirstColumn
        {
            get { return (int)GetValue(FirstColumnProperty); }
            set { SetValue(FirstColumnProperty, value); }
        }
        public static readonly DependencyProperty FirstColumnProperty = 
                DependencyProperty.Register("FirstColumn", typeof(int), typeof(UnifromGrid), 
                new PropertyMetadata(0, OnRowColumnChanged));

        public int Columns
        {
            get { return (int)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }

        public static readonly DependencyProperty ColumnsProperty = 
               DependencyProperty.Register("Columns", typeof(int), typeof(UnifromGrid),
               new PropertyMetadata(0, OnRowColumnChanged));

        public int Rows
        {
            get { return (int)GetValue(RowsProperty); }
            set { SetValue(RowsProperty, value); }
        }

        public static readonly DependencyProperty RowsProperty = 
               DependencyProperty.Register("Rows", typeof(int), typeof(UnifromGrid), 
               new PropertyMetadata(0, OnRowColumnChanged));

        private static void OnRowColumnChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (!(e.NewValue is int) || (int)e.NewValue < 0)
            {
                o.SetValue(e.Property, e.OldValue);
            }
        }

       ..........

       ..........


Above class Inherits from Panel Control, so you can create properties that used to change layout of Panel Control base of UniformGrid.

I have created DependencyProperty for Rows/Columns, used to set Row/Column value so controls placed within UniformGrid are automatically arrange in rows/columns.


OnRowColumnChanged method invoked when any one of property( Rows/Column) value set or changed.

private void UpdateComputedValues()
        {
            ComputedColumns = Columns;
            ComputedRows = Rows;
           
            if (FirstColumn >= ComputedColumns)
            {
                FirstColumn = 0;
            }
            if ((ComputedRows == 0) || (ComputedColumns == 0))
            {
                int nonCollapsedCount = 0;
                for (int i = 0, count = Children.Count; i < count; ++i)
                {
                    UIElement child = Children[i];
                    if (child.Visibility != Visibility.Collapsed)
                    {
                        nonCollapsedCount++;
                    }
                }
                if (nonCollapsedCount == 0)
                {
                    nonCollapsedCount = 1;
                }
                if (ComputedRows == 0)
                {                    
                  ComputedRows = (nonCollapsedCount + FirstColumn + 
                                 (ComputedColumns - 1)) / ComputedColumns;                                      
                }
                else if (ComputedColumns == 0)
                {
                    ComputedColumns = (nonCollapsedCount + 
                                      (ComputedRows - 1)) / ComputedRows;
                }
            }
        }


This UpdateComputedValues method is used to calculate Rows based on Column value set vise a versa.


Step 2 : Create HoriZontalScrollViewer Custom Control

public class HorizontalScrollViewer : ContentControl
    {
        public HorizontalScrollViewer()
        {
            this.DefaultStyleKey = typeof(HorizontalScrollViewer);
        }

        public RepeatButton ScrollLeftButton { get; set; }
        public RepeatButton ScrollRightButton { get; set; }
        public ScrollViewer MainScrollViewer { get; set; }

        public override void OnApplyTemplate()
        {
            ScrollLeftButton = (RepeatButton)GetTemplateChild("ScrollLeftButton");
            ScrollRightButton = (RepeatButton)GetTemplateChild("ScrollRightButton");
            MainScrollViewer = (ScrollViewer)GetTemplateChild("MainScrollViewer");

            ScrollLeftButton.Click += new RoutedEventHandler(ScrollLeftButton_Click);
            ScrollRightButton.Click += new RoutedEventHandler(ScrollRightButton_Click);

            base.OnApplyTemplate();
        }

        void ScrollRightButton_Click(object sender, RoutedEventArgs e)
        {
            MainScrollViewer.ScrollToHorizontalOffset(MainScrollViewer.HorizontalOffset + 20);
        }

        void ScrollLeftButton_Click(object sender, RoutedEventArgs e)
        {
            MainScrollViewer.ScrollToHorizontalOffset(MainScrollViewer.HorizontalOffset -20);
        }
    }

If you want to change appearance of any content control, you can create your own control that inherits from ContentControl.

In Above snippet, i have created class for HorizontalScrollViewer.

I have created ScrollLeft and ScrollRight button properties to scroll content with offset into ScrollViewer.

Step 3 : Create Style for  HorizontalScrollViewer.

Style used for change the layout of control.
Style can be placed in tow locations either in  ResourceDictionary file or in App.xaml file.

If you want to create style for custom control, you have to create Generic.xaml file within Themes folder of root directory of your application.

   <Style TargetType="controls:HorizontalScrollViewer">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="controls:HorizontalScrollViewer">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <RepeatButton Name="ScrollLeftButton"
                                      Grid.Column="0">
                            <RepeatButton.Content>
                                <Polyline Points="8,0 0,8 8,15"
                                          Stroke="Black"
                                          StrokeThickness="2"
                                          HorizontalAlignment="Center"
                                          VerticalAlignment="Center" />
                            </RepeatButton.Content>
                        </RepeatButton>
                        <ScrollViewer Name="MainScrollViewer"
                                      Grid.Column="1"
                                      VerticalScrollBarVisibility="Disabled"
                                      HorizontalScrollBarVisibility="Hidden">
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </ScrollViewer>
                        <RepeatButton Name="ScrollRightButton"
                                      Grid.Column="2">
                            <RepeatButton.Content>
                                <Polyline Points="0,0 8,8 0,15"
                                          Stroke="Black"
                                          StrokeThickness="2"
                                          HorizontalAlignment="Center"
                                          VerticalAlignment="Center" />
                            </RepeatButton.Content>
                        </RepeatButton>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style> 


As show in above code , i have created style for properties (ScrollLeftButton/ScrollRightButton and ScrollViewer) that was created in HorizontalScrollViewer class.

To set style for any control you have to set TargetType property which identify that for which control you are applying style.

Step 4 :Create Model that holds Data.

 public class NatureImages
    {
        public string ImageUri { get; set; }
        public string ImageName { get; set; }
        public NatureImages(string uri, string name)
        {
            ImageUri = uri;
            ImageName = name;
        }
    }

Step 5 : Create ViewModel for View

    public class MainPageViewModel : INotifyPropertyChanged
    {
        private ObservableCollection _imageCollection;
        public ObservableCollection ImageCollection
        {
            get { return _imageCollection; }
            set
            {
                _imageCollection = value;
                RaisePropertyChanged("ImageCollection");
            }
        }

        private NatureImages _selectedNature;
        public NatureImages SelectedNature
        {
            get { return _selectedNature; }
            set
            {
                _selectedNature = value;
                RaisePropertyChanged("SelectedNature");
            }
        }

        public MainPageViewModel()
        {
            ImageCollection = new ObservableCollection();
            //====Insert Data into ImageCollection======
              ......
              ......
              ......
           //===========================================   
           SelectedNature = ImageCollection.FirstOrDefault();

        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

    }

This MainPageViewModel contains properties for ItemsSource and SelectedItem of Listbox.

INotifyPropertyChanged Interface is used to notify view when any property value changed.

Step 6 : Create UI page.

  <controls:HorizontalScrollViewer Grid.Row="1">
                <ListBox    Padding="0"
                            Height="Auto"
                            ItemsSource="{Binding ImageCollection}"
                            SelectedItem="{Binding SelectedNature,Mode=TwoWay}"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch">
                    <ListBox.ItemContainerStyle>
                        <Style TargetType="ListBoxItem">
                            <Setter Property="HorizontalAlignment"
                                    Value="Stretch"></Setter>
                            <Setter Property="VerticalAlignment"
                                    Value="Stretch"></Setter>
                            <Setter Property="HorizontalContentAlignment"
                                    Value="Stretch"></Setter>
                            <Setter Property="VerticalContentAlignment"
                                    Value="Stretch"></Setter>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="ListBoxItem">
                                        <Grid>                                            
                                            <Border x:Name="colorBorder">
                                                <ContentPresenter Content="{TemplateBinding Content}" />
                                            </Border>
                                            <Border x:Name="selectedBorder"
                                                    Opacity="0"
                                                    BorderBrush="Black"
                                                    BorderThickness="2"></Border>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ListBox.ItemContainerStyle>
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <controls:UnifromGrid Rows="1" />
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Border Width="100"                                   
                                    BorderBrush="Black"
                                    BorderThickness="1,1,0,0"
                                    RenderTransformOrigin="0.5, 0.5">
                                <Image Source="{Binding ImageUri}"
                                       Stretch="Fill" />
                            </Border>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </controls:HorizontalScrollViewer>
 
 
As show in above snippet, i have placed Listbox in HorizontalScrollViewer custom control that was created previously.

so when any large amount of data is there in list, you can Scroll content using Previous and Next button.

I have set UniformGrid as ItemPanelTemplate in Listbox and set Rows=1, so it will arrange content in 1 Rows and Multiple columns based on ItemsSource records.

Conclusion 

This way you can customize layout of your control with styling and template based on requirements.

Click CustomUniformGridControl To Download Source.