It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

Building custom user control in Silverlight 2.0 + how to build code snippet for VS as bonus

Do you remember, that we have "go-live" for Silverlight 2.0 and already have build machines configured? Now it’s time to build your very own custom control. Today, we’ll build Range Slider.

image

What is range slider? Range slider is a control, that lets you input two values, typically an upper and a lower bound. Normal slider just lets you input one value. So, we have new behavior here, thus we’ll have to build our own control without reusing existing one.

But, before we’ll start, we’ll build code snippet for Visual Studio, that allows us quickly build Dependency Property. Due to fact, that existing snippets (propdp, etc) do not fit Silverlight DP creation pattern. In Silverlight, we have no DependencyPropertyMetadata, so the registration pattern will be

DependencyProperty.Register(
                  "$property$",
                  typeof($type$),
                  typeof($ownerclass$),
                  On$property$PropertyChanged);

Open new XML file, read this and let’s start. First of all, general stuff line who am I, what’s the short string for the snippet, etc.

<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>Define a DependencyProperty for Silverlight application</Title>
      <Shortcut>propds</Shortcut>
      <Description>
        Code snippet for a property using DependencyProperty as the backing store and a Handler for the DependencyPropertyChanged event
      </Description>
      <Author>Tamir Khason</Author>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>type</ID>
          <ToolTip>Property Type</ToolTip>
          <Default>int</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="true">
          <ID>property</ID>
          <ToolTip>Property Name</ToolTip>
          <Default>MyProperty</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="false">
          <ID>ownerclass</ID>
          <ToolTip>
            The owning class of this Property. Typically the class that it is declared in.
          </ToolTip>
          <Default>ClassNamePlaceholder</Default>
          <Function>ClassName()</Function>
        </Literal>
      </Declarations>

Then the interesting stuff. Where my properties and variables.

<Code Language="csharp">
        <![CDATA[
#region $property$

/// <summary>
/// Gets or sets the $property$ possible Value of the $type$ object.
/// </summary>
public $type$ $property$
{
    get { return ($type$)GetValue($property$Property); }
    set { SetValue($property$Property, value); }
}

/// <summary>
/// Identifies the $property$ dependency property.
/// </summary>
public static readonly DependencyProperty $property$Property =
            DependencyProperty.Register(
                  "$property$",
                  typeof($type$),
                  typeof($ownerclass$),
                  On$property$PropertyChanged);

/// <summary>
/// $property$Property property changed handler.
/// </summary>
/// <param name="d">$ownerclass$ that changed its $property$.</param>
/// <param name="e">DependencyPropertyChangedEventArgs.</param>
private static void On$property$PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  $ownerclass$ _$ownerclass$ = d as $ownerclass$;
  if (_$ownerclass$!=null)
  {
    //TODO: Handle new value.
  }
}
#endregion $property$
$end$]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

We done, you can either download the ready snippet for Silverlight Dependency Property creation here. All you have to do is to put it into %MY DOCUMENTS%\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets or \Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C# directory. Now, we can use "propdps" to quickly define Dependency Property for Silverlight class.

Well done, and now we can start writing. First of all, we’ll create base logic class to encapsulate Minimum, Maximum, ValueLow, ValueHigh properties and ValueChange routed events. The only object we can derive from in order to use Dependency Property is Control. So we’ll do it.

public abstract class DoubleRangeBase : Control
    {

Building Minimum property…

#region Minimum

        /// <summary>
        /// Gets or sets the Minimum possible Value of the double object.
        /// </summary>
        public double Minimum
        {
            get { return (double)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }

        /// <summary>
        /// Identifies the Minimum dependency property.
        /// </summary>
        public static readonly DependencyProperty MinimumProperty =
                    DependencyProperty.Register(
                          "Minimum",
                          typeof(double),
                          typeof(DoubleRangeBase),
                          OnMinimumChanged);

        /// <summary>
        /// MinimumProperty property changed handler.
        /// </summary>
        /// <param name="d">LowHighRangeBase that changed its Minimum.</param>
        /// <param name="e">DependencyPropertyChangedEventArgs.</param>
        private static void OnMinimumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DoubleRangeBase _LowHighRangeBase = d as DoubleRangeBase;
            if (_LowHighRangeBase != null)
            {
                _LowHighRangeBase._requestedMin = (double)e.NewValue;
                _LowHighRangeBase.CoerceMaximum();
                _LowHighRangeBase.CoerceValues();
                _LowHighRangeBase.OnMinimumChanged((double)e.OldValue, (double)e.NewValue);    
            }
        }
        #endregion

Isn’t it nice snippet? :) Now events

public event RoutedPropertyChangedEventHandler<double> ValueLowChanged;
public event RoutedPropertyChangedEventHandler<double> ValueHighChanged;
public event RoutedPropertyChangedEventHandler<ValueChangedEventArgs> ValueChanged;

Handlers… Some virtual and some not

protected virtual void OnMaximumChanged(double oldMaximum, double newMaximum)
        {
        }

