Silverlight Read External XML Loading Configuration – Use WebClient to Read XAP Package and XML File

I find this post from http://stephenchy520.blog.com/2011/07/26/silverlight-read-external-xml-loading-configuration-use-webclient-read-xml-from-xap-package/. It is very helpful so that I get permission from author and share it with you. And I have changed some sentences and hope it to be more readable.

How to use Webclient to read XAP package and XML file under it?

For reading XML file under XAP package, we need to put the XML file to the web category which loads XAP package. And then use URI method to read XML file under the URL.

At first, we need to use WebClient to download this XML file with XML asynchronously. Then, use XmlReaders to get data information of XML file.

There are three tips we need to know.

1. Get web address prefix when calling Silverlight application XAP package to get URL of this XML file.

            public static string GetURL()
            {
                ScriptObject location = (HtmlPage.Window.GetProperty(“location”) as ScriptObject);
                object r = location.GetProperty(“href”);

                //Intercept current URL prefix which is to save Silverlight application.
                string URL = r.ToString().Substring(0, r.ToString().LastIndexOf(‘/’));
                return URL;
            }

2. Download XML with WebClient

            Uri uri = new Uri(GetURL() + “/Config.xml”, UriKind.Absolute);

            //Use WebClient to download config.xml and read asynchronously.
            WebClient Appclient = new WebClient();
            Appclient.OpenReadAsync(uri);
            Appclient.OpenReadCompleted += new OpenReadCompletedEventHandler(Appclient_OpenReadCompleted);

3. Use XmlReader to read XML file.

            Stream stream = e.Result;
            using (XmlReader xReader = XmlReader.Create(stream))
            {
                //Use XmlReader to find “TestData” Elemenet and get its data.
                xReader.ReadToFollowing(“TestData”);

                string TestData = xReader.ReadElementContentAsString();
                MessageBox.Show(TestData);

                //Use ReadToNextSibling to find “SecData” Element data until the data is found.
                xReader.ReadToNextSibling(“SecData”);

                string SecData = xReader.ReadElementContentAsString();
                MessageBox.Show(SecData);
            }

Add the following namespace as reference:

using System.IO;
using System.Xml;
using System.Windows.Browser;

Code in details as following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Xml;
using System.Windows.Browser;

namespace SLReadXML
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            Uri uri = new Uri(GetURL() + “/Config.xml”, UriKind.Absolute);
            //Use WebClient to download config.xml and read asynchronously.
            WebClient Appclient = new WebClient();

            Appclient.OpenReadAsync(uri);
            Appclient.OpenReadCompleted += new OpenReadCompletedEventHandler(Appclient_OpenReadCompleted);
        }
        void Appclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            Stream stream = e.Result;
            using (XmlReader xReader = XmlReader.Create(stream))
            {
                //Use XmlReader to find “TestData” Elemenet and get its data.
                xReader.ReadToFollowing(“TestData”);

                string TestData = xReader.ReadElementContentAsString();
                MessageBox.Show(TestData);
                //Use ReadToNextSibling to find “SecData” Element data until the data is found.
                xReader.ReadToNextSibling(“SecData”);

                string SecData = xReader.ReadElementContentAsString();
                MessageBox.Show(SecData);
           }
        }

        ///<summary>
        ///Get current URL prefix which is to save Silverlight application.
        ///</summary>
        ///<returns>URL Prefix</returns>
        public static string GetURL()
        {
            ScriptObject location = (HtmlPage.Window.GetProperty(“location”) as ScriptObject);
            object r = location.GetProperty(“href”);
            //Intercept current URL prefix which is to save Silverlight application.
            string URL = r.ToString().Substring(0, r.ToString().LastIndexOf(‘/’));

            return URL;
        }
    }
}

Two Components Recommend:

Spire.Doc, is used to operate MS Word document for .Net and Silverlight, including basic manipulations (generate, open, edit documents), mail merge and other Word functions manipulations.

Spire.XLS, is used to operate MS Excel for .NET and Silverlight, including basic manipulations (generate, open, edit files), chart creation and data exporting.

Silverlight-MatrixTransform Detailed Introduction and How to Realize Other Transforms with It

This post focuses on how to use MatrixTransform to realize other transformations in Silverlight.

Essence of MatrixTransform: Every Piexels on element which needs to transform multiply matrix to get new coordinate of this point.

The following shows MatrixTransform 3*3 element image:

Number 0,0,1 are changless in silverlight so that we can ignor them. But there are four coordinate Matrix moudules (M11, M12,  M21, M22) we need to multiply.

Then, we can get the new coordinate points (X1, Y1) according to algorithm of old (X,Y) *matrix.

But the new point is not the final location. We need to plus offset point OffsetX and OffsetY to get the final coordinate point (X1+OffsetX, Y+OffsetY).

