David Sandor

Build succeeded.

Resize Images in a batch in C#/WPF with an MVVM application.

clock January 21, 2012 19:11 by author dsandor

I am working on a project where I need to resize a bunch of raster images from miscellaneous sizes to fit within a certain frame.  More specifically, I need a bunch of icons for an iPhone application and I need them to fit within a 64px by 64px frame.  I found a bunch of Photo Shop scripts, some console apps, and a few spamware solutions.  I figured half an hour and I would have one that works well.  I was right.

image

So here is how the app works:

Drag and drop the graphics files you wish to resize into the application.  The files will show in the list view area.  Next, enter the Max Height and Max Width values and then click the Resize button.

The application will write the resized file next to your original with _MaxHeightxMaxWidth appended to the filename.  Original files are not modified in any way during this process. 

So if you found this blog post in hopes that you would find a quick and simple image resizer for free, here is the link to the binaries: 

A little about the application source code.  The application is a .NET 4.0 WPF application that follows the M-V-VM (MVVM) design pattern.  Since there is drag and drop support in the application there is a little code behind to support this.  The rest of the application follow the MVVM pattern.

There is a tiny image resizer class in the project that you are free to use.  This is located in the DevSQL.Imaging assembly. 

The source code can be found below.



Align your code in Visual Studio 2010

clock January 21, 2012 16:47 by author dsandor

I love this Visual Studio Extension.  Wanted to keep it in the blog so I do not forget.  Chris also wrote a notepad++ plug-in for the same thing.  Kudos.

http://visualstudiogallery.msdn.microsoft.com/7179e851-a263-44b7-a177-1d31e33c84fd

Align by... (Dialog) Ctrl + Shift + =
Align by position... (Dialog) Ctrl + =, Ctrl + backspace
Align by Equals Ctrl + =, Ctrl + =
Align by m_ Ctrl + =, Ctrl + m
Align by " Ctrl + =, Ctrl + '
Align by . Ctrl + =, Ctrl + .
Align by Space Ctrl + =, Ctrl + Space



Solved: Add new configuration to Visual Studio 2010 project and code will no longer compile.

clock May 24, 2011 11:17 by author dsandor

Scenario

Create a new configuration in Visual Studio and select ‘copy’ from an existing working configuration.  The new configuration will not compile now.

image

As it turns out, Visual Studio 2010 (even with SP1) does not copy the Conditional compilation symbols.

image

Adding in my conditional compilation symbols allows the project to compile now.



iTouch Dynamics Ax 2009 inventory management application

clock May 10, 2011 13:39 by author dsandor

Business Problem

Mobile laser scanning applications for Microsoft Dynamics Ax 2009 are complicated, over-engineered, and down right ugly.  Many applications exist and are very configurable but provide a very poor user experience which in turn slows down the end user and makes the data gathering more error prone.

Solution

After evaluating several tools to provide Cycle Count, Purchase Order Receiving, Inventory Transfers, and Miscellaneous Receiving we decided it would be best to take a 37signals approach to Get Real with our application.  We provided our warehouse team a set of tools that allowed them to accomplish their job in a simple and user friendly manner.  In addition, we minimized our cost per mobile barcode scanner.  By using a $200 iTouch as the brains and a $499 Linea Laser Barcode cradle we dropped our $3,000 mobile scanning hardware to $699.

The user interface is built using Novell’s MonoTouch and is written in C#.  The XCode tools were also used for some screen layout.  No Objective-C was used on this project.  The iTouch applications make WCF calls to interact with Dynamics Ax 2009.  The WCF Services are written in C# 4.0 and employ the .NET Business Connector to interact with the ERP system’s data.  An Ax project that uses X++, Forms, Classes, and Schema Additions is used to provide a succinct API to the WCF Services.

Screenshot 2011.02.01 17.02.54
PO Search Screen

Screenshot 2011.02.01 17.02.46
PO Details Screen



RFID Client for Spares Management

clock May 10, 2011 11:01 by author dsandor

Business Problem

Large companies have lots of facilities which need spare part inventory on hand.  Facility operators may not reorder parts in a timely fashion which can lead to a local shortage of equipment.  Some facilities may hoard equipment creating a local surplus of equipment.  Both extremes are costly to a company.

Solution

Provide a simple to use touch screen computer that detects when a part is leaving or entering the spare parts room.  Upon detection of the part the touch screen computer displays a ‘tag’ with information about the part.  The facility user can touch the tag on the screen and note the use of the part.  When parts come in for replenishment the facility user can notate the put away location of the part.  When are part is used inventory levels at MDSi are updated.  If the minimum stocking level is reached a reorder is automatically generated and shipped to the facility to keep the stocking level true.

Components

RFID Client (Touch screen workstation)
This is the device with which the facility users interact.

image

The client is built with Microsoft .NET Framework 4.0 and uses Windows Presentation Foundation (WPF) to present the UX.  The client leverages the Model-View-ViewModel (MVVM) architectural pattern and is written in C#.  Communication to the home office is provided via WCF services.