protected virtual void OnValueChanged(double oldValue, double newValue, ValueChangeType type)
        {
            RoutedPropertyChangedEventHandler<ValueChangedEventArgs> handler = ValueChanged;
            if (handler != null)
            {
                ValueChangedEventArgs oVal = new ValueChangedEventArgs(oldValue,type);
                ValueChangedEventArgs nVal = new ValueChangedEventArgs(newValue, type);
                handler(this, new RoutedPropertyChangedEventArgs<ValueChangedEventArgs>(oVal, nVal));
            }
        }

Coerces (that we missing in Silverlight, and as for my, this approach much better, then lazy counters, used in extended Silverlight controls)…

private void CoerceValues()
        {
            // Ensure it’s a valid value
            if (!IsValidDoubleValue(_requestedValueLow) | !IsValidDoubleValue(_requestedValueHigh) | !IsValidDoubleValue(_requestedMax) | !IsValidDoubleValue(_requestedMin))
            {
                throw new ArgumentException("Invalid double value", MinimumProperty.ToString());
            }

            double minimum = Minimum;
            double maximum = Maximum;
            double valueHigh = ValueHigh;
            double valueLow = ValueLow;

            if (valueHigh < minimum)
            {
                SetValue(ValueHighProperty, minimum);
                return;
            }
            if (valueHigh > maximum)
            {
                SetValue(ValueHighProperty, maximum);
                return;
            }

            if (valueLow < minimum)
            {
                SetValue(ValueLowProperty, minimum);
                return;
            }
            if (valueLow > maximum)
            {
                SetValue(ValueLowProperty, maximum);
                return;
            }

            if (_requestedValueHigh < valueLow)
                _requestedValueHigh = valueLow;

            if (_requestedValueHigh > maximum)
                _requestedValueHigh = maximum;

            if (_requestedValueHigh < minimum)
                _requestedValueHigh = minimum;

            if (_requestedValueHigh != valueHigh)
            {
                SetValue(ValueHighProperty, _requestedValueHigh);
                return;
            }

            if (_requestedValueLow > valueHigh)
                _requestedValueLow = valueHigh;

            if (_requestedValueLow > maximum)
                _requestedValueLow = maximum;

            if (_requestedValueLow < minimum)
                _requestedValueLow = minimum;

            if (_requestedValueLow != valueLow)
            {
                SetValue(ValueLowProperty, _requestedValueLow);
                return;
            }

        }

And we done… Now the turn of the original class. We want to be able to template it, so, let’s add first generic.xaml with control template of our range slider. This is pretty simple, but there are some chatchus with it. One, you should explicitly specify the assembly, your control resides in. Another, that implicit styles do not work in Silverlight, so you should specify it. Other stuff is rather similar to WPF (even namespace)

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:Sharpsoft.Controls;assembly=Sharpsoft.Controls"
    >

….

<Grid x:Name="HorizontalTemplateElement">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <!– Track Layer –>
                            <Rectangle Stroke="Black" StrokeThickness="0.5" Fill="{TemplateBinding BackBrush}" Grid.Column="0" Grid.ColumnSpan="5" Height="3" Margin="5,0,5,0" />

                            <!– Fillters + Thumb –>
                            <Rectangle x:Name="HorizontalLowFillerElement" Fill="Transparent" Grid.Column="0" Height="3" />
                            <Thumb Style="{TemplateBinding ThumbStyle}" x:Name="HorizontalLowThumbElement" Grid.Column="1"/>
                            <Rectangle x:Name="HorizontalCenterFillerElement" Fill="{TemplateBinding SelectionBrush}" Grid.Column="2" Height="3" />
                            <Thumb Style="{TemplateBinding ThumbStyle}" x:Name="HorizontalHighThumbElement" Grid.Column="3" />
                            <Rectangle x:Name="HorizontalHighFillerElement" Fill="Transparent" Grid.Column="4" Height="3" />
                        </Grid>

We want to be able to change an orientation of the range slider, so adding another section for vertical alignment.

<Grid x:Name="VerticalTemplateElement" Visibility="Collapsed">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>

                            <!– Track Layer –>
                            <Rectangle Stroke="Black" StrokeThickness="0.5" Fill="{TemplateBinding BackBrush}" Grid.Row="0" Grid.RowSpan="5" Width="3" Margin="0,5,0,5" />

                            <!– Fillters + Thumb –>
                            <Rectangle x:Name="VerticalLowFillerElement" Grid.Row="4" Width="3" />
                            <Thumb Style="{TemplateBinding ThumbStyle}" x:Name="VerticalLowThumbElement" Grid.Row="3" />
                            <Rectangle x:Name="VerticalCenterFillerElement" Fill="{TemplateBinding SelectionBrush}" Grid.Row="2" Width="3" />
                            <Thumb Style="{TemplateBinding ThumbStyle}" x:Name="VerticalHighThumbElement" Grid.Row="1" />
                            <Rectangle x:Name="VerticalHighFillerElement" Grid.Row="0" Width="3" />
                        </Grid>

Now, when we done, we can start with the code of the control. Don’t forget about TemplatePart attributes….

