.Net C# – Generic Serialization Methods

1 Comment

Short blog post today.  These are a couple of generic serialize and deserialize methods that can be easily used when needing to serialize and deserialize classes.  The methods work with any .Net type.  That includes built-in .Net types and custom classes that you might create yourself.

These methods will only serialize PUBLIC properties of a class.  Also, the XML will be human-readable instead of one long line of text.

Serialize Method

/// <summary>
 /// Serializes the data in the object to the designated file path
 /// </summary>
 /// <typeparam name="T">Type of Object to serialize</typeparam>
 /// <param name="dataToSerialize">Object to serialize</param>
 /// <param name="filePath">FilePath for the XML file</param>
 public static void Serialize<T>(T dataToSerialize, string filePath)
 {
      try
      {
           using (Stream stream = File.Open(filePath, FileMode.Create, FileAccess.ReadWrite))
           {
                 XmlSerializer serializer = new XmlSerializer(typeof(T));
                 XmlTextWriter writer = new XmlTextWriter(stream, Encoding.Default);
                 writer.Formatting = Formatting.Indented;
                 serializer.Serialize(writer, dataToSerialize);
                 writer.Close();
           }
      }
      catch
      {
           throw;
      }
 }

Deserialize Method

/// <summary>
 /// Deserializes the data in the XML file into an object
 /// </summary>
 /// <typeparam name="T">Type of object to deserialize</typeparam>
 /// <param name="filePath">FilePath to XML file</param>
 /// <returns>Object containing deserialized data</returns>
 public static T Deserialize<T>(string filePath)
 {
      try
      {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            T serializedData;

            using (Stream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
            {
                 serializedData = (T)serializer.Deserialize(stream);
            }

            return serializedData;
      }
      catch
      {
            throw;
      }
 }

Here is some sample code to show the methods in action.

Person p = new Person() { Name = "John Doe", Age = 42 };
XmlHelper.Serialize<Person>(p, @"D:\text.xml");

Person p2 = new Person();
p2 = XmlHelper.Deserialize<Person>(@"D:\text.xml");

Console.WriteLine("Name: {0}", p2.Name);
Console.WriteLine("Age: {0}", p2.Age);

Console.Read();
Tags: ,

.Net WPF – Using Data Triggers

3 Comments

Data triggers are a great feature of WPF. They allow you to change the style properties of a control depending on the data of the bound items of that control.

In this tutorial, I am going to bind a set of data to a ListBox, and use Data Triggers to let me know when something is wrong.

So first, I am going to create a Person class. This class will have three public properties: Name, Age, and IsValid. All three properties will be readonly. The IsValid property will return whether the data of the class is good or not.

Person.cs

public class Person
{
    private string name;

    public string Name
    {
        get { return name; }
        private set { name = value; }
    }
    private int age;

    public int Age
    {
        get { return age; }
        private set { age = value; }
    }

    public bool IsValid
    {
        // will return false if either the name is blank
        //   or if the age is 0.
        get { return (!string.IsNullOrEmpty(name) && age != 0); }
    }

    public Person(string _name, int _age)
    {
        name = _name;
        age = _age;
    }
}

This is a simple example to show the concept. Basically, I am going to set the data to values that we don’t want.


MainWindow.xaml.cs

public partial class MainWindow : Window
{
    ObservableCollection<Person> col;

    public MainWindow()
    {
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        col = new ObservableCollection<Person>();
        col.Add(new Person("John Doe", 24));
        col.Add(new Person("", 24));
        col.Add(new Person("John Doe", 0));

        PersonListBox.ItemsSource = col;
    }
}

As you can see, I set the name to being blank for one object, and the age to being 0 for another object.

Now for the XAML. First, we need to add a new style to the Window.Resources. This style will target the ListBoxItem type.

<Window.Resources>
    <Style TargetType="{x:Type ListBoxItem}" x:Key="ItemStyle">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsValid}" Value="false">
                <Setter Property="Background" Value="Red" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

So if our IsValid property is false, then we will set the Background property of the ListBoxItem to Red.

Then we have our ListBox,

<Grid>
   <ListBox
       Name="PersonListBox"
       ItemsSource="{Binding}"
       ItemContainerStyle="{StaticResource ItemStyle}"
       Height="142"
       HorizontalAlignment="Left"
       Margin="39,30,0,0"
       VerticalAlignment="Top"
       Width="190">

       <ListBox.ItemTemplate>

          <DataTemplate>

             <StackPanel Orientation="Vertical">

                 <StackPanel Orientation="Horizontal">

                    <TextBlock
                        Text="Name:"
                        Width="50" />

                    <TextBlock
                        Text="{Binding Name}"
                        Width="150"  />

                 </StackPanel>

                 <StackPanel Orientation="Horizontal">

                    <TextBlock
                       Text="Age:"
                       Width="50" />

                    <TextBlock
                       Text="{Binding Age}"
                       Width="50"  />

                 </StackPanel>

             </StackPanel>

         </DataTemplate>

     </ListBox.ItemTemplate>

   </ListBox>
</Grid>

So I am binding the ItemsSource to the collection in the code-behind. Also notice that I am binding the style we created to the ItemContainerStyle. The DataTemplate simply creates a custom ItemTemplate to show the data.

So now if we run our code, we get this…

1

But that’s not all. Let’s say that we want to highlight the rows in different colors depending on if the name is blank or if the age is 0. We can create two separate triggers for that. We would simply change our style to this…

<Window.Resources>
   <Style TargetType="{x:Type ListBoxItem}" x:Key="ItemStyle">
       <Style.Triggers>
          <DataTrigger Binding="{Binding Name}" Value="">
               <Setter Property="Background" Value="Blue" />
          </DataTrigger>
          <DataTrigger Binding="{Binding Age}" Value="0">
               <Setter Property="Background" Value="Yellow" />
          </DataTrigger>
       </Style.Triggers>
   </Style>
</Window.Resources>

With that change, our ListBox now shows this…

2

As you can see, Data Triggers are a very powerful part of WPF. Now if only Microsoft would add this to Silverlight.

Tags: ,

.Net, Silverlight Silverlight 4 – Toolkit and Theming

9 Comments

I recently wanted to add a theme from the Silverlight 4 Toolkit, and ran into this runtime error…

12212010122804pm

XamlParseException: Failed to create a ‘System.Type’ from the text ‘input:AutoCompleteBox’.

I was perplexed as I didn’t have an AutoCompleteBox in my project.  It turns out that when you drag a theme from the Toolbox onto the designer, VS2010 doesn’t automatically add all of the references needed(it will add 2).  If you drag a theme from the Toolbox into XAML, VS2010 won’t add ANY references.

It also seems that because themes encompass a majority of controls, there must be a reference for those controls in the project.  After much trial and error, here are the 8 references that will be needed when using a theme from the toolkit:

References

If I removed any of these references, the application would throw a runtime exception similar to the screenshot above.

The “BureauBlack” reference will change depending on the theme that you choose to use in your application.  There is a reference for every theme in the toolkit.

Hope this help out anybody who runs across this problem.

Tags: , ,