windows phone 7 serialize object to isolated storage

November 16, 2011 at 11:41 PMdsoltesz

I have been working with windows phone 7 recently and i want to be able to serialize an object to xml to save into isolated storage.  Here is a Isolated storage helper that will allow you to do jus that.

public class IsolatedStorageHelper
    {
        public const string MyObjectFile = "myObject.xml";
        public static void WriteToXml<T>(T data, string path)
        {
            // Write to the Isolated Storage
            var xmlWriterSettings = new XmlWriterSettings { Indent = true };

            using (var myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var stream = myIsolatedStorage.OpenFile(path, FileMode.Create))
                {
                    var serializer = new XmlSerializer(typeof(T));
                    using (var xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
                    {
                        serializer.Serialize(xmlWriter, data);
                    }
                }
            }
        }
        public static T ReadFromXml<T>(string path)
        {
            T data = default(T);
            try
            {
                using (var myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (var stream = myIsolatedStorage.OpenFile(path, FileMode.Open))
                    {
                        var serializer = new XmlSerializer(typeof(T));
                        data = (T)serializer.Deserialize(stream);
                    }
                }
            }
            catch
            {    //add some code here
            }
            return data;
        }


    }

To save your object call

IsolatedStorageHelper.WriteToXml(MyObject, IsolatedStorageHelper.MyObjectFile);

To fetch your object

var myObject = IsolatedStorageHelper.ReadFromXml<MyObject> (IsolatedStorageHelper.MyObjectFile);

Posted in: .NET | c# | silverlight | Windows Phone 7

Tags: , , ,

Windows Phone 7 MVVM Framework

November 14, 2011 at 7:04 PMdsoltesz

I have recently starting building a new windows phone 7 application and I was looking for a nice MVVM framework to use.  After reviewing several frameworks, I decided to go with UltraLight MVVM framework.  This is a great light weight framework for developing MVVM Silverlight applications with support for tombstoning on the Windows Phone 7.

UltraLight.mvvm provides a quick, easy and light way to add the following features to your Windows Phone 7 applications:

  • Commands
  • Command binding for buttons (with parameters)
  • Support for binding commands to application buttons / menu items on the application bar
  • Dialogs, both notification and confirmation
  • Messaging using the event aggregator publisher/subscriber model
  • Service location
  • Design-time friendly view models
  • Tombstone-friendly view models with control hooks for tombstone events
  • Decoupled navigation support from the view model
  • Decoupled visual state support from the view model
  • Back button interception on the view model
  • Notify property changed using expressions instead of magic strings
  • Dispatcher helper for UI thread access

Posted in: .NET | c# | silverlight | Windows Phone 7

Tags: , , ,

Deleting a parent entity and related child entities with RIA Services

September 22, 2011 at 12:31 AMdsoltesz

I created an extension that will allow you to traverse child entities easily so that you can remove each one from the parent.  Code is below.

 

public static class EntityExtensions { #region Static Methods (public) public static IEnumerable TraverseChildEntities ( this Entity parent, EntityContainer container ) { IEnumerable entityCollectionProperties = from p in parent.GetType( ).GetProperties( ) where p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition( ) == typeof ( EntityCollection<> ) select p; //// For every entity list, bind to the entity removed event foreach ( PropertyInfo property in entityCollectionProperties ) { var collectionType = property.PropertyType.GetGenericArguments()[0]; EntitySet set; if (!container.TryGetEntitySet(collectionType,out set)) { continue; } var entityCollection = ( IEnumerable )property.GetValue( parent, null ); foreach ( Entity entity in entityCollection ) { foreach ( Entity childEntity in entity.TraverseChildEntities(container ) ) { yield return childEntity; } yield return entity; } } } #endregion }

