Embedding Fonts in your .Net Application Part 2

by Brian Brewder October 08, 2011 17:41

In my last article I showed a simple, but naive way to embed fonts in your application. The problem with the other approach is that the operating system combines multiple font files into a single font family, each file containing a style (such as bold or italic) that is available. So if you added Arial regular and Arial bold font files to the PrivateFontCollection, you would only have a single FontFamily in the collection.

A better approach is to continue using font family names as strings to create the font. The FontFamily class has a constructor that takes a FontCollection which allows you to send in the PrivateFontCollection that you added your embedded font to.

Here is a better solution for embedding fonts. You can register fonts externally during application startup, then, whenever you need a font, just call FontHelper.Create. This method will create any font, including fonts installed on the system.

public class FontHelper
{
    private static PrivateFontCollection sCustomFonts;
    private static Dictionary<string, FontFamily> sFamilies;

    static FontHelper()
    {
        sCustomFonts = new PrivateFontCollection();
        sFamilies = new Dictionary<string, FontFamily>(
            StringComparer.InvariantCultureIgnoreCase);
    }

    public static void RegisterFont(byte[] font)
    {
        var buffer = Marshal.AllocCoTaskMem(font.Length);
        Marshal.Copy(font, 0, buffer, font.Length);
        sCustomFonts.AddMemoryFont(buffer, font.Length);
    }

    public static void RegisterFont(string fontFilePath)
    {
        sCustomFonts.AddFontFile(fontFilePath);
    }

    public static FontFamily[] GetAllFamilies()
    {
        var families = new List<FontFamily>();
            
        families.AddRange(FontFamily.Families);
        families.AddRange(sCustomFonts.Families);

        families.Sort((f1, f2) => { return f1.Name.CompareTo(f2.Name); });
        return families.ToArray();
    }

    public static FontFamily GetFamily(string family)
    {
        try
        {
            // cache the family in a dictionary for fast lookup.
            if (!sFamilies.ContainsKey(family))
                sFamilies.Add(family, new FontFamily(family, sCustomFonts));
        }
        catch (ArgumentException)
        {
            sFamilies.Add(family, new FontFamily(family));
        }
        return sFamilies[family];
    }

    public static Font Create(
        string family, 
        float emSize, 
        FontStyle style = FontStyle.Regular, 
        GraphicsUnit unit = GraphicsUnit.Pixel)
    {
        var fam = GetFamily(family);
        return new Font(family, emSize, style, unit);
    }

}

You would use this class like this. MyFonts is simply a resource file (.resx) that I added to my project and dragged the font file (.ttf) into.

FontHelper.RegisterFont(MyFonts.Consolas);
using(var font = FontHelper.Create("Consolas", 12))
{
    // Use the font
}

Unfortunately I am not able to use this code for work. One of the requirements we have is that we must embed the fonts into PDF files. As much as I would like to deploy without installing fonts, it is much easier to embed fonts with the PDF library we are using when they are installed on the machine.

Tags:

Embedding Fonts in your .Net Application

by Brian Brewder September 17, 2011 18:40

WARNING: This article contains code that is a bit naïve. My new article shows a better way of dealing with fonts: Embedding Fonts in your .Net Application Part 2

At my job, I’m working on converting our Classic ASP application to .Net. One of my goals for the project is to make sure it can be XCopy deployed. This makes it much easier to setup development, test, staging, and production environments. Recently I found myself in a situation where we needed to use a font that wasn’t installed on the server by default (we create some graphics with text in them). Instead of installing the fonts on the server, I decided to learn how to embed the font as a resource in an assembly. Here’s what I came up with.

If you want to follow along, here’s how to go about setting this up:

  1. Create a console application in Visual Studio (this technique works in any type of project, but the console app is used for demo purposes).
  2. Create a folder called Fonts.
  3. Add a ttf file to the folder. You can find ttf files in your fonts directory (C:\Windows\Fonts) or you can download one from the Internet. You will probably want to rename the file to better reflect the name of the font.
  4. Create a resource file in the Fonts directory. For the demo, I called mine MyFonts.
  5. Add the font to the resource file. You can do this by opening the resource file in Visual Studio and dragging the font you added in step 3 into it.
  6. Create a static class called ResFonts in the Fonts directory.
  7. Create an enumeration called ResFontFamily and add an entry for each font you want to expose. Make sure the numbering for the fonts start at 0. The enum value is used as the index into the fonts collection.
  8. Create a private static field of type PrivateFontCollection. This class is in the System.Drawing.Text namespace. You will probably need to reference System.Drawing.dll to access it.
  9. Initialize the field in a static constructor (don’t worry, the code is below).
  10. Add a static method called Create that takes the enumeration value and a couple other values used for initializing the font and returns the Font. You can use this font just like you use fonts created in the more traditional way (don’t forget to dispose of it).

 