image

RFID Tags are read via a Motorola XR-450 tag reader.  This reader was selected because it has a built in Windows CE operating system that allows us to write Mobile Embedded .NET applications to interact with the reader and with our WCF Services.  The RFID Client Workstation has a Windows Service written in C# and .NET 4.0 which continually polls the XR-450 reader for new tags.  The service exposes a .NET Remoting service which is consumed locally by the client UI.  Multicast events are thrown and the client system can respond to new tags accordingly.


RFID WCF Services
All RFID Clients communicate to a set of centralized web servers in an NLB farm.  The WCF Services provide a data exchange layer which provides caching by leveraging the AppFabric Cache feature of Windows Server 2008 R2.  Data is stored in a SQL 2008 R2 Cluster and the data is organized through Microsoft Dynamics AX 2009.  X++ and Business Connector code was created to interface through the ERP system and pass through all of the business rules configured in the Dyanmics Ax system.  In addition to using the .NET Business Connector and custom Dynamics Ax projects to manage the data, ADO.NET, Linq and C# is used in the creation of these services.

RFID Management Display
A Network Operation Center (NOC) application was created to provide real-time node (RFID Touch Screen Client) availability data.  This data is organized on a map and allows an operator to drill in to a workstation and remotely manage the system.

image

RFID Warehouse Printing
Tools were created to interface with the Microsoft Dynamics Ax 2009 ERP system which allow a warehouse employee to print RFID labels for items being shipped out for replenishment.  This system interfaces with the Zebra RZ 400 RFID Printer.  This application was created using WPF, WCF, MVVM.

image

RFID On-Site Inventory and Auditing Tool
This application allows a warehouse specialist to audit a sparing facility.  This application is written using WPF and .NET 4.0.  The application consumes the same WCF services provided for the RFID Client to connect to the ERP system.  The application allows a specialist to print labels via a wireless Zebra RP4T RFID Label printer.  Using this application a project coordinator can determine what inventory is needed on site and what can be returned for general usage to the Distribution Center (DC).  This allows for a quick and efficient auditing process.  The warehouse specialist does not need to know anything about the product, just scan the serial number and the application tells the specialist the disposition of the part based on the Min/Max settings in the ERP system.

image

RFID Node Creation Tool
The Node Creation Tool allows a support engineer to provision a remote RFID Touch Screen Client from a central location.  A support engineer can provision all of the standard configuration settings for Development, Test, and Production from the single tool.  This application was created with WPF, C#, WCF, MVVM.

image

RFID Online Spares Management Web Application
A Silverlight application was created to provide scaled down functionality for locations that do not have the RFID Touch Screen client installed.  Some locations need the ability to consume, count and audit their inventory without an RFID client.  In this case a laser barcode scanner is used to scan the RFID barcode.  This application was written in Silverlight 4.0, uses WCF Services, and employs the MVVM architectural pattern.

image



Enable .config file build configuration transformations in non-web based applications.

clock April 28, 2011 11:05 by author dsandor

So Web Application projects have this great new feature that allows you to use an XML Transform file to merge settings into your Web.Config file based on the build configuration.  For example, if you have a Release build configuration you might want your connectionString section to point to a production server instead of your development server.  See this link for more information on Web Config Transforms.

This is a really cool feature and it is possible to use this with non-web application projects.  You can configure your project file to support this very easily.  You do need to insert some XML into your csproj file but it is really lightweight.

First, Add an App.config file to your project if you do not already have one.

Next, close Visual Studio and open your *.csproj file in notepad.

Go to the very end of the file and insert the UsingTask and Target sections directly above the </Project> closing tag. 

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
    <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
    <!-- Generate transformed app config in the intermediate directory -->
    <TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
    <!-- Force build process to use the transformed configuration file from now on. -->
    <ItemGroup>
      <AppConfigWithTargetPath Remove="app.config" />
      <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
        <TargetPath>$(TargetFileName).config</TargetPath>
      </AppConfigWithTargetPath>
    </ItemGroup>
  </Target>
</Project>

 

