European Silverlight 4 & Silverlight 5 Hosting BLOG

BLOG about Silverlight 5 Hosting and Its Techologies - Dedicated to European Windows Hosting Customer

European Silverlight 6 Hosting - HostForLIFE.eu :: Updating the XAP Configuration Programmatically

clock August 23, 2018 11:30 by author Peter

One of the bigger annoyances dealing with programming in Silverlight 6 is the deployment of XAP files. In order to properly update a XAP file you typically:

1. Rename XAP file to a ZIP file.

2. Extract the ServiceReferences.ClientConfig file.

3. Update the configuration file with the proper IP information.

4. Update the ZIP file and save.

5. Rename ZIP file back to XAP.

So, how do we do that with code so we can skip this frustration? Let’s first look at a few factors:

We are using the .Net 4.0 Framework. Don’t bother using System.IO.Packaging.ZipPackage. It thinks XAP files are always corrupt. It’s annoying. We are just updating the IP information. First, let’s look at how we update the configuration file if it was committed to a MemoryStream. In this snippet we:

1. Grab all the contents from the MemoryStream.

2. Replace the IP information in the content.

3. Clear the MemoryStream.

4. Overwrite the stream contents with the new content.

5. Reset the position in the stream to 0.

/// <summary>
/// Updates the configuration file
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="replacementIp">The replacement ip.</param>
/// <param name="destinationIp">The destination ip.</param>
/// <returns></returns>
private bool UpdateConfigurationFile(MemoryStream stream,
    string replacementIp, string destinationIp)
{
    bool isSuccessful = false;
    try
    {
        // Read current file
        var reader = new StreamReader(stream);
        stream.Position = 0;
        var contents = reader.ReadToEnd();       
        // Update IP information
        var newContents = contents.Replace(replacementIp, destinationIp);
        // Reset contents of stream
        stream.SetLength(0);
        // Overwrite original configuration file
        var writer = new StreamWriter(stream);
        writer.Write(newContents);
        writer.Flush();
        // Set position in stream to 0.
        // This allows us to start writing from the beginning of the stream.
        stream.Seek(0, SeekOrigin.Begin);
        // Success
        isSuccessful = true;
    }
    catch (Exception)
    {
    }
    // return
    return isSuccessful;
}

Our main method below does this:

- Extract the ServiceReferences.ClientConfig file.
- Call the UpdateConfigurationFile method above to revise the IP information.
-  Update the ZIP file and commit the changes.
/// <summary>
/// Updates the silverlight configuration file.
/// </summary>
/// <param name="configFileName">Name of the config file.</param>
/// <param name="xapFilePath">The xap file path.</param>
/// <param name="replacementIp">The replacement ip.</param>
/// <param name="destinationIp">The destination ip.</param>
/// <returns></returns>
private bool UpdateSilverlightConfigurationFile(string configFileName,
    string xapFilePath, string replacementIp, string destinationIp)
 {
    // Check file path
    if (!File.Exists(xapFilePath)) { return false; }
    // Open XAP and modify configuration
   using (var zip = ZipFile.Read(xapFilePath))
    {
        // Get config file
        var entry = zip[configFileName];
        var stream = new MemoryStream();
        entry.Extract(stream);
        // Manipulate configuration
        var updated =
            UpdateConfigurationFile(stream, replacementIp, destinationIp);
        // Evaluate
        if (updated)
        {
            // Replace existing configuration file in XAP
            zip.UpdateEntry(configFileName, stream);
            zip.Save();
        }
    }
    // return
    return true;
}

So, let’s look at the code in it’s entirety so that we get an implementation example as well as the needed includes:
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Ionic.Zip;
namespace XAPFileUpdaterTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            // Intialize UI
            InitializeComponent();
            // Parameters
            string configFile = "ServiceReferences.ClientConfig";
            string xap = @"MyAwesomeApp.xap";
            string replacementIp = "127.0.0.1";
            string destinationIp = "12.23.45.67";
             // Check
            var isClientConfigUpdated =
                UpdateSilverlightConfigurationFile(
                   configFile, xap, replacementIp, destinationIp); 
            // Setup message
            var message =
                (isClientConfigUpdated) ? "was successful" : "failed"; 
            // Notify user
            MessageBox.Show("The current update " + message);
        }
        /// <summary>
        /// Updates the configuration file.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="replacementIp">The replacement ip.</param>
        /// <param name="destinationIp">The destination ip.</param>
        /// <returns></returns>
        private bool UpdateConfigurationFile(MemoryStream stream,
            string replacementIp, string destinationIp)
        {
            bool isSuccessful = false;
           try
            {
                // Read current file
                var reader = new StreamReader(stream);
                stream.Position = 0;
                var contents = reader.ReadToEnd();
                // Update IP information
                var newContents = contents.Replace(replacementIp, destinationIp);
                // Reset contents of stream
                stream.SetLength(0);
                // Overwrite original configuration file
                var writer = new StreamWriter(stream);
                writer.Write(newContents);
                writer.Flush();
                // Set position in stream to 0.
                // This allows us to start writing from the beginning of the stream.
                stream.Seek(0, SeekOrigin.Begin);
                // Success
                isSuccessful = true;
            }
            catch (Exception)
            {
            }
            // return
            return isSuccessful;
        }
        /// <summary>
        /// Updates the silverlight configuration file.
        /// </summary>
        /// <param name="configFileName">Name of the config file.</param>
        /// <param name="xapFilePath">The xap file path.</param>
        /// <param name="replacementIp">The replacement ip.</param>
        /// <param name="destinationIp">The destination ip.</param>
        /// <returns></returns>
        private bool UpdateSilverlightConfigurationFile(string configFileName,
            string xapFilePath, string replacementIp, string destinationIp)
        {
            // Check file path
            if (!File.Exists(xapFilePath)) { return false; } 
            // Open XAP and modify configuration
            using (var zip = ZipFile.Read(xapFilePath))
            {
                // Get config file
                var entry = zip[configFileName];
               var stream = new MemoryStream();
                entry.Extract(stream);
                // Manipulate configuration
                var updated =
                    UpdateConfigurationFile(stream, replacementIp, destinationIp);
                // Evaluate
                if (updated)
                {
                    // Replace existing configuration file in XAP
                    zip.UpdateEntry(configFileName, stream);
                    zip.Save();
                }
            }
           // return
            return true;
        }
    }
}

