July 2007 - Posts

Wrapped List Box

WPF provides look less controllers witch makes it very easy to modify control look and behaviours. To demo how powerful this feature is, I will modify the standard list box to rather use a wrap panel and not the standard stack panel. This will make all the items in the list box be displayed from left to right. Once it riches the end, then thy wrap to the next line. To test this, resize your window to determine how thy wrap. This type of wrap behaviour is very commonly used when displaying products or photos.

Start a new WPF project and add a standard list box to the grid. Set this list box to have 0 margins to consume the whole screen.  Also add some dummy list box items or bind the list box to actual data.

<Grid x:Name="LayoutRoot">
       <
ListBox Margin="0,0,0,0" IsSynchronizedWithCurrentItem="True">
              <
ListBoxItem Content="Dummy #1" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #2" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #3" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #4" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #5" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #6" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #7" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #8" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #9" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #10" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #11" Width="100" Height="100"/>
              <
ListBoxItem Content="Dummy #12" Width="100" Height="100"/>
       </
ListBox>
</
Grid>

Next, we need to add a style to convert the stack panel to a wrap panel

<Style x:Key="WrapListBoxStyle" TargetType="{x:Type ListBox}">
       <
Setter Property="Template">
              <
Setter.Value>
                     <
ControlTemplate TargetType="{x:Type ListBox}">
                           <
WrapPanel Width="Auto" Height="Auto" IsItemsHost="True"/>
                     </
ControlTemplate>
              </
Setter.Value>
       </
Setter>
</
Style>

Add the following Style to the <Window.Resources> section

Next, we need to add a style to handle list box item selection. If you need to modify how the item gets selected or highlighted, this is where you would change that...

<Style x:Key="WrapItemStyle" TargetType="{x:Type ListBoxItem}">
       <
Setter Property="HorizontalContentAlignment" Value="Center"/>
       <
Setter Property="VerticalContentAlignment" Value="Center"/>
       <
Setter Property="Template">
              <
Setter.Value>
                     <
ControlTemplate TargetType="{x:Type ListBoxItem}">
                           <
Border SnapsToDevicePixels="true" x:Name="Bd" Width="100" Height="100" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                  <
ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                           </
Border>
                           <
ControlTemplate.Triggers>
                                  <
Trigger Property="IsSelected" Value="true">
                                         <
Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                         <
Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                                  </
Trigger>
                                  <
MultiTrigger>
                                         <
MultiTrigger.Conditions>
                                                <
Condition Property="IsSelected" Value="true"/>
                                                <
Condition Property="Selector.IsSelectionActive" Value="false"/>
                                         </
MultiTrigger.Conditions>
                                         <
Setter Property="Background" TargetName="Bd" value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                                         <
Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                                  </
MultiTrigger>
                           </
ControlTemplate.Triggers>
                     </
ControlTemplate>
              </
Setter.Value>
       </
Setter>
</
Style>

Lastly, we need to update our list box and list box items to use the dynamic resources

<ListBox Margin="0,0,0,0" Style="{DynamicResource WrapListBoxStyle}" IsSynchronizedWithCurrentItem="True">
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #1" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #2" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #3" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #4" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #5" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #6" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #7" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #8" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #9" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #10" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #11" Width="100" Height="100"/>
       <
ListBoxItem Style="{DynamicResource WrapItemStyle}" Content="Dummy #12" Width="100" Height="100"/>
</
ListBox>

And that is all that is required to convert a stock standard list box into a flashy wrapped list box

Posted by rudi | 1 comment(s)
Filed under:

WPF Articles

Dr Tim Sneath gives a overview of what is new in WPF 3.5

http://blogs.msdn.com/tims/archive/2007/07/27/what-s-new-in-wpf-3-5-here-s-fifteen-cool-features.aspx

Josh Smith (Who also has a very cool technical blog) has written a excellent article about creating a skinned UI using WPF

http://www.codeproject.com/useritems/SkinningInWPF.asp