Now for the code…

using System.Drawing;
using System.Drawing.Text;
using System.Runtime.InteropServices;
namespace EmbeddedFonts.Fonts
{
    public class ResFonts
    {
        private static PrivateFontCollection sFonts;
        static ResFonts()
        {
            sFonts = new PrivateFontCollection();
            // The order the fonts are added to the collection 
            // should be the same as the order they are added
            // to the ResFontFamily enum.
            AddFont(MyFonts.Consolas);
        }
        private static void AddFont(byte[] font)
        {
            var buffer = Marshal.AllocCoTaskMem(font.Length);
            Marshal.Copy(font, 0, buffer, font.Length);
            sFonts.AddMemoryFont(buffer, font.Length);
        }
        public static Font Create(
            ResFontFamily family, 
            float emSize, 
            FontStyle style = FontStyle.Regular, 
            GraphicsUnit unit = GraphicsUnit.Pixel)
        {
            var fam = sFonts.Families[(int)family];
            return new Font(fam, emSize, style, unit);
        }
    }
    public enum ResFontFamily
    {
        /// <summary>Consolas</summary>
        Consolas = 0
    }
}

And here’s an example of how you can use the fonts (the highlighted line is the call to our embedded fonts class)…

using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using EmbeddedFonts.Fonts;

namespace EmbeddedFonts
{
    class Program
    {
        static void Main(string[] args)
        {
            var str = args.Length > 0 ? args[0] : "Hello World!";
            using (var f = ResFonts.Create(ResFontFamily.Consolas, 26))
            {
                SizeF sz;
                using (var szBmp = new Bitmap(1, 1))
                using (var g = Graphics.FromImage(szBmp))
                    sz = g.MeasureString(str, f);

                var bmp = new Bitmap((int)sz.Width + 4, (int)sz.Height + 4);
                using (var g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.DrawString(str, f, Brushes.Black, 3, 3);
                    g.DrawString(str, f, Brushes.White, 1, 1);
                }

                var path = Path.Combine(Path.GetTempPath(), "test.png");
                bmp.Save(path, ImageFormat.Png);
                Process.Start(path);
            }

        }
    }
}

I hope this code proves useful to you. If you see any way to improve it, please let me know.

Tags:

wlwmanifest.xml Options Documented

by Brian Brewder October 12, 2010 00:36

There are a ton of options for Windows Live Writer, unfortunately most of them are undocumented. I have compiled a list of options that are available in Windows Live Writer 2011.

I have not tried them all out, but I have added descriptions where I can. If you have additional information about any of these, let me know and I’ll update my post.

Option

Change to Writer

API changes

supportsPostAsDraft Enables the “Post draft to blog” button. publish parameter (last one) is set to false if publishing as a draft.
supportsFileUpload    
supportsExtendedEntries    
supportsCustomDate Allows the user to set the post date (“Set post date”). Post.dateCreated is set.
supportsCustomDateUpdate    
supportsHttps    
supportsCategories Shows the categories for the user to pick from for the post. See supportsCategoriesInline.
supportsCategoriesInline   If Yes, metaWeblog.getCategories is called. If No, mt.getCategoryList is called.
supportsMultipleCategories Allows the user to select multiple categories (checkboxes instead of radio buttons).  
supportsHierarchicalCategories    
supportsNewCategories Allows the user to enter new categories.  
supportsNewCategoriesInline   Includes new categories in Post.categories. If No but supportsNewCategories is Yes, new categories are set by calling wp.addCategory.
supportsSuggestCategories    
categoryScheme    
supportsKeywords Allows user to enter tags. If Yes and tags are entered, sets Post.mt_keywords.
supportsGetTags Determines whether the available tags can be fetched from the provider. If Yes, calls wp.getTags.
supportsCommentPolicy   If Yes, Post.mt_allow_comments is used.