That’s all for now. I hope I helped you with this annoyance.



European Silverlight 6 Hosting - HostForLIFE.eu :: Tic Tac Toe, Silverlight Drawing Basics

clock August 16, 2018 11:32 by author Peter

Silverlight is being on high recognition in the industry and it is really cool! In this article I am trying to create a marker control that allows the user to mark certain areas on the image canvas.  This will work as the drawing board for our Tic Tac Toe game.  We can see the usage of Canvas and its Children property applied with the Line class.

The application provides with a layer of buttons on choosing the pen, eraser or the color selector.  The board is represented by a Canvas class.

Canvas
In this application, the Canvas instance serves as our main drawing board.  The canvas is named BoardCanvas.  The drawings over the canvas are captured as Line objects and added to the Children property of the canvas.  The Children property accepts of type UIElement.

Line
The Line instances are used whenever the user marks over the board.  For each stroke a number of line objects are created to represent the stroke.  The user can choose two colors from the screen.
Repeating  that the line objects are created and added to the Children property of the canvas.

Delete
The delete functionality allows the user to delete the line under mouse cursor position.  This helps the user to remove an unwanted line.

The functionality is implemented by taking the mouse X, Y position and parsing through the line collection.  Each line's X, Y will be checked with the mouse positions and if a match found, the line is deleted from the canvas object.

Clear
There is a Clear button on the screen that will clear the board canvas. This will quickly help the user to restart the game.

The functionality is implemented by clearing all the lines from the canvas Children property.

Functionality Explained

The enumeration Mode is used to represent the active drawing mode of the application.  When the application starts, the default mode will be Draw.
public enum Mode
{
    None,
    Draw,
    Delete
}

When the user presses the Pen button, the mode will be set to Draw.

private void PenButton_Click(object sender, RoutedEventArgs e)
{
    _mode = Mode.Draw;
}


When the user presses the Delete button, the mode will be set to Delete.
private void Delete_Click(object sender, RoutedEventArgs e)
{
    _mode = Mode.Erase;
}

When the user presses, the Clear button, there is no mode change – the ClearAll() method is called.  The ClearAll() method will clear the Children property of the canvas and resets the mode to Draw. There is a private variable _lines which is used to hold all the lines of the drawing.
private void ClearAll()
{
    foreach (Line line in _lines)
        BoardCanvas.Children.Remove(line);
    _lines.Clear();
    _mode = Mode.Draw;
}



European Silverlight 6 Hosting - HostForLIFE.eu :: Using Static Resource in Silverlight

clock August 9, 2018 09:19 by author Peter

In this article we will discuss more about using and managing Static Resource in Silverlight. Static Resource is nothing but a Resource which is defined and cannot be changed but can be used multiple times.

Steps to Bind Static Resource
Define the respective Namespaces
Define the instance in ResourceDictionary and give a name to it's x:key
To Bind to it, use the {StaticResource} markup extension.

Binding to a Static Resource of Simple String
Create a Silverlight Application and add two TextBoxes.

In the xaml code behind add the namespace:
xmlns:sys="clr-namespace:System;assembly=mscorlib"

Now add a String resource as described below:
<UserControl.Resources>
    <sys:String x:Key="SingleString">Hello World</sys:String>
</UserControl.Resources>


As we discussed earlier it can be used multiple number of times. We will use it in both TextBoxes:
<Grid>
  <TextBlock Margin="0,0"
             Text="{Binding Source={StaticResource SingleString}}" />
  <TextBlock  Margin="0,16" Text="{Binding Source={StaticResource SingleString}, Path=Length}"/>
</Grid>


Path is an attribute using which we can refer to a property of Static Resource.
Binding to a Static Resource of a single instance of a Custom Class
Create a Silverlight Application and add a class; name it as Users.cs.