Mike Hillberg has written a article on how to provide context sensitive help in WPF

http://blogs.msdn.com/mikehillberg/archive/2007/07/26/a-context-sensitive-help-provider-in-wpf.aspx

Jaime Rodriquez wrote a excellent 3 part article about drag & drop in WPF

http://blogs.msdn.com/jaimer/archive/2007/07/12/drag-drop-in-wpf-explained-end-to-end.aspx

 

Posted by rudi | with no comments
Filed under:

Facebook

I have to hang my head in shame this week and admit that I have joined facebookEmbarrassed. I love Facebook, I made contact with friends I haven't seen in years and facebook really makes it easy... I am not a big fan of social netowork applications but Facebook is great. It has a clean interface, its easy to use and I have found loads of my friends already.

While using Facebook I started wondering: What makes a great social network?

Posted by rudi | with no comments
Filed under:

XPE Weekly (29 July 2007)

Windows XP Embedded is a wonderful operating system but why should I use it? It is binary compatible with Windows XP Professional and supports full Win32, so why can't I just use XP? Well, in the next couple of XPE weeklies, I will try and answered this question by covering the embedded enabling features of XPE. This week, I will start with the Device Update Agent.

Ever wonder how you would update your operating system, install new drivers or update your applications on an embedded device? How about if you have 2000 of these device in the field? What if these 2000 units are spread out over the whole of South Africa or even worst, the world? The Device Update Agent will try and address these problems.

MSDN describes the DUA as follows: "Device Update Agent (DUA) enables you to update a run-time image remotely. DUA is a service that runs on your run-time image and performs administrative tasks, such as copying files, creating registry keys, or executing processes."

There are some obvious limitations. Your device needs to be able to connect to remote location, either by using a local area network or to an internet location. The DUA then polls this location for update scripts that it can execute.

These scripts are also not the easiest to write. Luckily Mike Hall and Aaron Stebner created a wonderful utility called DUAScriptGen. This utility can easily convert OS QFE's to scripts and also simplifies the writing of other scripts! This utility can be downloaded here:

http://blogs.msdn.com/astebner/articles/479475.aspx

Another limitation of the DUA is that the files doesn't get downloaded using the Background Intelligent Transfer Service (BITS) which means that if the connection gets lost or interrupted, then the download needs to be downloaded from scratch.

Even with these limitations, the DUA is a very useful feature and should always be considered as a standard part of your image!!!

That is all for this week...

PS. I received new copies of Windows XP Embedded trail edition and also of Windows CE 6.0. Please contact me if you need copies

Posted by rudi | with no comments
Filed under: ,

Robotic Studio Test Drive

AKA RoboHum 1.0

I decided to skip this week's XPE weekly and take the Microsoft Robotic Studio (MRS) for a test drive! I have to start off by saying... WOW! This is an awesome framework. Anybody that have tried writing software that uses many sensors and actuators and then trying to coordinate them will know that this is not an easy task!!! MRS makes it easy. I will quickly review the 2 parts that makes up the robotic studio and then talk a little about the way I tested it.

I will also review how I build my very 1st "robot"

Concurrency and Coordination Runtime (CCR) provides a highly concurrent, message oriented programming model with powerful orchestration primitives enabling coordination of messages without the use of manual threading, locks, semaphores, etc. CCR addresses the need of service-oriented applications by providing a programming model that facilitates managing asynchronous operations, dealing with concurrency, exploiting parallel hardware and handling partial failure. It enables you to design your application so that its software modules or components can be loosely coupled; that is, so that they can be developed independently and makes minimal assumptions about their runtime environment and other components. This approach changes how you think of programs from the beginning of the design process and facilitates dealing with concurrency, failure and isolation in a consistent way.

The CCR runtime is a self-contained .NET DLL accessible from any language targeting the .NET 2.0. Common Language Runtime (CLR).