[TemplatePart(Name = RangeSlider.ElementHorizontalHighFillerName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RangeSlider.ElementHorizontalLowFillerName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RangeSlider.ElementHorizontalCenterFillerName, Type = typeof(Rectangle))]
    [TemplatePart(Name = RangeSlider.ElementVerticalTemplateName, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = RangeSlider.ElementVerticalLowThumbName, Type = typeof(Thumb))]
    [TemplatePart(Name = RangeSlider.ElementVerticalHighThumbName, Type = typeof(Thumb))]

public class RangeSlider : DoubleRangeBase
    {

Don’t forget to create and register those properties in backend.

/// <summary>
        /// Horizontal low filler
        /// </summary>
        internal virtual Rectangle ElementHorizontalLowFiller { get; set; }
        internal const string ElementHorizontalLowFillerName = "HorizontalLowFillerElement";

        /// <summary>
        /// Vertical template root
        /// </summary>
        internal virtual FrameworkElement ElementVerticalTemplate { get; set; }
        internal const string ElementVerticalTemplateName = "VerticalTemplateElement";

Internally subscribing to mouse and keyboard events in constructor…

public RangeSlider()
        {
            Minimum = 0;
            Maximum = 100;
            ValueHigh = 80;
            ValueLow = 20;

            IsTabStop = true;
            IsEnabled = true;
            Orientation = Orientation.Horizontal;
            GotFocus += delegate { IsFocused = true; };
            LostFocus += delegate { IsFocused = false; };
            KeyDown += delegate(object sender, KeyEventArgs e) { OnKeyPressed(e); };
            MouseEnter += delegate(object sender, MouseEventArgs e) { OnMouseEnter(e); };
            MouseLeave += delegate(object sender, MouseEventArgs e) { OnMouseLeave(e); };
            MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { OnMouseLeftButtonDown(e); };
            MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e) { OnMouseLeftButtonUp(e); };
            SizeChanged += delegate { UpdateTrackLayout(); };
        }

And overriding OnApplyTemplate methods…