In conclusion, each coordinate point of original image must be calculated with this equation: X2=X*M11+Y*M21+OffsetX, Y2=X*M12+Y*M22+OffsetY to get the final coordinate point location.

The usage in source code is <MatrixTransform Matrix="M11 M12 M21 M22 OffsetX OffsetY"></MatrixTransform>.

Now, the following instance how to realize other transformations by MatrixTransform.

1. RotateTransform Effect

<! —a90°?transformation around central point (0,0)–>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“48,49,0,0” Name=“image11” Stretch=“Fill”  Width=“50” Source=“/SLTrans;component/iPhone_001.png”  Opacity=“.3” />
<Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“48,49,0,0” Name=“image1” Stretch=“Fill”  Width=“50” Source=“/SLTrans;component/iPhone_001.png” >
    <Image.RenderTransform>
        <!–m11(0) m12(1)   m21(-1) m22(0)   OffsetX(0) OffsetY(0)–>
        <!–0*X+ -1*X=-1X    1*Y+0*Y =1Y   -1X+0     1Y+0      =>New Coordinate Point (-1X,1Y)  –>
        <MatrixTransform Matrix=“0 1 -1 0 0 0”></MatrixTransform>
    </Image.RenderTransform>
</Image>

2. ScaleTransform Effect

<!–0.6 times scale transform–>
 <ImageHeight=“50”HorizontalAlignment=“Left”VerticalAlignment=“Top”Margin=“139,49,0,0”Name=“image21”Stretch=“Fill”Width=“50”Source=“/SLTrans;component/iPhone_002.png” Opacity=“.3”/> <ImageHeight=“50”HorizontalAlignment=“Left”VerticalAlignment=“Top”Margin=“139,49,0,0”Name=“image2”Stretch=“Fill”Width=“50”Source=“/SLTrans;component/iPhone_002.png”>
        <Image.RenderTransform>
            <!–m11(0.6) m12(0)   m21(0) m22(0.6)   OffsetX(0) OffsetY(0)–>
            <!–0.6*X+0*X=0.6X    0*Y+0.6*Y =0.6Y   0.6X+0     0.6Y+0      =>New Coordinate Point(0.6X,0.6Y)  –>
            <MatrixTransformMatrix=“0.6 0 0 0.6 0 0”></MatrixTransform>
        </Image.RenderTransform>
    </Image>

3. SkewTransform Effect

<! —aSkew Transform–>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“226,49,0,0” Name=“image31” Stretch=“Fill” Width=“50” Source=“/SLTrans;component/iPhone_003.png” Opacity=“.3”/>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“226,49,0,0” Name=“image3” Stretch=“Fill” Width=“50” Source=“/SLTrans;component/iPhone_003.png” >
    <Image.RenderTransform>
        <!–m11(1) m12(0)  m21(1) m22(1)  OffsetX(0) OffsetY(0)–>
        <!–1*X+1*X=2X     0*Y+1*Y =1Y    2X+0       1Y+0   =>New Coordinate Point(2X,0Y)  –>
        <MatrixTransform Matrix=“1 0 1 1 0 0”></MatrixTransform>
    </Image.RenderTransform>       
</Image>

4. TranslateTransform Effect

<!–TranslateTransform–>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“331,49,0,0” Name=“image41” Stretch=“Fill” Width=“50” Source=“/SLTrans;component/iPhone_004.png” Opacity=“.3”/>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“331,49,0,0” Name=“image4” Stretch=“Fill” Width=“50” Source=“/SLTrans;component/iPhone_004.png” >
        <Image.RenderTransform>
            <!–m11(1) m12(0)  m21(0) m22(1) OffsetX(10) OffsetY(50)–>
            <!–1*X+0*X=2X     0*Y+1*Y =0Y   1X+10       1Y+50  => New Coordinate Point(1X+10,1Y+50)  –>
            <MatrixTransform Matrix=“1 0 0 1 10 50”></MatrixTransform>
        </Image.RenderTransform>
    </Image>

5. TransformGroup Effect

<! —aOverturn around Y axle–>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“426,49,0,0” Name=“image51” Stretch=“Fill” Width=“50” Source=“/SLTrans;component/iPhone_005.png” Opacity=“.3”/>
    <Image Height=“50” HorizontalAlignment=“Left” VerticalAlignment=“Top” Margin=“426,49,0,0” Name=“image5” Stretch=“Fill” Width=“50” Source=“/SLTrans;component/iPhone_005.png” >
        <Image.RenderTransform>
            <!–m11(1) m12(0) m21(0) m22(-1)   OffsetX(0) OffsetY(100)–>
            <!–1*X+ 0*X=1X   0*Y+ -1*Y =-1Y   1X+0       -1Y+100  => New Coordinate Point(1X,-1Y)  –>
            <MatrixTransform Matrix=“1 0 0 -1 0 0”></MatrixTransform>
        </Image.RenderTransform>
    </Image>