0 - None - No comments allowed
1 - Open - Comments can be read and write 
2 - Closed - Comments can be read but not written

supportsPingPolicy    
supportsAuthor Allows the user to set the author of the post. Calls wp.getAuthors to get the list of authors. Sets Post.wp_author.
supportsSlug    
supportsPassword    
supportsExcerpt Allows the user to set the excerpt. Sets Post.mt_excerpt.
supportsTrackbacks    
supportsPages    
supportsPageParent    
supportsPageOrder    
supportsPageTrackbacks    
linkToSkyDriveSelfPage    
requiresHtmlTitles    
returnsHtmlTitlesOnGet    
supportsEmptyTitles    
supportsScripts    
supportsEmbeds    
supportsImageUpload    
defaultView    
characterSet    
requiresXHTML    
dhtmlImageViewer    
postBodyBackgroundColor    
maxCategoryNameLength    
supportsAutoUpdate    
invalidPostIdFaultCodePattern    
invalidPostIdFaultStringPattern    
templateIsRTL    
maxPostTitleLength If the title is over this number of characters, a message box will be displayed when they attempt to publish and the post cannot be published.  
homepageLinkText Display text for the link to the blog (under Blog Account tab, Shortcuts).  
adminLinkText Display text for the link to the admin console for the blog(under Blog Account tab, Shortcuts).  
adminUrl URL to the admin console(under Blog Account tab, Shortcuts).  
postEditingUrl    
postEditingUrlPostIdPattern    
imageEndpoint    
serviceName    
commentPolicyAsBoolean    
allowPolicyFalseValue    
maxRecentPosts    
contentFilter    
permalinkFormat    
postDateFormat    
fileUploadNameFormat    
useLocalTime    
supportsPostSynchronization    
trackbackDelimiter    
futurePublishDateWarning    
useSpacesTemplateHack    
useSpacesCIDMemberName    
usePicasaImgMaxAlways    
usePicasaS1600h    
keywordsAsTags    

Tutorial: Building a Windows Live Writer Provider in .Net

by Brian Brewder October 09, 2010 18:26

I am building my own blog engine for fun (I just want to learn how this all works) and figured I should start with support for Windows Live Writer since I wanted to make sure my database supported whatever structure Writer supported. This turned out to be a fairly challenging project so I decided I would write an article that walks through the steps of creating a basic provider to hopefully help other developers (and maybe future me Smile) get something up and running quickly.

First off, you should know that Writer uses a combination of MetaWeblog, Movable Type, and WordPress. These are all XML-RPC based APIs. In fact Writer can actually use subsets of these APIs so you can decide what you want to support. You can learn more about this on Microsoft’s site: Windows Live Writer Provider Customization API.

To make your life easier, you should download the Xml-Rpc.Net library created by Charles Cook. This library provides everything you need so you don’t need to worry about the Xml-Rpc protocol. You will just need to create a service with the right methods and the Xml-Rpc.Net library will handle the xml for you.

If you are building your service in .Net 4 you will want to make a change to the library before using it in your project or you might end up with a server error (I reported this to Charles so it might be fixed by the time you download the library). Basically you will want to apply SecurityCriticalAttribute to CookComputing.XmlRpc.XmlRpcFaultException.GetObjectData (src\XmlRpcFaultException.cs, line 76).

    [SecurityCritical]
    public override void GetObjectData

Sample Project

Once you’ve gotten the Xml-Rpc.Net library compiled and ready to go, you can now start creating your project. I’ve created an example project that you can use as reference for your project. The project was created from an empty web project in Visual Studio 2010 and was largely borrowed from Keyvan Nayyeri’s excellent article on this subject.

Download Example Project (look for the Download button)

If you prefer, you can just look at the code in the CodePlex repository, but you won’t be able to run it from there. The code does include a modified version of the Xml-Rpc.Net dll that works with this project.

The first file to look at in the project is the MetaWeblog.ashx file. This file is the common extension used to define a web handler. This one defines the backing class as LiveWriterExample.MetaWeblog.

The next file to look at is MetaWeblog.cs. This file contains the service contract interface IMetaWeblog and the class MetaWeblog (this is the class pointed at in MetaWeblog.ashx). All the methods on the interface have an XmlRpcMethodAttribute applied to them. The name provided is the name of the method as defined in the MetaWeblog API (this is the best reference for what Windows Live Writer supports).