protected override void OnApplyTemplate()
       {
           base.OnApplyTemplate();

           ElementRoot = GetTemplateChild(ElementRootName) as FrameworkElement;
           ElementHorizontalTemplate = GetTemplateChild(ElementHorizontalTemplateName) as FrameworkElement;
           ElementHorizontalLowThumb = GetTemplateChild(ElementHorizontalLowThumbName) as Thumb;
           ElementHorizontalHighThumb = GetTemplateChild(ElementHorizontalHighThumbName) as Thumb;
          

Don’t forget about Drag events.

if (ElementHorizontalLowThumb != null)
            {
                ElementHorizontalLowThumb.DragStarted += delegate(object sender, DragStartedEventArgs e) { OnLowThumbDragStarted(e); };
                ElementHorizontalLowThumb.DragDelta += delegate(object sender, DragDeltaEventArgs e) { OnLowThumbDragDelta(e); };
            }

Let’s add some UI related properties like Orientation, IsFocused, IsEnabled, SelectionBrush, BackBrush, etc… Even ThumbStyle (do you remember, it does not work implicitly)

#region ThumbStyle

        /// <summary>
        /// Gets or sets the ThumbStyle possible Value of the Style object.
        /// </summary>
        public Style ThumbStyle
        {
            get { return (Style)GetValue(ThumbStyleProperty); }
            set { SetValue(ThumbStyleProperty, value); }
        }

        /// <summary>
        /// Identifies the ThumbStyle dependency property.
        /// </summary>
        public static readonly DependencyProperty ThumbStyleProperty =
                    DependencyProperty.Register(
                          "ThumbStyle",
                          typeof(Style),
                          typeof(RangeSlider),
                          null);

        #endregion ThumbStyle

Ah, snippets is cool thing! Now we can override virtual methods to handle it

protected override void OnValueHighChanged(double oldValue, double newValue)
       {
           base.OnValueHighChanged(oldValue, newValue);
           if (ElementRoot != null)
           {
               UpdateTrackLayout();
           }
       }

Mouse events

private void OnMouseEnter(MouseEventArgs e)
        {
            e.Handled = true;
            IsMouseOver = true;
            if ((Orientation == Orientation.Horizontal && ElementHorizontalLowThumb != null && !ElementHorizontalLowThumb.IsDragging && ElementHorizontalHighThumb != null && !ElementHorizontalHighThumb.IsDragging) ||
                (Orientation == Orientation.Vertical && ElementVerticalLowThumb != null && !ElementVerticalLowThumb.IsDragging && ElementVerticalHighThumb != null && !ElementVerticalHighThumb.IsDragging))
            {
                UpdateVisualState();
            }
        }

Stubs for possible animations…

internal void ChangeVisualState(Storyboard state)
        {
            Storyboard previousState = _currentState;
            if (state == previousState)
            {
                return;
            }

            if (state != null)
            {
                if (previousState != null)
                {
                    previousState.Stop();
                }
                _currentState = state;
                state.Begin();
            }
        }

And position calculations at the end

private void OnLowThumbDragDelta(DragEventArgs e)
        {
            double offset = 0;

            if (Orientation == Orientation.Horizontal && ElementHorizontalLowThumb != null)
            {
                offset = e.HorizontalOffset / (ActualWidth – ElementHorizontalLowThumb.ActualWidth) * (Maximum – Minimum);
            }
            else if (Orientation == Orientation.Vertical && ElementVerticalLowThumb != null)
            {
                offset = -e.VerticalOffset / (ActualHeight – ElementVerticalLowThumb.ActualHeight) * (Maximum – Minimum);
            }

            if (!double.IsNaN(offset) && !double.IsInfinity(offset))
            {
                _dragValue += IsDirectionReversed ? -offset : offset;

                double newValue = Math.Min(Maximum, Math.Max(Minimum, _dragValue));

                if (newValue != ValueLow)
                {
                    ValueLow = newValue;
                }               
            }
        }

The only thing we have to do is to treat those measurement and layout calculations

protected virtual void UpdateTrackLayout()
        {
            double maximum = Maximum;
            double minimum = Minimum;
            double valueLow = ValueLow;
            double valueHigh = ValueHigh;

            Grid templateGrid = (Orientation == Orientation.Horizontal) ? (ElementHorizontalTemplate as Grid) : (ElementVerticalTemplate as Grid);
            if (templateGrid != null)
            {
                if (Orientation == Orientation.Horizontal && templateGrid.ColumnDefinitions != null &&
                    templateGrid.ColumnDefinitions.Count == 5)
                {
                    templateGrid.ColumnDefinitions[0].Width = new GridLength(1, IsDirectionReversed ? GridUnitType.Star : GridUnitType.Auto);
                    templateGrid.ColumnDefinitions[4].Width = new GridLength(1, IsDirectionReversed ? GridUnitType.Auto : GridUnitType.Star);                   
                }
                else if (Orientation == Orientation.Vertical && templateGrid.RowDefinitions != null &&
                    templateGrid.RowDefinitions.Count == 5)
                {
                    templateGrid.RowDefinitions[0].Height = new GridLength(1, IsDirectionReversed ? GridUnitType.Auto : GridUnitType.Star);
                    templateGrid.RowDefinitions[4].Height = new GridLength(1, IsDirectionReversed ? GridUnitType.Star : GridUnitType.Auto);                   
                }
            }

            if (Orientation == Orientation.Horizontal && ElementHorizontalCenterFiller != null &&
                ElementHorizontalLowFiller != null && ElementHorizontalLowThumb != null &&               
                ElementHorizontalHighFiller != null && ElementHorizontalHighThumb != null)
            {
                ElementHorizontalLowFiller.Width = (valueLow – minimum) * (ActualWidth – ElementHorizontalHighThumb.ActualWidth – ElementHorizontalLowThumb.ActualWidth) / (maximum – minimum);
                ElementHorizontalCenterFiller.Width = (valueHigh – valueLow) * (ActualWidth – ElementHorizontalHighThumb.ActualWidth – ElementHorizontalLowThumb.ActualWidth) / (maximum – minimum);
                ElementHorizontalHighFiller.Width = (maximum – valueHigh) * (ActualWidth – ElementHorizontalHighThumb.ActualWidth – ElementHorizontalLowThumb.ActualWidth) / (maximum – minimum);

            }
            else if (Orientation == Orientation.Vertical && ElementVerticalCenterFiller != null &&
                ElementVerticalLowFiller != null && ElementVerticalLowThumb != null &&
                ElementVerticalHighFiller != null && ElementVerticalHighThumb != null)
            {
                ElementVerticalLowFiller.Height = (valueLow – minimum) * (ActualHeight – ElementVerticalLowThumb.ActualHeight – ElementVerticalHighThumb.ActualHeight) / (maximum – minimum);
                ElementVerticalCenterFiller.Height = (valueHigh – valueLow) * (ActualHeight – ElementVerticalLowThumb.ActualHeight – ElementVerticalHighThumb.ActualHeight) / (maximum – minimum);
                ElementVerticalHighFiller.Height = (maximum – valueHigh) * (ActualHeight – ElementVerticalLowThumb.ActualHeight – ElementVerticalHighThumb.ActualHeight) / (maximum – minimum);
            }
        }

…and we done.

Now we can do to our Silverlight project and add the control there. something like this will work

<c:RangeSlider
            ValueHigh="{Binding Value1, Mode=TwoWay}"
            ValueLow="{Binding Value2, Mode=TwoWay}"
            Minimum="50"
            Maximum="250"
            SelectionBrush="Red"
            BackBrush="Blue"
            ThumbStyle="{StaticResource thumb}"
            Grid.ColumnSpan="2"
            />

<c:RangeSlider
            ValueHigh="{Binding Value1, Mode=TwoWay}"
            ValueLow="{Binding Value2, Mode=TwoWay}"
            Grid.RowSpan="3"
            Grid.Column="2"
            Orientation="Vertical"
            />

Of cause you need data in backend to bind to. Silverlight does not support ElementName in binding by now. Thus, you should work with object bindings only.

public class MyObject : INotifyPropertyChanged
    {
        double val1, val2;
        public double Value1 { get { return val1; } set { val1 = value; fireChanged("Value1"); } }
        public double Value2 { get { return val2; } set { val2 = value; fireChanged("Value2"); } }

        #region INotifyPropertyChanged Members

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

        #endregion
    }

As exposed thumb style property, so why not to create cool thumb as well?

<UserControl.Resources>
    <l:MyObject x:Name="obj"/>
    <Style TargetType="Thumb" x:Key="thumb">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Thumb">
                    <Path Data="M3,1 L2,2 L1,1 L2,3 z" Stretch="Fill" Fill="Yellow" Stroke="Black"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Width" Value="20"/>
        <Setter Property="Height" Value="20"/>
    </Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource obj}">