Decentralized System Services (DSS) provides a lightweight, service oriented application model that combines key aspects of traditional Web-based architecture (commonly known as REST) with pieces of Web Services architecture. The application model defined by DSS builds on the REST model by exposing services through their state and a uniform set of operations over that state but extends the application model provided by HTTP by adding structured data manipulation, event notification, and service composition.

The primary goal of DSS is to promote simplicity, interoperability, and loose coupling. This makes it particularly suited for creating applications as compositions of services regardless of whether these services are running within the same node or across the network. The result is a highly flexible yet simple platform for writing a broad set of applications. DSS uses HTTP and DSSP as the foundation for interacting with services. DSSP is a lightweight SOAP-based protocol that provides support for manipulation of structured state and for an event model driven by changes to the structured state. DSSP is used for manipulating and subscribing to services and hence compliments HTTP in providing a simple, state-driven application model.

The DSS runtime is built on top of CCR and does not rely on any other components in Microsoft Robotics Studio. It provides a hosting environment for managing services and a set of infrastructure services that can be used for service creation, discovery, logging, debugging, monitoring, and security.

[Taken from MSR documentation]

I decided to really test MRS, that I should make my own "robot". I went out and bought a cheap electric remote control car, stripped it open and started the conversion

 

Before

Stripped down

PC Added

I controlled my 2 motors via relays switched using the parallel port. Each motor has 2 relays. The first relay changed the direction of the motor by switching the polarity and the second relay is used to turn the motor on and off.

The next step was to create a LPT motor service. I based my service on the generic motor service provided. It is amazing to think that all this is done using managed code. Once my service was up and running I wrote a very basic coordinating service using the Visual Programming Language (VPL). The VPL also has a feature to export or compile the service as C# code. After compiling the service, I used DssDeploy to create a package.

Next, I installed XPe on the single board computer (SBC) and deployed my package. Finally I ran my MRS Service on my intelligent "robot".

MRS provides a few different methods of accessing remote DSS services:

  • WinForms UI
  • Web based UI
  • Vision based tracking
  • Audio based UI
  • Game Controller based UI

To access RoboHum, I added a Bluetooth dongle and established a Personal Area network with RoboHum. From here, I currently allow two methods of control (Web based UI & Game controller based UI). Future plans include adding speakers and a microphone to support Audio based UI and to add a web cam and support vision based tracking.

I am also planning on porting my service to the Compact Framework (CF) and to rather install CE on a SBC.

There are loads of was to test the MRS. MRS supports a very realistic simulation environment which can be used to test the features. Also have a look at the Sumo competition! I only chose to make my own robot because it is relative low cost method. The company that I work for sells SBC's so I didn't have to buy the PC. The remote control car was R300 and the relays that I had to buy were R100. This makes my "robot" total cost less than R500!!! Again there are loads of methods to do this... I only chose this method because I had all the necessary parts and knowledge...

 

Posted by rudi | 1 comment(s)
Filed under: ,

Project Management

I am planning on doing some project management training while I have time but to figure out which is better is taking me forever...

PRINCE2

PRINCE2, or PRojects IN Controlled Environments, is a process-driven project management method.

From what I can find on the internet, to be PRINCE2 qualified, you have to pass the Foundation and Practitioner Exams. I haven't yet found a place in SA where I can take this officialy acreddited exams

SCRUM

Scrum is a method for managing work, improving morale, and achieving very high productivity. Scrum is noted for its simplicity, its high level of transparency, and a team based approach to work. Scrum is an agile method for project management

Which of these are better? Where can find training on these? Any recommended reading?

Posted by rudi | 2 comment(s)
Filed under:

WPF Tools

I rely very heavily on XAML cruncher to test my XAML code, Charles Petzold just release XAML Cruncher 2.0

http://www.charlespetzold.com/blog/2007/07/100411.html

 

Posted by rudi | with no comments
Filed under:

XPE Weekly (10 July 2007)