Now find the section that has your App.config file include.  It will likely be in a <None /> tag.  Replace that tag with the following code. (Include a App.CONFIGURATION.config file for each build configuration you use.

    <Content Include="App.config">
      <SubType>Designer</SubType>
    </Content>
    <Content Include="App.Test.config">
      <DependentUpon>App.config</DependentUpon>
    </Content>
    <Content Include="App.Release.config">
      <DependentUpon>App.config</DependentUpon>
    </Content>

Save your csproj file and open it up in Visual Studio again.

image

Now when you build your solution/project the XML Transforms in your App.CONFIGURATION.config file will be merged at build time.



Dynamics Ax 2009 Logon/Logoff overhead, Business Connector, AIF.

clock April 17, 2011 17:54 by author dsandor

So last week I attended Convergence 2011 in Atlanta to prepare for Dynamics AX 2012.  I attended a few interactive discussions and met some folks that made some rather wild claims that I knew for a fact were wrong.  I advised them that they were probably missing something or there was a problem with their installation / database / or code.

The claim was that there is a 2 or more second authentication delay when logging on to Dynamics Ax from the AIF (and others claimed from the Business Connector as well).  Someone stated that it took them 5 hours to import 30,000 sales orders via the BC.  I import a heck of a lot more data then that on a routine basis and I am confident I could import 30k sales order in less than 2 mins.

The proof that they are wrong.

To prove this I wrote an application that logs on to AX and then off of AX and times the process with the Stopwatch class.  The system running AX is a Dynamics AX 2009 SP1 installation on a Dell i7 920 with 12G of RAM.  AOS, App files, and DB (SQL 2008R2 with 4GB of ram allocated to SQL) all run on the same machine.  So this is a basic low end developer workstation running everything.  Your production servers should run circles around the performance of my test machine.

Here are the results:

I ran the loop to logon and logoff 100 times.  You will see the first call takes 220ms and each subsequent call is at about 14ms.  This is a far cry from the 2,000+ ms claims from the interactive discussion at Convergence.

Start time: 0
sessionId: 5
Stop time: 220
Elapsed time: 220

Start time: 220
sessionId: 6
Stop time: 237
Elapsed time: 17

Start time: 237
sessionId: 7
Stop time: 256
Elapsed time: 19

Start time: 256
sessionId: 8
Stop time: 270
Elapsed time: 14

Start time: 270
sessionId: 9
Stop time: 284
Elapsed time: 14

Start time: 1629
sessionId: 103
Stop time: 1643
Elapsed time: 14

Start time: 1644
sessionId: 104
Stop time: 1658
Elapsed time: 14

What I suspect is that the code these folks are using is very poorly written.  Potentially executing a Refresh() call for each session that is constructed.  If you are running into a performance problem with your AIF or Business Connector code feel free to contact me to help you track it down.  My consulting rates are reasonable :)

The code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Dynamics.BusinessConnectorNet;
using log4net;
 
namespace AxConsoleForTests
{
    class Program
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));
 
        static void Main(string[] args)
        {
            
 
            using (Axapta ax = new Axapta())
            {
                string aosConnString = string.Format("{0}@{1}:{2}",
                    "ceu",
                    "devsql-s-06",
                    "2713");
 
                log.InfoFormat("MyMethodName - Connecting to AX Server: {0}", aosConnString);
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Start();
                long startTime = 0, stopTime = 0;
 
                for (int i = 0; i < 100; i++)
                {
                    try
                    {
                        startTime = sw.ElapsedMilliseconds;
                        Console.WriteLine("Start time: {0}", startTime);
 
                        ax.LogonAs("axTestUser", "",
                            new System.Net.NetworkCredentials
                              ("axTestUser", "password", "devsql.local")
                            ,
                            "ceu", "", aosConnString, "");
 
                        Console.WriteLine("sessionId: {0}", ax.Session());
 
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("MyMethodName - Failure: {0}\r\n{1}", ex.Message, ex);
                        throw ex;
                    }
                    finally
                    {
                        ax.Logoff();
                        stopTime = sw.ElapsedMilliseconds;
 
                        Console.WriteLine("Stop time: {0}", stopTime);
                        Console.WriteLine("Elapsed time: {0}\r\n", stopTime - startTime);
                    }
                }
 
                sw.Stop();
            }
            
            Console.WriteLine("Done");
            Console.ReadLine();
        }
    }
}

In order to thwart any comments that I cheated by placing my loop inside a using statement, I looped outside of it as well and the results are the same. 



iPhone / iTouch barcode scanning Hello World application with MonoTouch and LineaSDK

clock January 5, 2011 10:33 by author dsandor

This example is the result of many hours of trial and error.  With the resources provided in this post you will be able to create a small application that will let you scan a barcode into a textbox.  In future parts we will make a more useful application.

The barcode scanning functionality is provided with a hardware device.  If you are reading this you have likely already acquired the SDK and hardware from Infinate Periferals

The application will be developed in MonoDevelop and will utilize MonoTouch.net and MonoTouch.Dialog.  Please use this linkto get all these applications installed and working first.  Please be sure to compile the MonoTouch.Dialog assembly before getting started with this example.

Lets get started

First, Create a project in MonoDevelop of type iPhone Window-based project and give it a name.

Screen shot 2011-01-04 at 1.28.08 PM

When MonoDevelop has completed creating the templated project and solution files you will have something like this:

Screen shot 2011-01-04 at 1.34.28 PM

Here we will add a reference to the MonoTouch.Dialog assembly.  First I will copy it into my project folder by right clicking on the project name in MonoDevelop and choosing Open Containing Folder.  This opens the folder that contains your project files.  Copy the MonoTouch.Dialog.dll file into the project folder.  Right click on the References node in MonoDevelop and chose Edit References.