And that it. Now we have out range slider up and working. (You cannot see it from your feed reader. Visit the original page to view)

And the small tip at the end. If you want to register Silverlight MIME extension in your IIS (webhosting, etc), you should use application\x-silverlight-app application type for .xap file extensions.

Have a nice day and be good people.

Source code for this article.

MSBuild tasks for build machines for WPF and Silverlight

Silverlight got go-life, so we should start preparing automatic build machines for new Silverlight projects. Actually, it is not too complicated, however, there are some new tasks should be taken into account.

  • Output type of any Silverlight application is Library
  • New XML node specializing the output type of the library: SilverlightApplication with True value
  • Another XML node, that specializing the output file type XapOutputs with True value. XAP is, actually, ZIP archive of all assemblies, used within the application.
  • XAP file name can be set with XapFilename property
  • We can decide whither create Silverlight manifest file or not with GenerateSilverlightManifest tag (true)
  • The template of the manifest for generation resides in SilverlightManifestTemplate tag, so you can specify the path to xml file for manifest generation&nbsp;
  • The entry point of your application should be set with SilverlightAppEntry property, that specifying the name of class (for most cases it will be $(AppName).App)
  • You can tell the enviroment to generate test web page, hosting your Silverlight control by specifying CreateTestPage=true
  • If you decided to generate test file, you should specify the test page name by setting TestPageFileName

There are some new constants for compile conditions

  • DebugType – the type of debug symbols. Instead of general “full”, you should specify “pdbonly” value.
  • NoStdLib defines inclusion of standard libraries with the project (kind of “always copy”). Default = true (not include)
  • NoConfig defines inclusion of config data. Default = true (not include)

Reference set for standard Silverlight application is

  • System.Windows
  • mscorlib
  • system
  • System.Core
  • System.Xml
  • System.Windows.Browser
  • System.Windows.Controls

Those are not standard .NET classes, but special Silverlight dlls, resides in \Program Files\Microsoft Silverlight directory

You can also include your own references by setting Private node of Reference to true. Here the example of such include for Silverlight Extended controls

<Reference Include=”System.Windows.Controls.Extended”>
<Private>True</Private>
</Reference>

ItemGroup section is rather standard, except of new node SilverlightPage (uses standard MSBuild:CompileXaml generator.

That’s all, folks. Happy build machines to you.

Silverlight 2.0 beta 1 is alive – how to use it now?

As you, probably, know, Silverlight 2.0 got “non-commercial” go-live and how you can start using it for real. But how to do it? Let try to understand.

First of all, you have to remove all previous versions of Silverlight as well as remove Silverlight Alpha tools for Visual Studio. Then, install Runtime andm using chain installer, get Visual Studio 2008 tools for Silverlight 2.0 beta 1. I installs SDK, but does not install documentation. You can get it offline here. If everything went well, you’ll have version 2.0.30226.2 installed. As well as inside Visual Studio 2008, you’ll get new project type, named Silverlight.

Now, when we have the installation, our next step will be to understand changes in syntax and build one sample program.

First thing, we’ll do will be creation of DependencyObject.

public class MyObject : DependencyObject    {       
    public string Title        {           
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }        }
   
    public static readonly DependencyProperty TitleProperty
=            DependencyProperty.Register(“Title”, typeof(string),
typeof(MyObject), OnTitlePropertyChanged);

    static void OnTitlePropertyChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)        { }   
}

So far so good, but if you’ll try to compile it, you’ll get following error: “Error&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; The type ‘System.Windows.DependencyObject’ has no constructors defined“. What is it? This is beta! In Silverlight 2.0 beta 1, the only object you may directly derrive from is UserControl. So, let’s change out MyObject class to inherit from UserControl. Not very nice, but we have no chance.

Now the turn of collection. We can derrive from IList&lt;T&gt; or ICollection&lt;T&gt;, so let’s write some code.

public class MyCollection : ObservableCollection<MyObject>
    {
        public MyCollection()
        {
            for (int i = 0; i < 10; i++)
            {
                MyObject o = new MyObject();
                o.Title = string.Format(“Item {0}”, i);
                base.Add(o);
            }
        }
    }

You should also put it into resources, so inside you Page1.xaml, we’ll add following lines.