The following image shows the results.

Two Components Recommend:

Spire.Doc, is used to operate MS Word document for .Net and Silverlight, including basic manipulations (generate, open, edit documents), mail merge and other Word functions manipulations.

Spire.XLS, is used to operate MS Excel for .NET and Silverlight, including basic manipulations (generate, open, edit files), chart creation and data exporting.

Silverlight-Brief Introduction of MVVM Framework

This post focuses on the usage of  MNNM framework by taking MVVM Light Tooklit as example. Firstly, we need to download MVVM framework from http://mvvmlight.codeplex.com. Then install it. Open VS2010 and create a new project.

  • Tip: MVVM includes Model, ViewMode, View three levels.
  • Model: Entity class level, which is used to save all the needed entity classes.
  • ViewMode: Logic level, which is a big entity class to operate Model and View interface level and offers properties to bind to View level.
  • View: Interface display level. We just need to use its xaml code to bind corresponding ViewMode level properties.

1. In the following MainPage.xaml code, View level is bound to ViewMode level.  It is MainViewModel.cs class.

<UserControl x:Class=“MvvmLight1.MainPage”

             xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

             xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml&#8221;

             xmlns:d=http://schemas.microsoft.com/expression/blend/2008&#8221;

             xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006&#8221;

             mc:Ignorable=“d”

             Height=“300”

             Width=“300”

             DataContext=“{Binding Main, Source={StaticResource Locator}}”>

    <! —aBind static resource in App.xaml here to link MainViewModel class (ViewMode level) and MainPage.xaml code is View level–>

        <UserControl.Resources>

            <ResourceDictionary>

                <ResourceDictionary.MergedDictionaries>

                    <ResourceDictionary Source=“Skins/MainSkin.xaml” />

                </ResourceDictionary.MergedDictionaries>

            </ResourceDictionary>

        </UserControl.Resources>

        <Grid x:Name=“LayoutRoot”>

            <TextBlock FontSize=“36” FontWeight=“Bold” Foreground=“Purple” Text=“{Binding Welcome}” VerticalAlignment=“Center” HorizontalAlignment=“Center” TextWrapping=“Wrap” Margin=“12,25,20,171” />

            <Button Content=“{Binding BtnContent}” Height=“23” HorizontalAlignment=“Left” Margin=“12,178,0,0” Command=“{Binding ShowMessage}” Name=“button1” VerticalAlignment=“Top” Width=“75” />

            <Button Content=“Click to Change” Height=“23” HorizontalAlignment=“Left” Command=“{Binding ChangeText}” Margin=“187,178,0,0” Name=“button2” VerticalAlignment=“Top” Width=“75” />

        </Grid>

    </UserControl>

2. Then, ViewMode level. We state some string properties to bind to display content of View level. Then, send events and handling methods by using Command for mouse clicking method and set binding. If so, we can separate click events of foreground from background directly and inherit InotifyProperty connector to make ViewModel property be reflected to View level when changing and View level foreground presentation be changed when changing ViewModel properties in Command.

using GalaSoft.MvvmLight;

using System.Windows.Input;

using GalaSoft.MvvmLight.Command;

using System.Windows;

using System.ComponentModel;

namespace MvvmLight1.ViewModel

{

    ///<summary>

    ///This class contains properties that the main View can data bind to.

    ///<para>

    ///Use the <strong>mvvminpc</strong>snippet to add bindable properties to this ViewModel.

    ///</para>

    ///<para>

    ///You can also use Blend to data bind with the tool’s support.

    ///</para>

    ///<para>

    ///See http://www.galasoft.ch/mvvm/getstarted

    ///</para>

    ///</summary>

    public class MainViewModel : ViewModelBase, INotifyPropertyChanged

    {

        public string Welcome

        {

            get

            {

                return “Welcome to Use MVVM Light! “;

            }

        }

        ///<summary>

        ///Class Initialization

        ///</summary>

        public MainViewModel()

        {

            _btnContent = “Click”;

            RegistCommand();

        }

        //A. Bind Property

        private string _btnContent;

        public string BtnContent

        {

            set

            {

                _btnContent = value;

                NotifyPropertyChanged(“BtnContent”);

            }

            get

            {

                return _btnContent;

            }

        }

        //B. 1 State to Bind Click Event

        public RelayCommand ShowMessage { get; set; }

        //Use Registration of C step and Connect Command and Method to Run

        private void showmsg()

        {

            MessageBox.Show(“Succeed to bind command to interface layer!);

        }

        //B.2 Change Control Presentation Text on Interface

        public RelayCommand ChangeText { get; set; }

        //Operation to Change Text

        private void changeTxt()

        {

            BtnContent = “It has been changed.”;

        }