"Microsoft® Windows® XP Embedded provides the ability to build a customized operating system image which contains the components and technologies that are appropriate for your specific device. The image may contain customized device drivers and applications, and in some cases, it would also be appropriate to boot the Windows XP Embedded device directly into a customized application, or shell. This could prevent users from switching applications, accessing the control panel, or underlying filing system of the device. A retail point of sale (RPOS) device could simply boot directly into the RPOS application."

This week's XPE Weekly will kick off with an intermediate tutorial on how to create a custom shell.

 A Client this week requested a panel PC that only shows his website. The website must not have a start button, task bar or any other normal windows features. The website must also not be changeable (i.e. No address bar, etc). After a little research I found that IE can be used in KIOSK mode by calling IExplore.exe with a -k parameter. The next step was to create a custom shell that only launches IExplore.exe in KIOSK mode.

Microsoft Component Designer will be used to create the new custom shell that we will be using.

•1.       Launch Component Designer

  • 2. File -> New
  • 3. Right-click on the Components folder and select Add Component.
  • 4. Rename the component to a friendlier name. I renamed mine to "IE Kiosk Mode Shell" by changing the name in the Component Properties on the right hand side.
  • 5. Next we must select a prototype. On the right hand side, select Browse. Make sure that the Database is selected and then search for Software -> System -> User Interface -> Shell -> Windows Shell and select Shell Prototype Component
  • 6. We now have to tell the component which program to run on start-up. The start-up application is indicated by the cmiShellPath property. On the right hand side, click on the Advanced button. This will display a dialog box that can be used to add custom properties. Click on Add. The name of the property is cmiShellPath and the value is "IExplore.exe -k http://www.deat.gov.za/"
  • 7. Lastly, you need to associate the new component with "shell" dependency group by adding a Group Membership. Right-click on the Group Memberships and select Add Group Membership
  • 8. Select Categories -> Software -> System -> User Interface -> Shells

That is all that is required to make a basic custom shell.

The next step is to import this component (.SLD) into the database. Launch the Component Database Manager and click on Import. In the dialog box, browse to the create component (.SLD) and click on Import.

Now this component is available for use when building the image. When we create a new image, and run dependency checker, our newly created shell should show as a possible solution for the dependency

I finally build my image and launched it on my Panel PC. Only Internet Explorer was launched and it used KIOSK mode. Here is a picture of my POC running XPE + IE7 + Silverlight

 

That is all for this week. I will hopefully publish my beginner tutorial next week. If you have any question, please email me on rudi@cme.co.za

 

Posted by rudi | 2 comment(s)
Filed under: ,

Forza Motorsport 2

Just bought Forza, can't wait to try it out tonight...

Posted by rudi | 2 comment(s)
Filed under:

Silverlight Surface Demo

I don't know if anybody blogged about this yet... There was a huge hype about surface when it was released about a month ago. One of the demos showed was an application where it scatters photos on the surface and you could rotate, resize and manipulate photos and videos... Well, I found 2 separate silverlight websites with a similar application. The best part of it all it all is that both these applications source is also released!

Delay's Blog

http://blogs.msdn.com/delay/archive/2007/06/01/silverlight-surface-demonstration-silverlight-implementation-of-surface-s-photo-table-ui.aspx

and here is the demo website:

http://delay.members.winisp.net/SilverlightSurface/

Michael' Blog

http://weblogs.asp.net/mschwarz/

and here is his demo website:

http://silverlight.schwarz-interactive.de/ex02/

Posted by rudi | with no comments
Filed under: , ,

Computicket

On sunday evening I finally went to see Lion King at Monticasino... What a great show! Monticasino pulled out all the stops with this show and did south africa proud. The only problem I had with the whole show is computickets booking system!!!

 I booked my tickets online. I selected where I wanted to sit and how many tickets I wanted. a Popup appeared that said can't sit where I selected, should it try and find me seats. I thought great, let it choose some seats for me!!! What a mistake!!! Without me knowing, the 2 new seats it found me was miles appart. Without checking this, I went ahead and booked it! I know I should have checked before I paid but man!!! If I want 2 seats next to each other and it can't find 2 seats then this show has NO SEATS!!! Well, luckily thy managed to find me 2 seats next to each other and whe could enjoy a wonderfull show!