 With this extension in place now when I want to delete a parent entity and related child entities I can do somethig like this.

 

foreach (var child in new List(Parent.TraverseChildEntities(DomainContext.EntityContainer))) { DomainContext.EntityContainer.GetEntitySet(child.GetType()).Remove(child); } DomainContext.Parents.Remove(parent);

Posted in: c# | silverlight | wcf ria services

Tags: , ,

silverlight listbox autoscroll behavior

July 29, 2011 at 2:09 AMdsoltesz

Sometimes your list boxes can have a lot of items in them.  Even though you may order the list it still can be difficult for the user to find and item.  I like to give the user the abiltiy to search for an item in the listbox.  To keep this clean with MVVM, I created a behavior that can autoscroll for your via databinding.

 

Here is the behavior

 


/// <summary>
    /// Auto scroll listbox to item that is bound to the FoundItem property
    /// </summary>
    public class ListBoxItemAutoScrollBehavior : Behavior<ListBox>
    {
        #region Properties
        /// <summary>
        /// Item that is bound to listbox that you want to autoscroll to
        /// </summary>
        public object FoundItem
        {
            get { return GetValue(FoundItemProperty); }
            set { SetValue(FoundItemProperty, value); }
        }
 
        public static readonly DependencyProperty FoundItemProperty = DependencyProperty.Register("FoundItem"typeof(object), typeof(ListBoxItemAutoScrollBehavior), new PropertyMetadata(FoundItemChanged));
 
        private static void FoundItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ListBoxItemAutoScrollBehavior)d).AssociatedObject.ScrollIntoView(e.NewValue);
        }
        #endregion
    }

 

Make sure you add a reference to System.Windows.Interactivity.

 

To use the behavior I do something like this.

<ListBox ItemsSource="{Binding MyItems}"  DisplayMemberPath="ItemName"  SelectionMode="Multiple">
                        <i:Interaction.Behaviors>
                            <behaviors:ListBoxItemAutoScrollBehavior FoundItem="{Binding FoundItem}"/>
                        </i:Interaction.Behaviors>
                    </ListBox>
<TextBox Text="{Binding ItemToFind, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" BorderThickness="1" />

 

Now in your view model just define your properties to bind to.


public ObservableCollection<Item> MyItems
        {
            get { return _myItems; }
            set
            {
 
                if (_myItems == valuereturn;
                _myItems = value;
                OnPropertyChanged(() => MyItems);
            }
        }
 
        public string ItemToFind
        {
            get { return _itemToFind; }
            set
            {
                if (_itemToFind == valuereturn;
                _itemToFind = value;
                 FoundItem = MyItems.FirstOrDefault(o => o.ItemName.StartsWith(_itemToFind, StringComparison.CurrentCultureIgnoreCase));
                OnPropertyChanged(() => ItemToFind);
                OnPropertyChanged(() => FoundItem);
            }
        }
         public Item FoundItem { getset; }

 Now when the user types in something into the textbox, it will autoscroll to the item that is found

Posted in: behaviors | c# | silverlight

Tags: , ,

ListBox load data when user reaches end of list

January 25, 2011 at 10:48 PMdsoltesz

Great post on a behavior that will raise a command when the users scrolls to the end of a listbox to fetch more data.

This can easily be applied to wpf or silverlight as well.

http://danielvaughan.orpius.com/post/Scroll-Based-Data-Loading-in-Windows-Phone-7.aspx

Posted in: .NET | behaviors | silverlight

Tags: , ,

silverlight attach behavior in code

October 27, 2010 at 9:51 PMdsoltesz

I had a scenario where I needed to build part of the UI completely from Code and wanted to include a behavior as part of one of the UI controls.

Lets walk through and example of how to do this.

I want to create a WrapPanel that has the FluidMoveBehavior associated to the WrapPanel and applies the behavior to all its children.



var panel = new WrapPanel
{
   HorizontalAlignment = HorizontalAlignment.Left
};

var timeSpan = new TimeSpan(0, 0, 0, 0, 400);
var ease = new CubicEase
{
    EasingMode = EasingMode.EaseIn
};
var fluidMoveBehavior = new FluidMoveBehavior
{
    AppliesTo = FluidMoveScope.Children,
    Duration = new Duration(timeSpan),
    EaseX = ease,
    EaseY = ease
};

System.Windows.Interactivity.Interaction.GetBehaviors(panel).Add(fluidMoveBehavior);

 

Pretty easy, just make sure you add references to

  • System.Windows.Interactivity
  • Microsoft.Expression.Effects
  • Microsoft.Express.Interactions

Posted in: .NET | behaviors | c# | silverlight

Tags: , ,

Silverlight datagrid double click behavior MVVM

October 1, 2010 at 6:20 PMdsoltesz

I originally created a behavior to add double click support to a silverlight datagrid.  Post here http://www.dansoltesz.com/post/2010/02/19/Silverlight-datagrid-double-click-behavior.aspx

I had someone ask me how they could get this to work with MVVM so I want to post the changes to the DataGridDoubleClickBehavior class in the original post to support commanding.

Add a new dependency property

public ICommand DoubleClickCommand
        {
            get { return (ICommand)GetValue(DoubleClickCommandProperty); }
            set { SetValue(DoubleClickCommandProperty, value); }
        }

        public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.Register("DoubleClickCommand"typeof(ICommand), typeof(DataGridDoubleClickBehavior), new PropertyMetadata(DoubleClickCommandChanged));

        private static void DoubleClickCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Code for dealing with your property changes
        }


 public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter"typeof(object), typeof(DataGridDoubleClickBehavior), new PropertyMetadata(CommandParameterChanged));

        private static void CommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Code for dealing with your property changes
        }

