Silverlight Gantt Chart - Design Mode

3. June 2011 05:11

Great news!  The designer works for the Gantt Chart again.  I know it's been a while and a lot of you were waiting, so thanks for your patience.

 

http://www.coderforrent.com/Products/SilverlightGanttChart


New Control! Silverlight AutoScrollViewer.

17. March 2011 18:35

I was inspired by the Zune's quickstart page and came up with this really handy control.  Let me know what you think!

 

http://www.coderforrent.com/Products/SilverlightAutoScrollViewer


Mouse Wheel and the ScrollViewer

22. October 2010 03:40

Today I had a problem where the ScrollViewer in my user control would not scroll using the mouse wheel unless it was over a control like a textbox or label... anything other than the grid that is LayoutRoot.  It went something like this:


 <ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Padding="1" BorderThickness="0" >

<Grid x:Name="LayoutRoot" >

 

After much trial and error, I figured out that all is needed is a background... it can even be set to Transparent. So, I did this:

 


   <ScrollViewer Grid.Row="0"  VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Padding="1" BorderThickness="0" >
                <Border Background="Transparent">
                    <Grid x:Name="LayoutRoot"  >

 

I know it is simple and probably makes me look like igmo, but I thought it might help somebody else one day. :)


Silverlight 4 - Encode and Decode Jpeg

17. October 2010 18:02

By using the FJ.Core library, I was able to create a WriteableBitmapExtentions class that does a lot the work for encoding and decoding jpg's in Silverlight 4.  Most of the ideas came from Kodierer, but his decoder was jacked and it took me most of the day to figure out why, so I though it would be nice to put it here in case someone else needed it.

 

public static class WriteableBitmapExtentions
    {
        public static byte[] ToByteArray(this WriteableBitmap bmp)
        {
            int[] p = bmp.Pixels;
            int len = p.Length * 4;
            byte[] result = new byte[len]; // ARGB    
            Buffer.BlockCopy(p, 0, result, 0, len);
            return result;
        }

        public static void FromByteArray(this WriteableBitmap bmp, byte[] buffer)
        {
            Buffer.BlockCopy(buffer, 0, bmp.Pixels, 0, buffer.Length);
        }
        public static byte[] EncodeJpeg(this WriteableBitmap bmp)
        {
            MemoryStream ms = new MemoryStream();
            EncodeJpeg(bmp, ms);
            return ms.ToArray();
        }
        public static void EncodeJpeg(this WriteableBitmap bmp, Stream destinationStream)
        {
            // Init buffer in FluxJpeg format   
 
            int w = bmp.PixelWidth;
            int h = bmp.PixelHeight;
            int[] p = bmp.Pixels;
            byte[][,] pixelsForJpeg = new byte[3][,];

            // RGB colors   

            pixelsForJpeg[0] = new byte[w, h];
            pixelsForJpeg[1] = new byte[w, h];
            pixelsForJpeg[2] = new byte[w, h];

            // Copy WriteableBitmap data into buffer for FluxJpeg   
            for (int row = 0; row < h; row++)
            {
                for (int column = 0; column < w; column++)
                {
                    int pixel = bmp.Pixels[w * row + column];
                    pixelsForJpeg[0][column, row] = (byte)(pixel >> 16);
                    pixelsForJpeg[1][column, row] = (byte)(pixel >> 8);
                    pixelsForJpeg[2][column, row] = (byte)pixel;
                }
            }
            // Encode Image as JPEG using the FluxJpeg library   
            // and write to destination stream  

            ColorModel cm = new ColorModel { colorspace = ColorSpace.RGB };
            FluxJpeg.Core.Image jpegImage = new FluxJpeg.Core.Image(cm, pixelsForJpeg);
            JpegEncoder encoder = new JpegEncoder(jpegImage, 50, destinationStream);
            encoder.Encode();
        }
        public static WriteableBitmap DecodeJpeg(Stream sourceStream)
        {
            // Decode JPEG from stream   

            var decoder = new FluxJpeg.Core.Decoder.JpegDecoder(sourceStream);
            var jpegDecoded = decoder.Decode();
            var img = jpegDecoded.Image;
            img.ChangeColorSpace(ColorSpace.RGB);

            // Init Buffer 

            int w = img.Width;
            int h = img.Height;
            var result = new WriteableBitmap(w, h);
            int[] p = result.Pixels;
            byte[][,] pixelsFromJpeg = img.Raster;
            int i = 0;
              
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
              
                        p[i++] = (0xFF << 24)                    // A   
                            | (pixelsFromJpeg[0][x, y] << 16) // R     
                            | (pixelsFromJpeg[1][x, y] << 8)  // G      
                            | pixelsFromJpeg[2][x, y];       // B      
               
                }
            }
     
            return result;
        }
 
    }

 


Blacklight.Controls.DragDockPanel - Maximize To Fullscreen

2. September 2009 04:06

The Problem

Sometimes you want to maximize the contents of the DragDockPanel to encompass the entire Host control area.  If this is a fullscreen app, this would be the entire browser.

 

 