        //Text Can Be Changed or not

        private bool canchangeTxt()

        {

            if (BtnContent == “Click”)

            {

                return true;

            }

            else

            {

                return false;

            }

        }

        //C. Register for All Methods

        private void RegistCommand()

        {

            //C.1 Specify function showmsg() which is needed to execute.

            ShowMessage = new RelayCommand(() => showmsg());

            //Execute canchangeTxt() firstly to verify if text can be change. If can, execute changeTxt().

            ChangeText = new RelayCommand(() => changeTxt(), () => canchangeTxt());

        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

}

3. Here, we don’t use Model level. It is usually used for creating entity sets to bind control like DataGrid.

Two Components Recommend:

Spire.Doc, is used to operate MS Word document for .Net and Silverlight, including basic manipulations (generate, open, edit documents), mail merge and other Word functions manipulations.

Spire.XLS, is used to operate MS Excel for .NET and Silverlight, including basic manipulations (generate, open, edit files), chart creation and data exporting.

Silverlight – InkPresenter Doodle Pad Basic Usage and Save Image as Png

Sometimes, we need to draw lines by handing in Silverlight. InkPresenter can help us. It supports users to use mouse, writing pad and other tools to draw graph or handwriting.

InkPresenter inherits Canvas control and supports all the Canvas properties. Also, the other controls can be nested inside it. There are three levels of InkPresenter: bottom is background of InkPresenter; Middle is control with Children property of InkPresenter; the last is stroke of Strokes property.

We can set color, thinkness, border color and other properties for Stroke to get wonderful type. The following XAML code shows how to use InkPresenter.

    <Gridx:Name=”LayoutRoot1″Background=”White”>

<Canvas>

<BorderBorderThickness=”1″Margin=”50 10 0 0″BorderBrush=”CadetBlue”HorizontalAlignment=”Center”VerticalAlignment=”Center”>

<InkPresenterx:Name=”iPresenter”Height=”500″Width=”500″MouseLeftButtonDown=”iPresenter_MouseLeftButtonDown”LostMouseCapture=”iPresenter_LostMouseCapture”MouseMove=”iPresenter_MouseMove”Background=”Transparent”Opacity=”1″ >

<TextBoxWidth=”138″Canvas.Left=”58″Canvas.Top=”105″></TextBox>

</InkPresenter>

</Border>

<ButtonCanvas.Left=”560″Canvas.Top=”11″Content=”Save Graffiti as Image”Height=”23″Name=”button1″Width=”104″Click=”button1_Click” />

<ImageName=”showIP”Width=”400″Height=”400″Canvas.Left=”560″Canvas.Top=”60″></Image>

</Canvas>

</Grid>

Xaml.cs code:

    public partial class MainPage : UserControl

    {

        public MainPage()

        {

            InitializeComponent();

            SetPresenterClip();

        }

        Stroke myStroke;

        private void iPresenter_MouseLeftButtonDown(object sender, MouseEventArgs e)

        {

            //Use Mouse to Catch Data

            iPresenter.CaptureMouse();

            //Collect Data Point and Save Value to StylusPointCollection

            StylusPointCollection stylusPointCollection = new StylusPointCollection();

            stylusPointCollection.Add(e.StylusDevice.GetStylusPoints(iPresenter));

            //Save Data Point Collection as Stroke

            myStroke = new Stroke(stylusPointCollection);

            //Set Drawing Effect of Stork as Color, Size and so on

            myStroke.DrawingAttributes.Color = Colors.Gray;

            myStroke.DrawingAttributes.Width = 1;

            myStroke.DrawingAttributes.Height = 1;

            iPresenter.Strokes.Add(myStroke);

        }

        private void iPresenter_MouseMove(object sender, MouseEventArgs e)

        {

            //Add Data Point to Stroke when Moving Mouse

            if (myStroke != null)

                myStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(iPresenter));

        }

        private void iPresenter_LostMouseCapture(object sender, MouseEventArgs e)

        {

            //Clear Stroke

            myStroke = null;

            iPresenter.ReleaseMouseCapture();//Release Mouse Location

        }

        ///<summary>

        ///Set Drawing Range as Size of InkPresente

        ///</summary>

        private void SetPresenterClip()

        {

            RectangleGeometry MyRectangleGeometry = new RectangleGeometry();

            MyRectangleGeometry.Rect = new Rect(0, 0, iPresenter.ActualWidth, iPresenter.ActualHeight);

            //Set Available Range to Get Drawing Content

            iPresenter.Clip = MyRectangleGeometry;

        }

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            //Save Image which is Drawing in InkPresenter Doodle Pad

            WriteableBitmap _bitmap = new WriteableBitmap(iPresenter, null);

            this.showIP.Source = _bitmap;

            SaveFileDialog sfd = new SaveFileDialog();