The MetaWeblog class implements the IMetaWeblog interface. This is the critical code for you to modify if you want to create your own provider. Just look for the TODOs and change out the logic with your own.

The MetaWeblogStructures.cs file contains the code for the structures used as parameters and return values. Xml-Rpc.net automatically creates and populates the parameters from the xml being sent in and converts the return values into the correct Xml-Rpc response.

If you are wondering how Writer knows how to call into your provider, the answer starts in the Default.aspx file. The header of this file includes a link tag that defines the location of the RSD file. RSD stands for Really Simple Discovery which is an xml document that identifies what services are exposed by a website. The MetaWeblog node includes the url to the ashx file. The node also includes the id for the blog so if your blog engine supports multiple blogs, you will need to make this dynamic so that it returns the correct blogid.

The last file that we are going to look at is the wlwmanifest.xml file. This file contains Windows Live Writer specific configuration. It allows you to customize Writer to include features that your blog supports and exclude features it doesn’t. You can even include custom tools! Writer can find this file by either convention (eg, http://myblog.com/wlwmanifest.xml) or using a link tag in the blog page. Read Discovering and Downloading Manifest Files for more information. To keep things simple, the sample project removes almost all the options.

Running and Debugging the Project

To test the provider, simply run the project, copy the url, and use it to add an account to Windows Live Writer.

A few notes about debugging:

  • The sample project will accept any username and password, so no need to set one up.
  • Do not download the blog theme. This isn’t a blog engine, it is just the provider so there is no blog theme available.
  • The account doesn’t show up in Writer (at least not the version I have) until you restart Writer.
  • The sample project stores all the information in memory. Any posts that were created will be lost once you stop debugging the project.
  • If you are interested in seeing the raw xml, you can put a break point in the MetaWeblog.Invoke method. I modified the XmlRpcRequest object in the Xml-Rpc.Net library so that it contains the XmlDocument that is sent for the xml-rpc request.
  • Fiddler is a great way to see what requests Writer is making to your provider. However, if you are testing with localhost, you will need to slightly modify the url to your provider when adding the account. Instead of localhost:12345 (or whatever your port is), try localhost.:12345 (notice the dot after localhost). If you don’t include the dot, fiddler will not capture the traffic.
  • If the service is running but Writer cannot create an account, try adding a break on Exception for all exceptions.
  • I cannot figure out how to populate the Service Name in the account details. I verified that the node name in wlwmanifest.xml is correct.

Great Resources

This article is littered with resources that I have found invaluable for learning how to create my own blog engine. To make it easier to find them, I figured I should provide a nice ordered list.

Have fun writing the next greatest blog engine!Party smile

Windows Live Photo Gallery Plugin From the Ground Up

by Brian Brewder March 01, 2010 22:00

image Recently I came across Windows Live Photo Gallery which is an easy-to-use photo management tool available for free from Microsoft. This tool has a number of features that makes it a convenient tools to use for managing photos. The feature that caught my eye, and the subject of this article, is the support for 3rd party developer plugins.

This article is intended to be a tutorial to help developers get a basic plugin built without having to try to reverse engineer the sample application that Microsoft has provided as part of their documentation. This article is not intended to be a full tutorial of how Photo Gallery plugins work. For that, please see the documentation (it looks pretty decent).

  1. Install Windows Live Photo Gallery
  2. Create a .Net class library project in Visual Studio
  3. Reference C:\Program Files\Windows Live\Photo Gallery\Microsoft.WindowsLive.PublishPlugins.dll (or wherever Photo Gallery was installed to, Program Files (x86) for 64 bit OS).
  4. Reference System.Windows.Forms.dll (in the GAC)
  5. Create a class that implements Microsoft.WindowsLive.PublishPlugins.IPublishPlugin
  6. Compile the dll
  7. Register the plugin. Copy the following text into a .reg file, update the names, then run it (or open the Registry Editor and edit the keys manually).
    Windows Registry Editor Version 5.00
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Live\PublishPlugins\My Plugin]
    "AssemblyPath"="C:\\My Path\\MyPlugin.dll"
    "ClassName"="MyNamespace.MyClass"
    "FriendlyName"="My Plugin"
    "IconPath"="C:\\My Path\\MyPlugin.dll,-32512"
    NOTE: If you are running a 64 bit OS the registry key should be [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Live\PublishPlugins\My Plugin]
  8. To debug, set the Start Action (project properties –> Debug) to “Start external program” and set the value to C:\Program Files\Windows Live\Photo Gallery\WLXPhotoGallery.exe (or wherever Photo Gallery was installed to, Program Files (x86) for 64 bit OS).
    You should be able to run the plugin within Photo Gallery by going to Publish -> More Services -> My Plugin.