The Solution

The code for this can be found in the CoderForRent.ProductManager.Client.Controls assembly.  I tried listing it here, but there's just too much.

Here is a link to the CodePlex Source code page.

 

The Example

The Product Manager uses a child class (SettingsDragDockPanel) of this control in the dashboard on the home page and a live demo can be found at pim.coderforrent.com.  The code for SettingsDragDockPanel can be found in that codeplex app as well.

 


Silverlight/WCF - (404) Not Found - BEGONE!

25. August 2009 04:08

The Problem

The first problem is that any error thrown in the WCF layer of the application will be returned to Silverlight as "The remote server returned an unexpected response: (404) Not Found".  This isn't helpful in the least bit.  For now, let's not ask the obvious question, "Why not return better errors?"  Instead, let's look for a solution that we can control. 

Additionally, we need means to track the errors that are thrown in both the server and client.

The Basic Solution

 

The (404) Not Found Error

The first reason people get this error when they get started is because the iis root does not have the clientaccesspolicy.xml file defined properly.  This post should help you out there.  If you have this in place and you are still getting the error, make sure it is in the IIS root directory.  In Visual Studio, you can use the Development Server or the local IIS to host the WCF application.  If you use the Visual Studio Development Server, make sure the "Virtual path" is "/" and not some extended path.  Adding some virtual path here will make it impossible for you to add the clientaccesspolicy.xml file as there is no "root" directory.  It should look something like the picture below (note: you can assign any port number that you'd like).

 

 

 

 

Better Error Handling

The previous section will more than likely get you past the new project woes of 404 Not Found, but we still have to be able to track errors in our application in a responsible way.  We don't want the user of the application to see our ugly error messages, so our solution will have to be fault safe and any single error should not result in complete application failure.

 

Step 1 - Create a common Result object

We will ALWAYS return an object from the web service call (no void calls).  This means that the only server error that can occur (and not get handled) will be a bad connection to the server. A simple example of the Result object is:

[DataContract]
public class Result
{
[DataMember]
public bool HasError{get; set;}

[DataMember]
public string CustomMessage{get; set;}

public Result(){
   HasError = false;
   CustomErrorMessage = null;
}

public Result(ErrorLog err){
   HasError = true;
   CustomErrorMessage = "An error has occurred.";

}
}

 

 

Step 2 - Create an ErrorLog data store and ErrorManager class for the server

The data store can be of any type that you choose, but for the purposes of this article, I will assume a SQL Table named ErrorLog.  This table can be defined as :

 

 

 

You can of course add other fields if you have a need, such as Message, etc.  This works for our purposes. 

Defining a class called ErrorLogManager will give you an easy way to pass errors to the database.  It can be defined as:


public class ErrorLogManager
{
public static ErrorLog HandleException(Exception exc, string module, string userId)
{
//This is Linq To Sql, but you could use anything.  It's a black box.

using(MyDataContext db = new MyDataContext)
{
  ErrorLog err = new ErrorLog();
  err.StackTrace = exc.StackTrace;
  err.Module = module;
  err.UserId = userId;
  err.DateCreated = DateTime.Now;

  db.ErrorLogs.InsertOnSubmit(err);
  db.SubmitChanges();

  return err;
}
}
}

 

Step 3 Writing the Service

 

I won't spend any time explaining the service layer as it is unimportant, but the basic setup should be like this:

[OperationContract]
public Result DoSomething()
{
     try
     {
         return BusinessManager.DoSomething();
     }
     catch(Exception exc)
     {
        return new Result(ErrorLogManager.HandleException(exc, "Foo", "Bar"));
     }
}
 

 

Step 4 Extending the Result Object

It wouldn't be very useful if the error framework didn't allow other custom Data Transfer Objects to be passed in addition to the error information.  We can inherit from the Result class an create a generic Result<T> that will solve this issue:

[DataContract]
public class Result<T> : Result
{

[DataMember]
public T Item{get; set;}
public Result(T item) : base()
{
this.Item = item;
}

public Result(ErrorLog err) : base(err)
{
  Item = null;
}

}

I have also found it useful to have a Resultlist<T> option as well:

[DataContract]
public class ResultList<T> : Result
{

[DataMember]
public List<T> Items{get; set;}
public ItemResult(T items) : base()
{
this.Items = items;
}

public ItemResult(ErrorLog err) : base(err)
{
  Item = null;
}

}

 

The Example

 

Our Product Information Manager uses this model in the latest builds.  It is the only open source example of this method that I know of.

 

 


Custom Development

ALL USA BASED DEVELOPERS

 

Coder For Rent is a one-stop shop for all your .Net programming needs.  We can make project-based fixed bids as well as hourly/weekly/monthly quotes.  Our goal is to meet your needs the first time, saving you time and money.

 

Call to speak with an account manager. We take projects of all sizes.

 

713-482-7155 

Contact Us

Call 713-482-7155 
for technical or purchasing support

Freshbooks Rocks

FreshBooks

Silverlight Gantt Chart Control
Silverlight Scheduler Control