            sfd.Filter = “PNG Files (*.png)|*.png|All Files (*.*)|*.*”;

            sfd.DefaultExt = “.png”;

            sfd.FilterIndex = 1;

            if ((bool)sfd.ShowDialog())

            {

                using (Stream fs = sfd.OpenFile())

                {

                    int width = _bitmap.PixelWidth;

                    int height = _bitmap.PixelHeight;

                    EditableImage ei = new EditableImage(width, height);

                    for (int i = 0; i < height; i++)

                    {

                        for (int j = 0; j < width; j++)

                        {

                            int pixel = _bitmap.Pixels[(i * width) + j];

                            ei.SetPixel(j, i,

                                (byte)((pixel >> 16) & 0xFF),

                                (byte)((pixel >> 8) & 0xFF),

                                (byte)(pixel & 0xFF),

                                (byte)((pixel >> 24) & 0xFF)

                                );

                        }

                    }

                    //Get Stream

                    Stream png = ei.GetStream();

                    int len = (int)png.Length;

                    byte[] bytes = new byte[len];

                    png.Read(bytes, 0, len);

                    fs.Write(bytes, 0, len);

                    MessageBox.Show(“Succeed to Save Image”);

                }

            }

        }

}

If we want to save the image which is drawn in InkPresenter as png, we need to use two classes which is assisted to convert image to png.

    ///<summary>

    ///Edit Image

    ///</summary>

    public class EditableImage

    {

        private int _width = 0;

        private int _height = 0;

        private bool _init = false;

        private byte[] _buffer;

        private int _rowLength;

        ///<summary>

        ///Trigger when Having Image Error

        ///</summary>

        public event EventHandler<EditableImageErrorEventArgs> ImageError;

        ///<summary>

        ///Instantiate

        ///</summary>

        ///<param name=”width”></param>

        ///<param name=”height”></param>

        public EditableImage(int width, int height)

        {

            this.Width = width;

            this.Height = height;

        }

        public int Width

        {

            get

            {

                return _width;

            }

            set

            {

                if (_init)

                {

                    OnImageError(“Error: Width cannot be changed after initializing image.”);

                }

                else if ((value <= 0) || (value > 2047))

                {

                    OnImageError(“Error: Width must be between 0 and 2047”);

                }

                else

                {

                    _width = value;

                }

            }

        }

        public int Height

        {

            get

            {

                return _height;

            }

            set

            {

                if (_init)

                {

                    OnImageError(“Error: Height cannot be changed after initializing image.”);

                }

                else if ((value <= 0) || (value > 2047))

                {

                    OnImageError(“Error: Height must be between 0 and 2047.”);

                }

                else

                {

                    _height = value;

                }

            }

        }

        public void SetPixel(int col, int row, Color color)

        {

            SetPixel(col, row, color.R, color.G, color.B, color.A);

        }

        public void SetPixel(int col, int row, byte red, byte green, byte blue, byte alpha)

        {

            if (!_init)

            {

                _rowLength = _width * 4 + 1;

                _buffer = new byte[_rowLength * _height];

                // Initialize

                for (int idx = 0; idx < _height; idx++)

                {

                    _buffer[idx * _rowLength] = 0;     

                }

                _init = true;

            }

            if ((col > _width) || (col < 0))

            {

                OnImageError(“Error: Column must be greater than 0 and less than the Width”);

            }

            else if ((row > _height) || (row < 0))

            {

                OnImageError(“Error: Row must be greater than 0 and less than the Height”);

            }

            // Set the pixel

            int start = _rowLength * row + col * 4 + 1;

            _buffer[start] = red;

            _buffer[start + 1] = green;

            _buffer[start + 2] = blue;

            _buffer[start + 3] = alpha;

        }

        public Color GetPixel(int col, int row)

        {

            if ((col > _width) || (col < 0))

            {

                OnImageError(“Error: Column must be greater than 0 and less than the Width”);

            }

            else if ((row > _height) || (row < 0))

            {

                OnImageError(“Error: Row must be greater than 0 and less than the Height”);

            }

            Color color = new Color();

            int _base = _rowLength * row + col + 1;

            color.R = _buffer[_base];

            color.G = _buffer[_base + 1];

            color.B = _buffer[_base + 2];

            color.A = _buffer[_base + 3];

            return color;

        }

        public Stream GetStream()

        {

            Stream stream;

            if (!_init)

            {

                OnImageError(“Error: Image has not been initialized”);

                stream = null;

            }

            else

            {

                stream = PngEncoder.Encode(_buffer, _width, _height);

            }

            return stream;

        }

        private void OnImageError(string msg)

        {

            if (null != ImageError)

            {

                EditableImageErrorEventArgs args = new EditableImageErrorEventArgs();

                args.ErrorMessage = msg;

                ImageError(this, args);

            }

        }

        public class EditableImageErrorEventArgs : EventArgs

        {

            private string _errorMessage = string.Empty;

            public string ErrorMessage

            {

                get { return _errorMessage; }

                set { _errorMessage = value; }

            }

        }

    }