Initially I feld stupid about this mistake but while standing at the ticket office, 2 other couples had exactly the same problem...

 

Posted by rudi | 3 comment(s)
Filed under:

Under the hood: Dependency Properties

Dependency Properties are a huge part of what makes WPF work so I decided to spend a little time on the subject! As the name implies, Dependency Properties are properties that depend on other factors.  The value of a dependency property can be determined by a variety of factors, enabling features such as real-time property validation and notifying related properties of changes to value for other properties.

A little bit of history

To understand dependency properties, you have to remember the good old days of normal CLR properties. If you missed that part, here is a quick recap: Properties basically uses a getter and a setter to set a private variable.

private bool IsEmptyValue;
public bool IsEmpty
{
    get { 
return IsEmptyValue}
    set { IsEmptyValue 
value}
}

.NET Framework 3.0 added a quick way to define a property

public bool IsEmpty
{
    get
;
    
set;
}

Now for the good stuff...

There is now better way to start learning something new then by doing it. Charles Petzold's book Application = Markup + Code has an excellent example of how to test the basics of dependency properties. The application creates a Window and adds a grid to the content of this window. The grid is then divided into 2 rows and 3 columns. Each cell gets 1 button. The top row's buttons basically change the font size of the window and the bottom row changes the font size of the button. The important features to notice is that once a buttons font size has been changed, then changing the font size using the windows font size has no effect. This indicates that there is some order of precedence in setting the value of a property.

Order of precedence

  • 1. Property system coercion
  • 2. Active animation

•3.       Local value

  • 4. TemplateParent template
  • 5. Style triggers
  • 6. Template triggers
  • 7. Style setters
  • 8. Theme style

•9.       Inheritance

•10.   Default value

From this list we can deduct why the application functions the way it does. Once the button is created, it gets it default value from its metadata. This is the lowest value it can have. If the font size of the window gets changed, then the buttons inherit this value. This inherited value is of slight higher precedence. If you manually set the value of a button, then inheritance is ignored because it has a lower precedence than manually setting the buttons value.

This is a very important concept to grasp. Another interesting thing to note is that the grid has no FontSize property but the FontSize property of the Window gets passed down to all children of this grid.

How to implement a Dependency Properties

A class can only define dependency properties if it is derived from DependencyObject. This provides all the basic functionality required to implement dependency properties. The 3 most important methods defined are SetValue, GetValue and ClearValue. Have a look at an older post I made about dependency properties to see how to implement them.

http://dotnet.org.za/rudi/archive/2007/05/21/dependency-properties.aspx

Why use Dependency Properties?

So, inheritance is great but what else can these properties do? Dependency properties have very well defined set of metadata that can be set per property. Some of the options that can be defined with this metadata is the default value, can it be inherited, etc. Dependency Properties facilitate attached properties. I will hopefully cover attached properties later, but for now just know that attached properties are often used in WPF to simplify layout. Dependency properties also provide self-contained validation handling and of course dependency properties are XAML friendly. This allows other features like data binding, styling, animation, etc...

Where is Dependency Properties used?

Well, the short answer is basically everywhere... Properly the biggest example of using dependency properties is FrameworkElement.DataContext. This property is inherited by all the decedents and can thus implicitly share the same data source. The example out of Charles Petzold's book used the FontSize property.

For more detailed information, have a look at the 3 articles Josh Smith wrote at http://joshsmithonwpf.wordpress.com/. The sample code from Charles Petzold's book can be downloaded from his homepage at http://www.charlespetzold.com/.

Disclaimer

The following article is based on my personal testing, code from Charles Petzolds book, great articles on Josh Smith's blog about Dependency Properties and also some research on MSDN

kick it on DotNetKicks.com
Posted by rudi | 4 comment(s)
Filed under: ,