image

Locate the MonoTouch.Dialog.dll assembly

image

Double click on the MonoTouch.Dialog.dll assembly to add the reference and click OK.

We are now going to create a simple View that displays a message and an input field.  This View (aka form, dialog, screen, page) will be created using MonoTouch.Dialog to simplify things.  Please read up on MT.D on your own.  More examples will follow in the future for that.

Add a navigation controller to the application by double clicking on the MainWindow.xib file.  This will launch Interface Builder.  In the library window choose Objects and drag the Navigation Controller object to the MainWindow.xib window.  You will now have a navigation controller listed.  See image below.

image

Now we need to create an Outlet (aka property) for the navigation controller.  This is used to push views.  Think of the navigation controller as a Push / Pop frame and your Dialog is a view that will be pushed to the visible surface of the application.

imageTo create the Outlet you need to click on the Classes tab of the Library then click on the AppDelegate class at the top of the list.  Then at the bottom of the Library window you need to choose Outlets in the combo box. 

Click the little plus sign + to add a new outlet.  Name it navigation. 

Now we need to link the outlet to the Navigation Controller object in the MainWindow.xib.

image

Click on the App Delegate object in the MainWindow.xib interface builder window.  In the App Delegate Connections window you will see your new navigation outlet.  Hook this outlet up by clicking on the empty circle next to it and dragging it to the Navigation Controller object in the MainWindow.xib window.

image

When you have done this, your App Delegate Connections window will look like this:

image

Save your changes in the interface builder (Command + S).

Go back to MonoDevelop, you are ready to code.

Create an empty class file and call it:  MyBarcodeDialog.cs

Paste the following code, it creates a view with a textbox that we are going to scan into.

using System;
using MonoTouch.Dialog;

namespace MTBarcodeExample
{
    public class MyBarcodeDialog : DialogViewController
    {
        public MyBarcodeDialog () : base(null)
        {
            initView();
        }
        
        EntryElement txtBarcode;
        
        private void initView()
        {
            var root = new RootElement("Simple Barcode Example");
            var section = new Section("Collect Barcode");
            
            txtBarcode = new EntryElement("Barcode", "Please scan a barcode.", "");
            
            section.Add(txtBarcode);
            root.Add(section);
            
            this.Root = root;
        }
    }
}

Save your new class and double click on the Main.cs file.  We are now going to have the application load the NavigationController and then have the navigation controller push your MyBarcodeDialog view to the foreground.

To accomplish this we are going to modify the FinishedLaunching method.

public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        
{
     // If you have defined a view, add it here:
            
     window.AddSubview (navigation.View);

     navigation.PushViewController(new MyBarcodeDialog(), true);

     window.MakeKeyAndVisible ();
    
     return true;
        
}

Basically what we did here was to add the navigation controller to the window’s SubView.  Then we use the navigation outlet (property) to push our new MyBarcodeDialog view controller into view.

Running the application now will result in the following form:

image

We now have a simple iPhone / iTouch application.  Now we will hook up the code for barcode scanning.

First we need to copy the libLineaSDK.a library file into our project folder.  This file is not distributed with the example code here because you need to sign up to be a developer with Integrated Peripherals and sign an NDA in order to acquire the SDK.

Next, we need to tell MonoTouch how to find the LineaSDK library and how to link it in to the project.  This next section allows no room for error.  Everything must be as described here or it will not work.  This has to do with the way that the LineaSDK is compiled and a nasty bug in the XCode linker.

Right click on the project and choose Options.

image

Click on iPhone Build and choose iPhone from the platform combo box.

Choose Don’t link in the linker behavior and paste the Extra arguments below.

-v -gcc_flags "-L${ProjectDir} -lLineaSDK -framework AudioToolbox -framework CoreGraphics -framework ExternalAccessory -ObjC"

Click OK to close the options window.

In order to use the barcode hardware, we need to edit the .plist file.  This file contains properties and values that tell the iOS information about your application.  In this case we need to tell the iOS that we want to allow the Linea hardware to talk to our app.  Double click on the Info.plist file to open up the plist editor.

image

Here we have to add two properties.

First, click on the Information Property List node and then click Add Child.

For the name enter UISupportedExternalAccessoryProtocols.  Click enter then right click on the property, choose value type and select Array.  Now we need to add two items to the array.

image

Click the button to the right of the property value.  This will add a child to the property.  It will auto name the property Item 0.  Enter com.datecs.linea.pro.msr

Click the button again to create Item 1.  Enter com.datecs.linea.pro.bar

Save and close the plist editor.

Now we need to create a class file that will provide an interface to the LineaSDK library.  This class file will be compiled with the btouch compiler provided with MonoTouch.  I will not go through that process here but I included the compiled DLL and the .CS class file used to generate the DLL.  This class is basically an interop class that provides an interface for the C# managed mono code to talk to the native LineaSDK.