Png Operation Class:

    ///<summary>

    ///PNG Format Operation Class

    ///</summary>

    public class PngEncoder

    {

        private const int _ADLER32_BASE = 65521;

        private const int _MAXBLOCK = 0xFFFF;

        private static byte[] _HEADER = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };

        private static byte[] _IHDR = { (byte)‘I’, (byte)‘H’, (byte)‘D’, (byte)‘R’ };

        private static byte[] _GAMA = { (byte)‘g’, (byte)‘A’, (byte)‘M’, (byte)‘A’ };

        private static byte[] _IDAT = { (byte)‘I’, (byte)‘D’, (byte)‘A’, (byte)‘T’ };

        private static byte[] _IEND = { (byte)‘I’, (byte)‘E’, (byte)‘N’, (byte)‘D’ };

        private static byte[] _4BYTEDATA = { 0, 0, 0, 0 };

        private static byte[] _ARGB = { 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 0, 0, 0 };

        ///<summary>

        ///Coding

        ///</summary>

        ///<param name=”data”></param>

        ///<param name=”width”></param>

        ///<param name=”height”></param>

        ///<returns></returns>

        public static Stream Encode(byte[] data, int width, int height)

        {

            MemoryStream ms = new MemoryStream();

            byte[] size;

            // Write PNG header

            ms.Write(_HEADER, 0, _HEADER.Length);

            // Write IHDR

            //  Width:              4 bytes

            //  Height:             4 bytes

            //  Bit depth:          1 byte

            //  Color type:         1 byte

            //  Compression method: 1 byte

            //  Filter method:      1 byte

            //  Interlace method:   1 byte

            size = BitConverter.GetBytes(width);

            _ARGB[0] = size[3]; _ARGB[1] = size[2]; _ARGB[2] = size[1]; _ARGB[3] = size[0];

            size = BitConverter.GetBytes(height);

            _ARGB[4] = size[3]; _ARGB[5] = size[2]; _ARGB[6] = size[1]; _ARGB[7] = size[0];

            // Write IHDR chunk

            WriteChunk(ms, _IHDR, _ARGB);

            // Set gamma = 1

            size = BitConverter.GetBytes(1 * 100000);

            _4BYTEDATA[0] = size[3]; _4BYTEDATA[1] = size[2]; _4BYTEDATA[2] = size[1]; _4BYTEDATA[3] = size[0];

            // Write gAMA chunk

            WriteChunk(ms, _GAMA, _4BYTEDATA);

            // Write IDAT chunk

            uint widthLength = (uint)(width * 4) + 1;

            uint dcSize = widthLength * (uint)height;

            // First part of ZLIB header is 78 1101 1010 (DA) 0000 00001 (01)

            // ZLIB info

            //

            // CMF Byte: 78

            //  CINFO = 7 (32K window size)

            //  CM = 8 = (deflate compression)

            // FLG Byte: DA

            //  FLEVEL = 3 (bits 6 and 7 – ignored but signifies max compression)

            //  FDICT = 0 (bit 5, 0 – no preset dictionary)

            //  FCHCK = 26 (bits 0-4 – ensure CMF*256+FLG / 31 has no remainder)

            // Compressed data

            //  FLAGS: 0 or 1

            //    00000 00 (no compression) X (X=1 for last block, 0=not the last block)

            //    LEN = length in bytes (equal to ((width*4)+1)*height

            //    NLEN = one’s compliment of LEN

            //    Example: 1111 1011 1111 1111 (FB), 0000 0100 0000 0000 (40)

            //    Data for each line: 0 [RGBA] [RGBA] [RGBA] …

            //    ADLER32

            uint adler = ComputeAdler32(data);

            MemoryStream comp = new MemoryStream();

            // 64K Counting

            uint rowsPerBlock = _MAXBLOCK / widthLength;

            uint blockSize = rowsPerBlock * widthLength;

            uint blockCount;

            ushort length;

            uint remainder = dcSize;

            if ((dcSize % blockSize) == 0)

            {

                blockCount = dcSize / blockSize;

            }

            else

            {

                blockCount = (dcSize / blockSize) + 1;

                // Header

                comp.WriteByte(0x78);

                comp.WriteByte(0xDA);

                for (uint blocks = 0; blocks < blockCount; blocks++)

                {

                    // Length

                    length = (ushort)((remainder < blockSize) ? remainder : blockSize);

                    if (length == remainder)

                    {

                        comp.WriteByte(0x01);

                    }

                    else

                    {

                        comp.WriteByte(0x00);

                    }

                    comp.Write(BitConverter.GetBytes(length), 0, 2);

                    comp.Write(BitConverter.GetBytes((ushort)~length), 0, 2);

                    // Write Block

                    comp.Write(data, (int)(blocks * blockSize), length);

                    //Next One

                    remainder -= blockSize;

                }

                WriteReversedBuffer(comp, BitConverter.GetBytes(adler));

                comp.Seek(0, SeekOrigin.Begin);

                byte[] dat = new byte[comp.Length];

                comp.Read(dat, 0, (int)comp.Length);

                WriteChunk(ms, _IDAT, dat);

                // Write IEND chunk

                WriteChunk(ms, _IEND, new byte[0]);

                // Reset stream

                ms.Seek(0, SeekOrigin.Begin);

                return ms;

            }

            private static void WriteReversedBuffer(Stream stream, byte[] data)

            {

                int size = data.Length;

                byte[] reorder = new byte[size];

                for (int idx = 0; idx < size; idx++)

                {

                    reorder[idx] = data[size – idx – 1];

                }

                stream.Write(reorder, 0, size);

            }

        private static void WriteChunk(Stream stream, byte[] type, byte[] data)

        {

            int idx;

            int size = type.Length;

            byte[] buffer = new byte[type.Length + data.Length];

            // Initialization Load

            for (idx = 0; idx < type.Length; idx++)

            {

                buffer[idx] = type[idx];

            }

            for (idx = 0; idx < data.Length; idx++)

            {

                buffer[idx + size] = data[idx];

            }

            WriteReversedBuffer(stream, BitConverter.GetBytes(data.Length));

            // Write Type and Data

            stream.Write(buffer, 0, buffer.Length);  

            // Calculate and Write CRC

            WriteReversedBuffer(stream, BitConverter.GetBytes(GetCRC(buffer)));

        }

        private static uint[] _crcTable = new uint[256];

        private static bool _crcTableComputed = false;

        private static void MakeCRCTable()

        {

            uint c;

            for (int n = 0; n < 256; n++)

            {

                c = (uint)n;

                for (int k = 0; k < 8; k++)

                {

                    if ((c & (0x00000001)) > 0)

                        c = 0xEDB88320 ^ (c >> 1);

                    else

                        c = c >> 1;

                }

                _crcTable[n] = c;

            }

            _crcTableComputed = true;

        }

        private static uint UpdateCRC(uint crc, byte[] buf, int len)

        {

            uint c = crc;

            if (!_crcTableComputed)

            {

                MakeCRCTable();

            }

            for (int n = 0; n < len; n++)

            {

                c = _crcTable[(c ^ buf[n]) & 0xFF] ^ (c >> 8);

            }

            return c;

        }

        //Return Byte CRC Buffer Zone

        private static uint GetCRC(byte[] buf)

        {

            return UpdateCRC(0xFFFFFFFF, buf, buf.Length) ^ 0xFFFFFFFF;

        }

        private static uint ComputeAdler32(byte[] buf)

        {

            uint s1 = 1;

            uint s2 = 0;

            int length = buf.Length;

            for (int idx = 0; idx < length; idx++)

            {

                s1 = (s1 + (uint)buf[idx]) % _ADLER32_BASE;

                s2 = (s2 + s1) % _ADLER32_BASE;

            }

            return (s2 << 16) + s1;

        }

    }