Now in the _gridClickManager_DoubleClick event defined in the behavior add this new line

 void _gridClickManager_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (DoubleClick != null)
                DoubleClick(sender, e);

           if(DoubleClickCommand != null) DoubleClickCommand.Execute(CommandParameter); //code added

        } 

the behavior class now looks like this

 public class DataGridDoubleClickBehavior : Behavior<DataGrid>
    {

        private readonly MouseClickManager _gridClickManager;
        public event EventHandler<MouseButtonEventArgs> DoubleClick;
        public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter"typeof(object), typeof(DataGridDoubleClickBehavior), new PropertyMetadata(CommandParameterChanged));

        private static void CommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Code for dealing with your property changes
        }
        public ICommand DoubleClickCommand
        {
            get { return (ICommand)GetValue(DoubleClickCommandProperty); }
            set { SetValue(DoubleClickCommandProperty, value); }
        }

        public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.Register("DoubleClickCommand"typeof(ICommand), typeof(DataGridDoubleClickBehavior), new PropertyMetadata(DoubleClickCommandChanged));

        private static void DoubleClickCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Code for dealing with your property changes
        }

        public DataGridDoubleClickBehavior()
        {
            _gridClickManager = new MouseClickManager(300);
            _gridClickManager.DoubleClick += new MouseButtonEventHandler(_gridClickManager_DoubleClick);
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.LoadingRow += OnLoadingRow;
            AssociatedObject.UnloadingRow += OnUnloadingRow;
        }

        void OnUnloadingRow(object sender, DataGridRowEventArgs e)
        {
            //row is no longer visible so remove double click event otherwise
            //row events will miss fire
            e.Row.MouseLeftButtonUp -= _gridClickManager.HandleClick;
        }

        void OnLoadingRow(object sender, DataGridRowEventArgs e)
        {
            //row is visible in grid, wire up double click event
            e.Row.MouseLeftButtonUp += _gridClickManager.HandleClick;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.LoadingRow -= OnLoadingRow;
            AssociatedObject.UnloadingRow -= OnUnloadingRow;
        }

        void _gridClickManager_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (DoubleClick != null)
                DoubleClick(sender, e);
 if (DoubleClickCommand != null)
DoubleClickCommand.Execute(CommandParameter);
        }

    }

 

Now in your datagrid instead of wiring up an event for the double click you bind to the DoubleClickCommand of your viewmodel.

Originally was

<data:DataGrid x:Name="myDataGrid">