xmlns:l=”clr-namespace:SilverlightApplication1″
    Width=”400″ Height=”300″>
    <UserControl.Resources>
        <l:MyCollection x:Key=”collection”/>
    </UserControl.Resources>

Dont’t it looks like WPF? It really is! Let’s see if binding works the same way as in WPF

<Grid x:Name=”LayoutRoot” Background=”White”>
            <ListBox ItemsSource=”{Binding Source={StaticResource collection}}”/>
    </Grid>

Compile and run – see nothing? There is a reason for it. If you’ll change the collection to well-known type collection (e.g. string), you’ll see the result. Now you see nothing, ‘cos you have no DataTemplate (for some reason reflected type does not appear as well – nu, shojn, beta :) ). So, now we know, that we need DataTemplate. Let’s do it

<UserControl.Resources>
        <l:MyCollection x:Key=”collection”/>
        <DataTemplate x:Key=”template”>
            <TextBlock Text=”{Binding Title}”/>
        </DataTemplate>
    </UserControl.Resources>
    <Grid x:Name=”LayoutRoot” Background=”White”>
        <ListBox
            ItemTemplate=”{StaticResource template}”
            ItemsSource=”{Binding Source={StaticResource collection}}”/>
    </Grid>

Very well. We have simple ListBox, binded to underlying data source. As alternative, you can use DisplayMemberPath=”Title” (in our case) to visualize simple data item



So far, so good. Let’s add buttons and handlers to our sample program.
First let’s create markup for the root grid

<Grid x:Name=”LayoutRoot” Background=”White”>
        <Grid.RowDefinitions>
            <RowDefinition Height=”*”/>
            <RowDefinition Height=”*”/>
        </Grid.RowDefinitions>

Next, put StackPanel and two buttons inside it.

<StackPanel Grid.Row=”1″ >
            <Button x:Name=”addButton” Content=”Add Item” Click=”Button_Click”/>
            <Button x:Name=”removeButton” Content=”Remove Item” Click=”Button_Click”/>
    </StackPanel>

And at the end, handlers for those buttons

private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyCollection coll = Resources["collection"] as MyCollection;
            Button b = sender as Button;
            if (b.Name == “addButton”)
            {
                MyObject o = new MyObject();
                o.Title = string.Format(“Item {0}”, coll.Count);
                coll.Insert(0,o);
            }
            else if (b.Name == “removeButton”)
            {
                if (coll.Count > 0)
                {
                    coll.RemoveAt(0);
                }
            }
        }

Well, it’s absolutely WPF stuff, in spite of the fact, that we are in Silverlight. However, it’s not 100% right. We’re still missing DataTriggers, some of layout controls, style trigger etc. But it’s still in beta, and by now it’s looking like in very near future we’ll be able to develop the same code and just compile it for different platforms: WPF, WPF XBAP, Silverlight (as for me WPF/E is better name for this version, due to fact, that it’s tool close to WPF)

Thank you and be good people. Stay tuned for upcoming articles…

Learning marathon – December 23-29