From here you should be able to follow the documentation to make your plugin interesting. Good luck!

Tags:

BizArk Feature Spotlight – Command-line Parsing

by Brian Brewder February 20, 2010 20:39

Command-line parsing can be a tedious chore when you are building an application that accepts command-line arguments. But what if all you had to do was create a class with the properties that you want to accept? The BizArk framework offers a simple to use command-line parsing utility that allows you to do exactly that.

Command-line parsing in the BizArk framework has these key features:

  • Automatic initialization: Class properties are automatically set based on the command-line arguments.
  • Default properties: Send in a value without specifying the property name.
  • Value conversion: Uses the powerful ConvertEx class also included in BizArk to convert values to the proper type.
  • Boolean flags. Flags can be specified by simply using the argument (ex, /b for true and /b- for false) or by adding the value true/false, yes/no, etc.
  • Argument arrays. Simply add multiple values after the command-line name to set a property that is defined as an array. Ex, /x 1 2 3 will populate x with the array { 1, 2, 3 } (assuming x is defined as an array of integers).
  • Command-line aliases: A property can support multiple command-line aliases for it. For example, Help uses the alias ?.
  • Partial name recognition. You don’t need to spell out the full name or alias, just spell enough for the parser to disambiguate the property/alias from the others.
  • Supports ClickOnce: Can initialize properties even when they are specified as the query string in a URL for ClickOnce deployed applications. The command-line initialization method will detect if it is running as ClickOnce or not so your code doesn’t need to change when using it.
  • Automatically creates /? help: This includes nice formatting that takes into account the width of the console.
  • Load/Save command-line arguments to a file: This is especially useful if you have multiple large, complex sets of command-line arguments that you want to run multiple times.

So how do you use the command-line parsing? Start by creating a class that is derived from CmdLineObject. Add properties with data types that support conversion from a string using the BizArk ConvertEx class. In main, instantiate your class and call Initialize. That’s it.

If you want to validate your command-line or display help, you will need to check a couple of CmdLineObject properties. Other than that, you can just use your object as any other class.

Here’s an example class that uses it (you can also view an example in the RedwerbEntry project, Program.cs):

    static void Main(string[] args)
{
RedwerbCmdLine cmdLine = new RedwerbCmdLine();
cmdLine.Initialize();
// Validate only after checking to see if they requested help
// in order to prevent displaying errors when they request help.
if (cmdLine.Help || !cmdLine.IsValid())
{
DlgMgr.ShowCmdLineHelp(cmdLine);
return;
}
// do your stuff
}
    [CmdLineDefaultArg("SettingsPath")]
public class RedwerbCmdLine
: CmdLineObject
{
public RedwerbCmdLine()
{
SettingsPath = @"C:\Garb\Settings.rdb";
FadeInTime = 2000;
FadeOutTime = 1000;
RunTime = 5000;
}
[CmdLineArg(Alias="S", ShowInUsage=DefaultBoolean.True, Required=true)]
[Description("If false the splash screen is not displayed during startup.")]
public bool ShowSplashScreen { get; set; }
[CmdLineArg(Alias = "I")]
[Description("Determines how long it takes for the splash screen to fade in.")]
public int FadeInTime { get; set; }
[CmdLineArg(Alias = "O")]
[Description("Determines how long it takes for the splash screen to fade out.")]
public int FadeOutTime { get; set; }
[CmdLineArg(Alias = "R")]
[Description("Determines how long Redwerb will run.")]
public int RunTime { get; set; }
[CmdLineArg(Alias = "P", Usage = "Settings Path")]
[Description("Path to the settings file.")]
public string SettingsPath { get; set; }
[CmdLineArg(Alias = "M", Usage = "Message")]
[Description("Message to display.")]
public string Message { get; set; }
}

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

BizArk is now on CodePlex

by Brian Brewder December 31, 2009 12:27