The class I used looks like this:

using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.ObjCRuntime;
using MonoTouch.UIKit;
using MonoTouch.ExternalAccessory;

namespace LineaSDK
{
    [BaseType (typeof (NSObject))]
    [Model]
    interface LineaDelegate {
        
        //-(void)connectionState:(int)state;
        [Abstract]
        [Export( "connectionState:" )]
        void ConnectionStateChanged( int state );
        
        //-(void)buttonPressed:(int)which;
        [Export ("buttonPressed:")]
        void ButtonPressed (int which);

        //-(void)buttonReleased:(int)which;
        [Export ("buttonReleased:")]
        void ButtonReleased (int which);

I attached this code here:

Here is the compiled DLL

You can learn how to compile this on your own here.

We now need to reference this class.  Right click on references and add the LineaSDK.dll to your project.

Your solution should now look like this:

image

We are getting close now.  We need to create two more classes to use with the LineaSDK.  An event message class and a LineaDelegate implementation. 

First we create the BarcodeMessageEventArgs.cs class in the project.  The code should look like this:

using System;
namespace MTBarcodeExample
{
    public class BarcodeMessageEventArgs : EventArgs
    {
        public BarcodeMessageEventArgs ()
        {
        }
        
        public BarcodeMessageEventArgs (string message)
        {
            Message = message;
        }
        
        
        public string Message {
            get;
            set;
        }
    }
}

Next, we need to implement the Linea Delegate interface.  Add a new class to your project named MyLineaDelegate.cs.

Use the following code:

using System;
namespace MTBarcodeExample
{
    public class MyLineaDelegate : LineaSDK.LineaDelegate
    {
        public override void ConnectionStateChanged (int state)
        {
            System.Diagnostics.Debug.WriteLine("ConnectionStateChanged: " + state.ToString());
        }
        
        public override void BarcodeDataReceived (string barcode, int type)
        {
            System.Diagnostics.Debug.WriteLine("Got barcode: " + barcode);
            
            if ( GotBarcode != null )
                GotBarcode.Invoke(this, new BarcodeMessageEventArgs(barcode));
        }
        