<i:Interaction.Behaviors>

            <behaviors:DataGridDoubleClickBehavior DoubleClick="myDataGrid_DoubleClick"/>

      </i:Interaction.Behaviors> 

</data:DataGrid>

Now change to

That its, now when a user double clicks a grid row, the command will be raised in your viewModel.

<data:DataGrid x:Name="myDataGrid">

<i:Interaction.Behaviors>

            <behaviors:DataGridDoubleClickBehavior

DoubleClickCommand="{Binding DoubleCommand}

CommandParameter="{Binding SelectedItem, ElementName=myDataGrid}"/>

 

    </i:Interaction.Behaviors>

</data:DataGrid>

 

Posted in: .NET | behaviors | silverlight

Tags: , , ,

Silverlight display special characters

June 3, 2010 at 11:45 PMdsoltesz

I wanted to diplay an ampersand (&) in the text of a textblock.  At first I tried this

<TextBlock Text="Folders & Files"/>

 but visual studio gave me an error

If you change the code to

<TextBlock Text="Folders &amp; Files"/>


everything words fine and visual studio is happy

Other special character encodings are

Character

Encoding

&

&amp;

&quot;

<

&lt;

>

&gt;

space

&#160;

&apos;

Posted in: silverlight

Tags: ,

Silverlight 4 textbox right click context menu with cut, copy and paste behavior

May 27, 2010 at 9:46 PMdsoltesz

I wanted to be able to allow my users the ability to right click in a textbox and have a contextmenu shown to be able to cut, copy and paste. I decided to create a behavior so that the functionality can easily be added to any textbox control.


using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

using System.Windows.Interactivity;

 

namespace MyApp.Behaviors.TextBox

{

    public class TextBoxCutCopyPasteBehavior : Behavior<System.Windows.Controls.TextBox>

    {

        private ContextMenu _contextMenu;

        private MenuItem _copy;

        private MenuItem _cut;

        private MenuItem _paste;

        public TextBoxCutCopyPasteBehavior()

        {

 

            _contextMenu = new ContextMenu();

            _cut = new MenuItem();

            _cut.Header = "Cut";

            _cut.Click += new RoutedEventHandler(cut_Click);

            _contextMenu.Items.Add(_cut);

 

            _copy = new MenuItem();

            _copy.Header = "Copy";

            _copy.Click += new RoutedEventHandler(copy_Click);

            _contextMenu.Items.Add(_copy);

 

            _paste = new MenuItem();

            _paste.Header = "Paste";

            _paste.Click += new RoutedEventHandler(paste_Click);

            _contextMenu.Items.Add(_paste);

 

 

        }

 

        void paste_Click(object sender, RoutedEventArgs e)

        {

            AssociatedObject.SelectedText = Clipboard.GetText();

            _contextMenu.IsOpen = false;

        }

 

        void cut_Click(object sender, RoutedEventArgs e)

        {

            Clipboard.SetText(AssociatedObject.SelectedText);

            AssociatedObject.SelectedText = string.Empty;

            AssociatedObject.Focus();

            _contextMenu.IsOpen = false;

        }

 

        void copy_Click(object sender, RoutedEventArgs e)

        {

            Clipboard.SetText(AssociatedObject.SelectedText);

            AssociatedObject.Focus();

            _contextMenu.IsOpen = false;

        }

 

        protected override void OnAttached()

        {

 

            AssociatedObject.MouseRightButtonDown += new MouseButtonEventHandler(AssociatedObject_MouseRightButtonDown);

            AssociatedObject.MouseRightButtonUp += new MouseButtonEventHandler(AssociatedObject_MouseRightButtonUp);

            AssociatedObject.SetValue(ContextMenuService.ContextMenuProperty, _contextMenu);

            base.OnAttached();

        }

 

        void AssociatedObject_MouseRightButtonUp(object sender, MouseButtonEventArgs e)