I have finally gotten around to putting BizArk on CodePlex. Check it out at http://bizark.codeplex.com. I will be removing the BizArk downloads from Redwerb.

Tags:

BizArk

BizArk Feature Spotlight - WebHelper

by Brian Brewder November 20, 2009 23:43

The WebHelper class is a new feature of the BizArk framework. It’s primary purpose is to replace System.Web.WebClient. The WebClient is a great class that makes it pretty easy to do simple web requests.

Unfortunately WebClient only supports a small set of requests such as simple gets, form value posts, single file uploads, and a few others. If you need to upload multiple files in the same request, you are out of luck. If you have a request that might take more than 100 seconds, you are out of luck. If you need to do anything special at all, you are pretty much out of luck and will have to use the HttpRequest object to perform the request.

HttpRequest allows you to do a lot more, but you are stuck implementing the different protocols for the content body. These are very specific and technical and easy to miss something, not to mention that it doesn’t support progress reporting (you have to build that yourself).

The Redwerb.BizArk.Core.Web.WebHelper class is intended to provide you full access to making requests without bothering you with all the mundane details. It includes the following features:

  • Supports no content type, multipart/form-data, and application/x-www-form-urlencoded. Will automatically pick the correct content type based on the properties you set. It can also support custom content types. Just inherit from Redwerb.BizArk.Core.Web.ContentType and implement the two required methods.
  • Can set the timeout for the request.
  • Simple multiple file upload with form values. WebClient makes you send values in the query string.
  • Supports in-memory file uploads. The file doesn’t actually have to exist on disk.
  • Handles compressed responses with a simple property set.
  • Supports progress. You can set an estimated response length to get an approximate total progress before a response is received. If not set, the request/response will be 50/50.
  • Supports asynchronous requests.
  • Event to modify the request before it is sent to the server. Provides you with full control over the request that is sent.
  • Event to process the response instead of having the WebHelper handle it.
  • The response is returned as a WebHelperResponse object. This object provides access to the result as well as status of the response. It also allows you to convert the response to another type other than a byte[] (such as string, image, etc).

To use the WebHelper, just set the url and call MakeRequest.

    var helper = new WebHelper();
helper.Url = "http://localhost:57492/Test/SimpleTest";
var response = helper.MakeRequest();
var result = response.ConvertResult<bool>();
If you want to upload a file and some form variables, that’s easy too!
    var helper = new WebHelper();
helper.Url = "http://localhost:57492/Test/UploadFileTest";
helper.FormValues.Add("test", "Hello");
helper.Files.Add(new UploadFile("file1", @"text\plain", "file1.txt", Encoding.UTF8.GetBytes("Hello World")));
helper.Files.Add(new UploadFile("file2", @"text\plain", "file2.txt", Encoding.UTF8.GetBytes("Goodbye World")));
var response = helper.MakeRequest();
var result = response.ResultToString();  

I’m sure there is still a lot of work to do on this component. Let me know if you find any problems!

I would like to give a special thanks to aspnetupload.com. WebHelper essentially started out as a copy of UploadHelper from this site (though I don’t think there is too much in common with it anymore).

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

BizArk Feature Spotlight – Data Type Conversions

by Brian Brewder September 08, 2009 00:15

The System.Convert class in .Net is a great way to convert basic values to new and wonderful types. Unfortunately it only works on a very limited set of data types. To be precise, it only works if the type implements IConvertible and you can see what types are supported in the listing below.

public interface IConvertible
{
TypeCode GetTypeCode();
bool ToBoolean(IFormatProvider provider);
byte ToByte(IFormatProvider provider);
char ToChar(IFormatProvider provider);
DateTime ToDateTime(IFormatProvider provider);
decimal ToDecimal(IFormatProvider provider);
double ToDouble(IFormatProvider provider);
short ToInt16(IFormatProvider provider);
int ToInt32(IFormatProvider provider);
long ToInt64(IFormatProvider provider);
sbyte ToSByte(IFormatProvider provider);
float ToSingle(IFormatProvider provider);
string ToString(IFormatProvider provider);
object ToType(Type conversionType, IFormatProvider provider);
ushort ToUInt16(IFormatProvider provider);
uint ToUInt32(IFormatProvider provider);
ulong ToUInt64(IFormatProvider provider);
}

If you are looking to convert to other values or the type you are converting from does not implement IConvertible, you are out of luck.