Now define the class using the following properties:
public class Users
{
public string FirstName { get; set; }
public string LastName { get; set; }}


To use it in xaml first define the namespace:
xmlns:local="clr-namespace:StaticResourceSL3"

And then add the resources as follows:
<UserControl.Resources>
    <local:Users x:Key="SingleUser" FirstName="Diptimaya" LastName="Patra"/>
</UserControl.Resources>


To bind it to follow the earlier instructions and use Path attribute to use the property:
<TextBlock Text="{Binding Source={StaticResource SingleUser}, Path=FirstName}"/>

Binding to a Static Resource of a Collection of Custom Instances

We will follow the above example i.e. we will use the same class Users.cs. We will add another class called UserList which will inherit List of Users. As follows:
public class Users
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class UsersList : List<Users>
{
public UsersList
{
this.Add(new Users() { FirstName = "John", LastName = "Lock"});
this.Add(new Users() { FirstName = "James", LastName = "Soyer"});
this.Add(new Users() { FirstName = "Jack", LastName = "Sephered"});
}}


As usual add the namespace to have a reference of the class.

Now add the Resources to xaml code behind:
Before that refer to this assembly.
xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
<UserControl.Resources>
<local:UsersList x:Key="UsersList"/></UserControl.Resources>


Now bind the Static Resource to a ListBox's ItemSource as follows:
<ListBox  Margin="0,135,0,50" ItemsSource="{StaticResource UsersList }"/>

Or you can bind the FirstName attribute as follows:
<ListBox  Margin="0,60,0,120" >
<ListBox.ItemsSource>
        <Binding Source="{StaticResource somePersons}" />
</ListBox.ItemsSource>
        <ListBox.ItemTemplate>
                    <DataTemplate>
<TextBlock Text="{Binding Path=FirstName}"></TextBlock>
                     </DataTemplate>
        </ListBox.ItemTemplate>
</ListBox>


Binding to a Static Resource of a Collection of Strings

Now assume that you need a collection of strings to be added to a ListBox or to a AutoCompleteBox, how will you do it:

Create a class and name it as ObjectCollection and add the following constructors:
public partial class ObjectCollection : Collection<object>
{
public ObjectCollection()
{
}
public ObjectCollection(IEnumerable collection)

{
  foreach (object obj in collection)
 {
    Add(obj);
 }
}
}

Now in xaml code behind add the Resources as follows:
<UserControl.Resources>
 <controls:ObjectCollection x:Key="SampleData">
    <sys:String>User 1</sys:String>
    <sys:String>User 2</sys:String>
    <sys:String>User 3</sys:String>
 </controls:ObjectCollection>
</UserControl.Resources>


Now you can use it as the ItemSource of a ListBox or AutoCompleteBox or others:
<ListBox  Margin="0,135,0,50" ItemsSource="{StaticResource SampleData}"/>
That's it you have successfully used Static Resources



European Silverlight 6 Hosting - HostForLIFE.eu :: Silverlight UserControl Custom Property Binding

clock August 7, 2018 12:00 by author Peter

In this article we will be seeing how to create a Custom Silverlight UserControl and Binding the Property. We will use a dependency Property in this example.

Created a Project as SamplePro.
Added an a new User Control as MyNewControl.

Dependency Property:
Now let's add a dependency property. To know more about DP, check out this site:
http://msdn.microsoft.com/en-us/library/cc221408(v=vs.95).aspx

My dependency property code looks as follows:
//  Dependency Property - Begin
        public const string DisplayTextPropertyName = "DisplayText";
        public string DisplayText
        {
            get
            {
                return (string)GetValue(DisplayTextProperty);
            }
            set
            {
                SetValue(DisplayTextProperty, value);
            }
        }
        public static readonly DependencyProperty DisplayTextProperty = DependencyProperty.Register(
DisplayTextPropertyName,typeof(string), typeof(MyNewControl),new PropertyMetadata(String.Empty));
//  Dependency Property - End


The UserControl MyNewControl looks as below:
public partial class MyNewControl : UserControl
    {
//  Dependency Property - Begin
        public const string DisplayTextPropertyName = "DisplayText";
        public string DisplayText
        {
            get
            {
                return (string)GetValue(DisplayTextProperty);
            }
            set
            {
                SetValue(DisplayTextProperty, value);
            }
        }
        public static readonly DependencyProperty DisplayTextProperty = DependencyProperty.Register(
DisplayTextPropertyName,typeof(string), typeof(MyNewControl),new PropertyMetadata(String.Empty));
//  Dependency Property - End
        public MyNewControl()
        {
            InitializeComponent();
            btn.SetBinding(Button.ContentProperty, new Binding() { Source = this, Path = new PropertyPath("DisplayText"), Mode = BindingMode.TwoWay });
        }
    }


MyNewControl is ready for use as shown below:
<UserControl x:Class="SamplePro.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:SamplePro"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
        <local:MyNewControl Width="300" Height="300"  Foreground="Black" x:Name="newcontrol" DisplayText="Hit Me Now !!!"> </local:MyNewControl>
    </Grid>
</UserControl>


Let's give it a run:



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in