        public event EventHandler<BarcodeMessageEventArgs> GotBarcode;
    }
}

Now we can start using the LineaSDK and interact with the barcode scanner.

In the MyBarcodeDialog.cs class file we are going to add a method and an event handler.  This code will setup the SDK interface, connect to the hardware and update our textbox in the event of a barcode scan.

private void initHardware()
{
    Linea             = new LineaSDK.Linea();
    LineaDelegate     = new MyLineaDelegate();
    Linea.Delegate     = LineaDelegate;
    
    LineaDelegate.GotBarcode += HandleLineaDelegateGotBarcode;
    
    Linea.Connect();
}

void HandleLineaDelegateGotBarcode (object sender, BarcodeMessageEventArgs e)
{
    this.InvokeOnMainThread( delegate { txtBarcode.Value = e.Message; } );
}

The last thing to do here it to update the constructor to make sure the initHardware method is called.

public MyBarcodeDialog () : base(null)
{
   initView();
   initHardware();
}

Compile the code, deploy to the device, then run the application.  When the view loads you should see your form.  Clicking the scan button on the laser barcode hardware should scan barcodes into the Barcode field on the view.

image

 

There were a great many steps in this example but once you get this far you have a base scanning application.  Your next step should be to explore MonoTouch.Dialog and make a more complex application.

Download the full MonoDevelop solution below.  Please note that the LineaSDK library and any bits that belong to Infinate Periferals has been removed from this project.  You will need to add the libLineaSDK.a file in to the project folder yourself.

Download Source: MTBarcodeExample.zip


Download Source: MTBarcodeExample.zip



Asynchronous Programming for C# / Visual Studio Async CTP

clock October 29, 2010 18:15 by author dsandor

Download and more reference material here:

http://msdn.microsoft.com/en-us/vstudio/async.aspx

Great crash course article from Alexandra Rusina here:

http://blogs.msdn.com/b/csharpfaq/archive/2010/10/28/async.aspx

Executive summary:

Basically you get two new powerful C# language keywords, await and async.  Instead of having to write callback methods for multithreaded code, you can now decorate a method signature with async and call the method with await. You write the code as if it were a synchronous block of code and let the runtime perform the heavy lifting.  Very cool and really streamlined.  I wonder what debugging will look like. 



Two MVVM snippets I use a lot: ViewModelBase and ModelBase

clock September 5, 2010 18:03 by author dsandor

I use these two snippets a lot for WPF and Silverlight development.  I decided to post them on the blog so that I have them available to me whenever and wherever.  I always seem to be searching through older projects for this code.

vmb

This snippet creates the ViewModelBase that I use almost everywhere.  It simply implements INotifyPropertyChanged and works in both WPF and Silverlight.  I use this for my ViewModels so that the properties on the VM are observable for databinding.  I use this in conjunction with my propsn snippet that creates a property with SafeNotify calls in the setter.

mb

This snippet is used to create the ModelBase.  Again, this is a WPF / Silverlight compatible class.  I link my model such that it compiles for WPF and Silverlight so that I can share my model between my WCF and my UI.  This class gives me INotifyPropertyChanged, SafeNotify, and a ToString implementation that uses reflection to dump a shallow representation of the class.

Hope this code helps someone.



Make Visual Studio 2010 even better with Productivity Tools

clock August 7, 2010 06:38 by author dsandor

If you have not installed the latest version of the Visual Studio Productivity Power Tools (The LATEST release that is), you are missing out on some killer functionality.

Download them here:
http://visualstudiogallery.msdn.microsoft.com/en-us/d0d33361-18e2-46c0-8ff2-4adea1e34fef

There is now a Solution Navigator:

image

Advanced object information when hovering over an object or method with your cursor:

image

image

image

Cool new color coded gradient backed tabs:

image

Pinning of tabs is still supported:

image

 

Check out more info on the Visual Studio Blog
http://blogs.msdn.com/b/visualstudio/archive/2010/07/20/solution-navigator-blog-post.aspx

Download the latest version of the Productivity Power Tools
http://visualstudiogallery.msdn.microsoft.com/en-us/d0d33361-18e2-46c0-8ff2-4adea1e34fef



Solved: Objects are not fully deserializing when using DataContractSerializer in Silverlight.

clock July 7, 2010 02:53 by author dsandor

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer_members.aspx

So as it turns out, your XML stream must have the XML Nodes in Alphabetical Order when trying to deserialize XML data into an object.  Very wierd.



Silverlight Hover Button – XAML Style implementation with code that is dynamic and skinnable.

clock July 6, 2010 04:52 by author dsandor

So I needed to create a hover button.  The idea is that when the mouse rolls over the button the image will flip between a normal and ‘over’ version of the button image.  This is the same thing as old school image rollover code we have all used before.  There is an image that you use for a button in the ‘normal’ or ‘off’ state and when the mouse rolls over the image the picture changes to the ‘over’ or ‘on’ state.

It is pretty easy to do this statically.  Edit the button style, slap a couple of images in the ControlTemplate and tie that to the Normal and MouseOver visual states and you are done.

But what if you want to be able to use that same style for all your buttons and you want to be able to databind the Normal and MouseOver images?

This was pretty easy with a trick here or there.

First, we need to create a HoverButton class that inherits from the standard Button.  We need to do this because we need 2 new properties for our Normal and Over image url’s.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
 
namespace MySLApplication.Local
{
    public class HoverButton : Button
    {
 
 
        public string NormalImageUrl
        {
            get { return (string)GetValue(NormalImageUrlProperty); }
            set { SetValue(NormalImageUrlProperty, value); }
        }
 
        public static readonly DependencyProperty NormalImageUrlProperty =
            DependencyProperty.Register("NormalImageUrl", typeof(string), typeof(HoverButton), 
            new PropertyMetadata(""));
 
 
 
        public string MouseOverImageUrl
        {
            get { return (string)GetValue(MouseOverImageUrlProperty); }
            set { SetValue(MouseOverImageUrlProperty, value); }
        }
 