The BizArk framework provides the Redwerb.BizArk.Core.ConvertEx class which extends the conversion capabilities of the .Net framework. ConvertEx can convert types based on the following conversion strategies:

  • TypeConverter: This is a class that you can implement to support conversions between any data types you wish to support. You can get a TypeConverter by calling TypeDescriptor.GetConverter(Type). TypeConverters are used in the binding support in WinForms as well as a few other places in the .Net framework.
  • ToXxx methods: This is a common naming convention for converting an object into another type. The most common of these is the System.Object.ToString() method.
  • Parameterized constructors:  This is a convention where a constructor for a class takes a typed parameter.
  • Parse static methods. This is a common convention for converting strings to a particular type. See Int32.Parse for an example.
  • Image to byte array and vice versa: This is a specific type of conversion to convert an image to a byte array for storage or sending to a stream.
  • To/from null: Reference types can be set to null, but value types cannot. In those cases ConvertEx supports the concept of empty values. An empty value is determined based the following criteria:
    • Reference type: null
    • Char: 0 (that is \0)
    • Static [Type].Empty property (if defined)
    • Static [Type].MinValue property (if defined)
    • Custom empty value. Register the empty value by calling ConvertEx.RegisterEmptyValue.

To use ConvertEx, simply call one of the ConvertEx methods. There are a number of helper methods to convert values to basic types such as integer, string, boolean, etc. However, you can also call the ConvertEx.ChangeType method to convert between any two types (as long as one of the types supports conversions from the other type).

The following example shows how to use the generic version of ConvertEx.ChangeType. As you can see, it is pretty straight forward.

var pt = new Point(5, 10);
var myPt = ConvertEx.ChangeType<MyPoint>(pt);

ConvertEx also provides a plugin architecture if you want to extend the types that it can convert to/from. To use it, just create a class that implements the Redwerb.BizArk.Core.Convert.IConvertStrategy interface and register it by calling Redwerb.BizArk.Core.Convert.ConvertStrategyMgr.SetStrategy (you must register it for each to/from type you want it to support).

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

BizArk Feature Spotlight – Splash Screen

by Brian Brewder August 30, 2009 11:47

The splash screen is a common feature in many desktop applications. A splash screen is used to provide feedback to the user as the application initializes. If your application does not have a long initialization process, it does not need a splash screen, and should not have one (the splash screen can become annoying after a while, especially if it is not necessary).

If you are in need of a splash screen, the BizArk framework provides the capability to show the splash screen on a thread while you initialize your application in Main (the starting point in Windows applications). You do not need to worry about any of the threading issues, BizArk takes care of all that for you. If you are interested in learning how to display a form on a separate thread, check out the source code in SplashScreen.cs, BizArkWinForms project.

The BizArk SplashScreen class provides the following capabilities:

  • Displays a custom splash screen on a separate thread to allow for initialization on the main thread.
  • Provides a mechanism to send progress to the splash screen.
  • Can fade in and out to give a more finished, polished look.
  • Set a minimum time to show the splash screen.

The splash screen is easy to use. Just create your splash screen as a standard Form. In your programs Main method (usually in Program.cs), create a new instance of Redwerb.BizArk.WinForms.SplashScreen and send in the type for your custom splash screen. When you are ready to show your splash screen call ShowSplash and when you are done with it call HideSplash.

If you want to send status updates to the splash screen, your form will need to implement the ISplashScreen interface. The BizArk SplashScreen object will route the status to the correct thread so that you don’t need to worry about cross threading issues (problematic with WinForms).

Below is an example of calling the splash screen from the RedwerbEntry project (a test project available in the BizArk Framework download):

    SplashScreen splash = new SplashScreen(typeof(Splash));
splash.FadeInTime = 500;
splash.FadeOutTime = 500;
splash.MinShowTime = 3000;
splash.ShowSplash();
//todo: remove sleep (used for testing purposes).
splash.Status = "Sleeping";
System.Threading.Thread.Sleep(cmdLine.RunTime);
//todo: initialize the application including creating an instance of the main form.
//var frm = new MyForm();
//var frm.Initialize(); // or whatever you need to do to prepare the form before display.
splash.Status = "Hiding";
splash.HideSplash(true);
//Application.Run(frm);

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

Powered by BlogEngine.NET 1.6.0.0