Two Components Recommend:

Spire.Doc, is used to operate MS Word document for .Net and Silverlight, including basic manipulations (generate, open, edit documents), mail merge and other Word functions manipulations.

Spire.XLS, is used to operate MS Excel for .NET and Silverlight, including basic manipulations (generate, open, edit files), chart creation and data exporting.

Silverlight-DataGrid Row Detailed Information Binding-DataGrid.RowDetailsTemplate

If we want to click one row and view details of this row when using DataGrid in Silverlight, how should we do? Additionally, this deatailed information includes several rows of data, not just several properties.

We use DataGrid.DetailsTemplate to set or get detailed information. Firstly, name A for one DataGrid and set RowDetailsVisibilityMode = “WisibleWhenSelected” (The display mode of details template is to unfold the detailed information when the row is selected.). Then set DataGrid.RowDetailsTemplate for A and add another DataGrid B. Also, set an entity set AList to bind DataGrid A.In AList, there is one property BList, which is the multiple row details. Then, bind BList detail fields to ItemSource of DataGrid B.

<Gridx:Name=”LayoutRoot”Background=”White”>

<! —aThere is one DataGrid,its DataGrid.RowDetailsTemplate will be bound to another DataGrid to display detailed information.–>

<sdk:DataGridx:Name=”gridEmployee”CanUserReorderColumns=”False”CanUserSortColumns=”False”RowDetailsVisibilityMode=”VisibleWhenSelected”HorizontalAlignment=”Center”ScrollViewer.VerticalScrollBarVisibility=”Auto”Height=”200″ AutoGenerateColumns=”False”Width=”422″VerticalAlignment=”Center”>