        public static readonly DependencyProperty MouseOverImageUrlProperty =
            DependencyProperty.Register("MouseOverImageUrl", typeof(string), typeof(HoverButton), 
            new PropertyMetadata(""));
 
 
 
    }
}

This is the button you will place on your design surface instead of the regular button.  This one gives us NormalImageUrl and the MouseOverImageUrl.  These properties we will set to the URL for the images we want to use for our normal state and mouse over state.

Next is the Style (see the zip file at the bottom of this post for the actual code).  Since the Style is so big, I will describe the important pieces to you.

First, your XAML that contains this style code needs to have a namespace reference to the HoverButton’s namespace.  I named mine local so you will see my TargetType set to local:HoverButton.

xmlns:local="clr-namespace:MySLApplication.Local"

So the style starts out like this:

<Style x:Key="HoverButtonStyle" TargetType="local:HoverButton">
            <Setter Property="Background" Value="#FF1F3B53"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Height" Value="36" />
            <Setter Property="Width" Value="118" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:HoverButton">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">

Note the TargetType in both instances is pointed to the local namespace and the HoverButton class name.  The real magic occurs in the ControlTemplate portion of the code.  Here there are several Visual States defined.  We are concered with two of them (feel free to extend this to the others also): Normal and MouseOver.

You will notice in each of the two Visual States we are concerned with there is a storyboard.  The StroryBoard executes when the visual state is entered.  So for example, when the button starts out it is in the Normal state.  When the control is rendered the Normal visual state causes the storyboard defined here to execute:

 

<VisualState x:Name="Normal">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" 
        Storyboard.TargetName="OverImage">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" 
        Storyboard.TargetName="NormalImage">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

What happens here is that the StoryBoard sets the OverImage’s Visibility property to Collapsed and the NormalImage’s Visibility property to Visible. 

Before confusion sets in, scroll down to the bottom of the style.  You will see the two images we just discussed.

<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" 
   Content="{TemplateBinding Content}" 
   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
   Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Image x:Name="NormalImage" DataContext="{TemplateBinding NormalImageUrl}" Source="{Binding}" />
<Image x:Name="OverImage" DataContext="{TemplateBinding MouseOverImageUrl}" Source="{Binding}" />

The two images defined inside the button’s visual surface are the actual images you will see at runtime.  Notice that we had to set the DataContext of the Image control to the property NormalImageUrl and MouseOverImageUrl and THEN set the Source property to {Binding}.  You need this little trick in order to allow databinding to convert the string based URL to an ImageSource.

So now we are good to go.  We can use our HoverButton like this:

<local:HoverButton Content="" Height="36" HorizontalAlignment="Left" 
    Margin="508,558,0,0" x:Name="btnSpin" VerticalAlignment="Top" Width="118" 
    Click="btnSpin_Click" Style="{StaticResource HoverButtonStyle}"
    NormalImageUrl="http://yourdomain.com/Normal.png"
    MouseOverImageUrl="http://yourdomain.com/Over.png"/>

So now you can specify the Normal and MouseOver images for your button.  The same style can be used for all these hover buttons, just specify the 2 images and you are set. 

 

Download File - HoverButtonSource

 

 

 

 

 

 



Serialize and Deserialize in Silverlight ( XmlSerializer does not exist ).

clock July 6, 2010 02:18 by author dsandor

Many thanks to Einar Ingebrigsten!  I needed to serialize and deserialize some configuration data in one of my Silverlight projects I am currently working on.  This really came in handy:

http://www.ingebrigtsen.info/post/2008/11/29/Serialization-in-Silverlight.aspx

The executive summary is that you can use the DataContractSerializer without the need for DataContract or DataMember attributes.  Einar even gives you some sweet helper methods for Silverlight to make your life even easier.



Solved: Cannot resolve TargetProperty (UIElement.RenderTransform).(CompositeTransform.TranslateY) on specified object.

clock July 4, 2010 05:02 by author dsandor

I was using Blend 4 to do some simple animations then copy and pasting the storyboard for use on other objects in my application.  When I executed the Begin() method on the storyboard I would get the following:

Cannot resolve TargetProperty (UIElement.RenderTransform).(CompositeTransform.TranslateY) on specified object.

My XAML was pretty basic.  I finally noticed that Blend had populated the RenderTransform property for me on the working objects.  When I cut and pasted and updated the target object I failed to add the render transform.  Doing so fixes the problem:

Working:

<local:Tile ImageUrl="/SL;component/Images/02_100x100.png" Margin="0,200,0,0" Height="100"
 Width="100" VerticalAlignment="Top" x:Name="Tile_2"
 RenderTransformOrigin="0.5,0.5" >
   <local:Tile.RenderTransform>
        <CompositeTransform/>
   </local:Tile.RenderTransform>
</local:Tile>

Not working:

<local:Tile ImageUrl="/SL;component/Images/02_100x100.png" Margin="0,200,0,0" Height="100"
 Width="100" VerticalAlignment="Top" x:Name="Tile_2"
 RenderTransformOrigin="0.5,0.5" >
</local:Tile>
 

So if you get this message it is basically telling you that you are missing the RenderTransform property on the target object.



How To: Make a complex clipping path in Blend 4.

clock July 3, 2010 18:38 by author dsandor

This how-to will show you a few simple steps to making a clipping path in Blend 4.  Below is a mockup of my basic canvas (this is a PNG imported into Blend).  I want to make the green area visible and I want to clip the while rectangles out of the image.  Eventually, I will place some animated elements where the white rectangles are.

game-mockup

The first thing you want to do is to draw rectangles where you want the image to be visible.

image 

Now that I have all of my purple rectangles drawn out I am ready to convert them to a clipping path.

Remember, the rectangles are the areas that will be visible on the clipped object.

image

Choose the direct select tool: image and select all of your rectangles.  Hold down the CTRL key and you can multi-select.  You can also select the rectangles from the Objects and Timeline window.

image

Choose Object | Path | Convert to Path from the Blend menu.  This converts all your rectangles to a path which we will in turn convert to a clipping path.

image

Next, go back to Object | Path on the menu and choose Make Compound Path.  This will make one complex path from your individual paths.

image

Now that you have one compound path select the Path object from the Objects and Timelines window.  Now you can go back to Object | Path and you have the option to Make Clipping Path.

image

Now you choose the object to clip and you will now have a clipped object (an image in my case). 

image

Here is the end result in the Blend designer:

image

And here is the nice clean XAML you generated (please note, for space constraints I truncated the path data in the Clip property):