        {

            if (Clipboard.ContainsText())

                _paste.IsEnabled = true;

            else

                _paste.IsEnabled = false;

 

            if (string.IsNullOrEmpty(AssociatedObject.SelectedText))

            {

                _cut.IsEnabled = false;

                _copy.IsEnabled = false;

            }

            else

            {

                _cut.IsEnabled = true;

                _copy.IsEnabled = true;

            }

            _contextMenu.IsOpen = true;

 

        }

 

        void AssociatedObject_MouseRightButtonDown(object sender, MouseButtonEventArgs e)

        {

            e.Handled = true;

        }

 

        protected override void OnDetaching()

        {

            AssociatedObject.MouseRightButtonDown -= new MouseButtonEventHandler(AssociatedObject_MouseRightButtonDown);

            AssociatedObject.MouseRightButtonUp -= new MouseButtonEventHandler(AssociatedObject_MouseRightButtonUp);

            _contextMenu = null;

            base.OnDetaching();

 

        }

 

    }

}

 

 

Once the behavior is created we can now add to our TextBox

  1. add a reference to System.Windows.Interactivity
  2. In your xaml code add
    1. xmlns

      :i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    2. xmlns

      :behaviors="clr-namespace:MyApp.Behaviors.TextBox;assembly=MyApp"
    3.  <TextBox x:Name="myTextBox" >
             <i:Interaction.Behaviors>
                 <behaviros:TextBoxCutCopyPasteBehavior/>
             </i:Interaction.Behaviors>
         </TextBox>


That's it, now you have right click support for your textbox with cut, copy and paste.

Posted in: behaviors | silverlight

Tags: ,

silverlight save settings

April 6, 2010 at 6:19 PMdsoltesz

There are lots of time when you want to be able to store user settings in between sessions of your application. I found that using Isoloated Storage makes this very easy. I created a helper class to do just this.


IsolatedStorageManager.cs

using System.IO.IsolatedStorage;

namespace MyApp.Utilities

{

    public static class IsolatedStorageManager

    {

        /// <summary>

        /// Save property and value into isolated storage

        /// </summary>

        /// <param name="value">value to store</param>

        /// <param name="name">name of property</param>

        public static void SaveIntoIsolatedStorage(object value, string name)

        {

            IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings; 

            //If settings have never been saved, then we have to add appsetting first

            if (!appSettings.Contains(name))

            {

                appSettings.Add(name, null);

            }

            //store page user is currently on for when they come back in

            appSettings[name] = value;

        }

        public static bool Contains(string name)

        {

            IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

            return appSettings.Contains(name);

        }

        /// <summary>

        /// Remove property value from isolated storage

        /// </summary>

        /// <param name="name">name of property</param>

        public static void Remove(string name)

        {

            IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;


            //If settings have been saved, then we remove since the user wants to select a new queue/page

            if (appSettings.Contains(name))

            {

                appSettings.Remove(name);

            }

        }

        /// <summary>

        /// Removes all properties stored in isolated storage

        /// </summary>

        public static void RemoveAll()

        {

            IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

            appSettings.Clear();

        } 

        /// <summary>

        /// Retrieve setting that was stored in Isolated Storage

        /// </summary>

        /// <param name="name">name of the property to retrieve</param>

        /// <returns></returns>

        public static object LoadFromIsolatedStorage(string name)

        {

            IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

            if (appSettings.Contains(name))

            {

                return appSettings[name];

            }

            return null;

        }

    }

}


Now when we want to save a user setting or retrieve a user setting we can simple use our helper class.

Example: I wanted to remember the last page the user was on and automatically navigate the user to that page when they returned. Whenever a user navigated to a page I would simple store the name of the current page

IsolatedStorageManager .SaveIntoIsolatedStorage(pageName, Constants.CURRENT_PAGE);

Now when the user leaves your application and returns, we can check to see what page they were on before and return them to that page.

if (IsolatedStorageManager.Contains(Constants.CURRENT_PAGE)) //user was here before

{

   NavigateToPage((string)IsolatedStorageManager.LoadFromIsolatedStorage(Constants.CURRENT_PAGE));

 }

 else

  NavigateToPage("Home");

}

Posted in: c# | silverlight

Tags: ,