<sdk:DataGrid.Columns>

<sdk:DataGridTextColumnWidth=”150″Header=”User Name”Binding=”{BindingUserName}”/>

<sdk:DataGridTextColumnWidth=”150″Header=”User Password”Binding=”{BindingUserPwd}”/>

</sdk:DataGrid.Columns>

<sdk:DataGrid.RowDetailsTemplate>

<DataTemplate>

<! —aThere is the other DataGrid detailed information.>

<sdk:DataGrid AutoGenerateColumns=”False”ItemsSource=”{BindingUserDetailInfomation}”HeadersVisibility=”None”>

<sdk:DataGrid.Columns>

<sdk:DataGridTextColumnWidth=”100″Header=”Address”Binding=”{BindingUserAddress}”/>

<sdk:DataGridTextColumnWidth=”100″Header=”City”Binding=”{BindingUserCity}”/>

<sdk:DataGridTextColumnWidth=”100″Header=”Country”Binding=”{BindingUserCountry}”/>

<sdk:DataGridTextColumnWidth=”100″Header=”State”Binding=”{BindingUserState}”/>

</sdk:DataGrid.Columns>

</sdk:DataGrid>

</DataTemplate>

</sdk:DataGrid.RowDetailsTemplate>

</sdk:DataGrid>

</Grid>

DataSource XAML.cs code:

    public partial class MainPage : UserControl

    {

        public MainPage()

        {

            InitializeComponent();

            this.gridEmployee.ItemsSource = new UserInfo().GetEmployeeData();

        }

    }

    ///<summary>

    ///User Information

    ///</summary>

    public class UserInfo

    {

        public string UserName { get; set; }

        public string UserPwd { get; set; }

        ///<summary>

        ///User Detailed Information

        ///</summary>

        public List<UserDetailInfo> UserDetailInfomation{get;set;}

        public UserInfo()

        { }

        ///<summary>

        ///Get User Information Instance

        ///</summary>

        ///<returns></returns>

        public List<UserInfo> GetEmployeeData()

        {

            List<UserInfo> employees = new List<UserInfo>();

            employees.Add

                (

                new UserInfo

                {

                    UserName = “Joe”,

                    UserPwd = “1234567”,

                    UserDetailInfomation = new List<UserDetailInfo>()

                    {

                        new UserDetailInfo()

                        {

                            UserAddress=“Anchorage, Alaska”,

                            UserCity=“Anchorage”,

                            UserCountry=“America”,

                            UserState=“Alaska”

                        },

                        new UserDetailInfo()

                        {

                            UserAddress=“Denver, Colorado”,

                            UserCity=“Denver”,

                            UserCountry=“America”,

                            UserState=“Colorado”

                        }

                    }

                });

            employees.Add

                (

                new UserInfo

                {

                    UserName = “Json”,

                    UserPwd = “json282”,

                    UserDetailInfomation = new List<UserDetailInfo>()

                    {

                        new UserDetailInfo()

                        {

                            UserAddress=“Hartford, Connecticut”,

                            UserCity=“Hartford”,

                            UserCountry=“America”,

                            UserState=“Connecticut”

                        },

                        new UserDetailInfo()

                        {

                            UserAddress=“Dover, Delaware”,

                            UserCity=“Dover”,

                            UserCountry=“America”,

                            UserState=“Delaware”

                        }

                    }

                });

            employees.Add

                (

                new UserInfo

                {

                    UserName = “Lisa”,

                    UserPwd = “lilisasa”,

                    UserDetailInfomation = new List<UserDetailInfo>()

                    {

                        new UserDetailInfo()

                        {

                            UserAddress=“Tampa, Florida”,

                            UserCity=“Tampa”,

                            UserCountry=“America”,

                            UserState=“Florida”

                        },

                        new UserDetailInfo()

                        {

                            UserAddress=“Gainesville, Florida”,

                            UserCity=“Gainesville”,

                            UserCountry=“America”,

                            UserState=“Florida”

                        }

                    }

                });

            return employees;

        }

    }

    ///<summary>

    ///User Detailed Information Entity

    ///</summary>

    public class UserDetailInfo

    {

        public string UserAddress { get; set; }

        public string UserCity { get; set; }

        public string UserState { get; set; }

        public string UserCountry { get; set; }

    }

Two Components Recommend:

Spire.Doc, is used to operate MS Word document for .Net and Silverlight, including basic manipulations (generate, open, edit documents), mail merge and other Word functions manipulations.

Spire.XLS, is used to operate MS Excel for .NET and Silverlight, including basic manipulations (generate, open, edit files), chart creation and data exporting.