    <Grid x:Name="LayoutRoot" >
        <Image Margin="0" Source="Images/game-mockup.png" Stretch="Fill" 
         Clip="M0.5,0.5 L799.5,0.5 L799.5,202.5 L0.5,202.5 z M0.5,203.5 ... z">
        </Image>
    </Grid>


Solved: The C++ module failed to load while attempting to initialize the default appdomain.

clock July 2, 2010 20:37 by author dsandor

Summary of Errors:

Exception of type 'System.Web.HttpUnhandledException' was thrown.

The type initializer for '' threw an exception.

The C++ module failed to load while attempting to initialize the default appdomain.

Illegal operation attempted on a registry key that has been marked for deletion.

 

The full ugly error:

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The type initializer for '' threw an exception. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.TypeInitializationException: The type initializer for '' threw an exception. ----> System.TypeInitializationException: The type initializer for '' threw an exception. ----> .ModuleLoadException: The C++ module failed to load while attempting to initialize the default appdomain. ----> System.Runtime.InteropServices.COMException: Illegal operation attempted on a registry key that has been marked for deletion. (Exception from HRESULT: 0x800703FA) at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at .GetDefaultDomain() at .DoCallBackInDefaultDomain(IntPtr function, Void* cookie) at .LanguageSupport.InitializeDefaultAppDomain(LanguageSupport* ) at .LanguageSupport._Initialize(LanguageSupport* ) ...). --- End of inner exception stack trace --- at System.Web.UI.Page.HandleError(Exception e) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) at System.Web.UI.Page.ProcessRequest(HttpContext context) at ASP.fieldreceiptdetail_aspx.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Solution:

This problem was related to a cross-appdomain failure.  We are using the Microsoft Dynamics AX 2009 Business Connector in this application.  The Business Connector is a C++ application that we use to talk to AX.  From what I can gather, there are two applications using the C++ DLL at the same time.  The problem is that the DLL is mixing appdomains because of our Application Pool setup in IIS 7. 

image

So to solve the problem, I created a new Application Pool for this application.  I also set the pipeline mode to Classic.  This solved the problem for me.



New certifications added to my Resume this week.

clock July 1, 2010 22:29 by author dsandor

So I went in and took 5 of the 6 new beta exams (the 6th one was the TS Exam for Web, that one was full and could not take it for free) and I am happy to say I passed 5 of the 5 I took.  I just need to take the Web TS and I should add Web Developer 4 and Enterprise Developer 4 to the MCPD.

Now my Microsoft Certifications look like this:

519
Pro: Designing and Developing Web Applications Using Microsoft .NET Framework 4.0
Apr 09, 2010

518
Pro: Designing and Developing Windows Applications Using Microsoft .NET Framework 4.0
Apr 08, 2010

516
TS: Microsoft .NET Framework 4, Accessing Data with ADO.NET
Apr 07, 2010

513
TS: Microsoft .NET Framework 4, Windows Communication Foundation Development
Apr 06, 2010

511
TS: Microsoft .NET Framework 4, Windows Applications Development
Apr 05, 2010

MCPD(rgb)_1371MCTS(rgb)_1269_1374_1369_1373_514

MCSE(rgb)

 

MCPI(rgb)

MCPSB(rgb)



Setting maxArrayLength value for a customBinding using binaryMessageEncoding.

clock May 24, 2010 22:52 by author dsandor

So as it turns out pretty much all the examples I have read online show no attributes when using the binaryMessageEncoder.

As it turns out, just like text encoding, you can add a readerQuotas element like this:

<binding name="MaintenanceServiceBindingConfiguration">
  <binaryMessageEncoding>
      <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
  </binaryMessageEncoding>
  <httpTransport maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
          maxReceivedMessageSize="2147483647" />
</binding>


MockupToXaml codeplex project progression.

clock May 18, 2010 06:47 by author dsandor

The UI for the converter kind of stinks right now because I have been concentrating on functionality.  I am now rendering XAML via plug-in modules.  In addition a preview of the rendered XAML is displayed after generating the XAML.

The UI is really basic right now:

image

Click the Load Mockup button to locate a .BMML mockup file.

image

The BMML document is parsed into a set of .NET objects.  For now, the controls are displayed in a grid.  This is going to be removed.  It was mainly used while coding the Mockup XML parsing logic.

image

Clicking generate will generate the XAML in the texbox at the bottom of the form.

image

In addition to generating the XAML, it is parsed at runtime and the Mockup is compiled at runtime and previewed.

image

That is the preview of the XAML rendered from my mockup below:

image

I still need to include the properties and sample data in the Xaml controls.  But for now, we have a start.



About the author

David Sandor is a Software Architect working in Chicago, IL.  My development focuses around the Microsoft Stack including Azure, AppFabric, Silverlight, WPF, .NET Framework, and various mobile devices including iOS (iPhone/iTouch), Android, Windows Mobile and Windows Phone 7.

Month List

Sign in