Do you want to know WPF, Silverlight or it’s architecture or appliance and you are in Israel next week? If so, please keep reading. Next week (Dec 23-29) it’s going to be a lot of workshops, courses and other learning attractions, related to those technologies.

  • 24-Dec [4:00PM-8:00PM] – Architects user’s group "Architects Forum Meeting – User Experience – Architecture and Technologies Dillemas" in Microsoft Israel (2, haPnina str, Ra’anana). The place to discuss with me + light dinner
  • 25-Dec [9:30AM-4:30PM] – "WPF training for designers" in Sela college (14, Baruch Hirsh str., Bnei Brak). If you are designer and want to stop getting rejects from developers, you should attend. You’ll learn how to use efficiently Microsoft Expression tools and begin to designing real applications. What’s in agenda?
    • What is UX? (Developers are strange nation)
    • Expression Design (It’s not Adobe)
    • Expression Blend (We do not need those strange designers)
    • Windows Experience (Visual Studio is old and bad tool)
    • Hands On Labs (Let’s make it work)
  • 26-Dec [8:30AM-1:30PM] – "Microsoft technologies appliance in C2 and military systems" in Microsoft Israel (2, haPnina str, Ra’anana). You’ll hear about real world real time and near real time applications, command and control systems, and using WPF, Silverlight, Windows Server and .NET technologies to build them. If you are working in military industry – you have to attend. Lunch and dinner included.
    • Modern C&C systems, using new technologies (me)
    • mCore as C2 framework (Eli Arlozorov)
    • Israel Navy as C2 and WPF successful case study (Lior Rozner)
  • 27-Dec [9:30AM-4:30PM] – "Silverlight training for designers" in Sela college (14, Baruch Hirsh str., Bnei Brak). If you are designer and want to start writing Silverlight applications, you should attend. One day session to start work in Silverlight, by using Microsoft Expression suite. Agenda
    • How to start project (developers understand nothing)
    • Prepare assets (make developers not interrupt you)
    • Expression Blend how to (if I know Adobe, I already know it)
    • Make it moving (Adobe Flash is my friend)
    • Make it play (You are producer)
    • Fundamentals (make you understand developers)
    • How to finish project (developers understand nothing)

    Not bad, ah? You should register @ Microsoft [send me an email if you have registration problem] to attend any of those events (it’s free, if there are places). See you there and have a good weekend.

    Tafiti goes open source (well, actually, shared source under MS-PL)

    All those, how want to implement data visualization in Silverlight (as Tafiti does), can look into this CodePlex project and use it for your own. Notice, you can download, modify and, even, resell this code, due to fact, that it’s under MS-PL shared source licence. Well done, Live team.

    Silverlight 2.0 it’s time to GoLive

    Great news for web developers. Silverlight 2.0 beta will be released with Go-Live licence within a couple of months. Other words, in Q1 2008.

    What is Go-Live?

    This means, that you can begin to build your production Silverlight applications without being worry about feature capabilities and hard rewrites and integrations. Another news is, that in the same time (or even earlier) we’ll get CTP of ASP.NET 3.5 extensions, which will be added to ASP.NET next year.

    What is Silverlight 2.0?

    It’s, actually, Silverlight 1.1, that you know. But due to new “managed” concept the product was renamed to 2.0. Other words, too much changed for 0.1 mark :)

    What is ASP.NET 3.5 extensions?

    Actually, those are extensions for ASP.NET 3.5, released last month. It will include:

    • MVC (model-view-controller) for ASP.NET
    • Entity Framework – kind of Linq, data modeling framework
    • Data Services – access any data by URL
    • Dynamic Data – access dynamic and rapidly changing data without special code to write
    • AJAX – need to explain?
    • Silverlight Controls for ASP.NET – easy integration of Silverlight and ASP.NET server code.

    What SL 2.0 will include?

    Layout management (Stack and Grid panels), a lot of networking (mostly POX and REST) and controls: Button, CheckBox, DataGrid, Hyperlink, ListBox, Modal Window, Popup, ProgressBar, RadioButton, ScrollViewer, Slider, TabControl, Canvas, FileOpenDialog, Grid, Image, ItemsControl, StackPanel, TextBlock, TextBox, MediaElement and MultiScaleImageElement.

    When the final release?

    Soon, but we can not tell you yet.

    And the last, but not least – Silverlight will be available for mobile devices as well. It, probably, will not happen in current version, but in really near future. Additionaly, Silverlight 1.0 applications will be fully supported by Silverlight 2.0 runtime.

    Silverlight tools for Visual Studio 2008 RTM

    After upgrade to Visual Studio 2008 RTM from Beta 2, you, probably, will need Silverlight tools for VS2008. Download and install it from here. Please note, before installation, you should completely uninstall previouse version of Silverlight tools for Visual Studio 2008 beta 2.

    Working with XML in Silverlight and bonus – generic Property Bag implementation

    I believe, that if you are in programming, you know what Property Bag is. This is handy generic class, that can "eat" poor-known structure and process a list with all this information. You often can access properties of the parent class by name.

    Why this good? Property Bag provides very intuitive way to access data. This type safe collection, that has not single type, but can be filled with data of different types. Let’s see an example of such data.

     
        
    <vCard>
    <
    FullName>
    <
    FamilyName>Crystal</FamilyName>
    <
    GivenName>Corky</GivenName>
    </
    FullName>
    <
    Title>Computer Officer Class 3</Title>
    <
    Role>Programmer</Role>
    <
    Phone>+61 7 555 5555</Phone>
    <
    Email>corky@qqqfoo.com</Email>
    <
    Organization>
    <
    OrganizationName>qqqfoo.com Pty Ltd</OrganizationName>
    <
    OrganizationUnit> Commercialisation Division </OrganizationUnit>
    </
    Organization>
    <
    Address>
    <
    Street>111 Lake Drive</Street>
    <
    Locality>WonderCity </Locality>
    <
    Pcode>55555</Pcode>
    <
    Country>Australia</Country>
    </
    Address>
    </
    vCard>

     

    Well, in order to get any information from such file, you need to parse XML and know it’s structure or DTD. If someone will change the file and remove FullName tag, for example, all your program often have to be rewritten. So, we’re implementing PropertyBag helper call to take care on such cases. Here the simple implementation of such class in C#

     
        
    public class PropertyBag : List<KeyValuePair<string, string>>
    {
    public PropertyBag (XmlDocument source)
    {
    //((WaitCallback)delegate
    //{
    fillTheBag(source.ChildNodes);
    //}).BeginInvoke(null, null, null);
    }

    void fillTheBag(XmlNodeList root)
    {
    for (int i = 0; i < root.Count; i++)
    {
    if (root[i].ChildNodes.Count > 0)
    {
    fillTheBag(root[i].ChildNodes);
    }
    else
    {
    base.Add(new KeyValuePair<string, string>(root[i].ParentNode.Name, root[i].InnerText));
    }
    }
    }

    public string GetPropertyValue(string property)
    {
    for (int i = 0; i < base.Count; i++)
    {
    if (base[i].Key == property)
    return base[i].Value;
    }
    return string.Empty;
    }
    }

     

    Now, you can create PropertyBag by using easy constructor with XmlDocument as parameter and call any of internal information, found in source XML as bag["FirstName"].

    This is very cool, but when we want to implement such approach in Silverlight, we will find, that there is no XmlDocument there, as well as no DOM at all. The only thing, you can use is XmlReader, that reads information from string stream and parses in on the fly. So how to know, when we have nested elements, how to know, that we have types of data. Let me introduce you SilverPropertyBag, useful class to read information from remote XML file and put it into property bag.

     
        
    public class SilverPropertiesBag : List<KeyValuePair<string, string>>
    {
    public SilverPropertiesBag(string xmlPath)
    {
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ConformanceLevel =
    ConformanceLevel.Fragment;
    settings.IgnoreWhitespace =
    true;
    settings.IgnoreComments =
    true;
    settings.IgnoreProcessingInstructions =
    true;

    try
    {
    HttpWebRequest request = new BrowserHttpWebRequest(new Uri(xmlPath));
    HttpWebResponse response = request.GetResponse();
    Stream content = response.GetResponseStream();

    XmlReader reader = XmlReader.Create(content, settings);
    reader.MoveToFirstAttribute();

    fillTheBag(reader);
    }
    catch {}
    }

    void fillTheBag(XmlReader root)
    {
    int depth = root.Depth;
    KeyValuePair<string, string> last = new KeyValuePair<string, string>();
    while (root.Read())
    {
    switch (root.NodeType)
    {
    case XmlNodeType.Text:
    last =
    new KeyValuePair<string, string>(root.Name, root.Value);
    break;
    case XmlNodeType.EndElement:
    if (last.Key == string.Empty && last.Value != string.Empty)
    {
    last =
    new KeyValuePair<string, string>(root.Name, last.Value);
    base.Add(last);
    last =
    new KeyValuePair<string,string>();
    }
    if (depth > root.Depth)
    return;
    break;

    }
    if (root.IsEmptyElement || root.EOF) return;
    else if (root.IsStartElement())
    {
    string name = root.Name;

    if (root.HasAttributes)
    {
    while (root.MoveToNextAttribute())
    {
    base.Add(new KeyValuePair<string, string>(root.Name, root.Value));
    }
    root.Read();
    if (root.NodeType == XmlNodeType.CDATA && root.Value.Length == 0)
    {
    root.Read();
    }

    if (root.NodeType == XmlNodeType.Text && root.ValueType == typeof(string) && root.Value != string.Empty)
    {
    base.Add(new KeyValuePair<string, string>(name, root.Value));
    }

    if (root.NodeType == XmlNodeType.EndElement && root.Name.Equals(name))
    {
    root.Read();
    if (root.Depth < depth)
    return;
    else
    continue;

    }

    if (root.IsStartElement())
    {

    if (root.Depth > depth)
    fillTheBag(root);
    else
    continue;
    }
    root.Read();
    }
    }
    }
    }

    public string GetPropertyValue(string property)
    {
    for (int i = 0; i < base.Count; i++)
    {
    if (base[i].Key == property)
    return base[i].Value;
    }
    return string.Empty;
    }

    }

     

    Well. It’s pretty easy to understand how it works, but it’s extremely useful for  any of your Silverlight projects. Happy programming.

    Microsoft Expression Blend 2 August Preview is available

    New refreshment of great XAML editing tool is available for download as Preview version. What’s new? Silverlight (working with Silverlight 1.0 RC) and Visual Studio 2008 (Orcas) integration support, User controls authoring, XAML editor got some improvements, such as changing font sizes, word wrapping, etc. You can now target your build by using $(BuildingExpressionBlend) property. New storyboard picker replaces old Storyboard combobox and you can finally manipulate (scaling, resizing, etc) multiple objects.

    We’re looking forward for your feedbacks

    Download Microsoft Expression Blend 2 August Preview

    Now it’s official – WPF/E=SilverLight

    New “flash killer” is here and this time it’s serious. Today at NAB conference, Microsoft announced and demonstrates it’s next generation cross-platform web technology Microsoft Silverlight. Actually, it’s totaly rebranded WPF/E . Microsoft Silverlight will enable content providers to deliver media experiences and rich interactive applications that incorporate media, graphics, animation, and much, much more with full application functionality on both Windows and Mac platforms and inside IE, Firefox and Safari. Silverlight users will also enjoy compatibility with the broad ecosystem of Windows Media (VC-1) enabled tools and solutions, including existing and upcoming IIS and Windows Streaming Media server technologies.

    So it comes with new server side products – Expression Media Encoder, IIS7 Media Pack and broadcast system. You can learn more about this new technology here.

    Also, there are some interesting comparison tables between WPF, SilverLight and Flash at MED blog as well as at off. site of this platform.

     

    ⟨ , ,  ⟩

    Recommended

     

    Sponsor


    Partners

    WPF Disciples
    Dreamhost
    Code Project