Ohad's Blog

Lets talk about .net !

Mirror at:
blogs.microsoft.co.il

News

         Ohad Israeli's Facebook profile
      

C# Code Snippts

Favorite Blogs

Israeli .Net Bloggers

January 2007 - Posts

Lenovo finally released the ThinkPad Vista Drivers

Lenovo just release line of ThinkPad Vista Drivers... It took them some time... but well they finally did it.

I just finished configuring my T60P with the latest drivers... and everything seems to be working great.

In the release you can find the long waited ATI FireGL Driver... we can finally display WPF correctly on ThinkPad.

Check it out here

Five things you didn't know about me

I've been tagged by Arnon (almost 11 days ago...oops) so I'll join the

Blog-Tag game.

Five things you didn't know about me:

1. I am almost 35. married and have a 1.5 year old child by the name of Shira. Part of my wife's family still live in Australia so we tend to visit them there from time to time... through it can take 35 hours to get there from Israel.

2. I stated my interaction with computers at the age of 8 - my first computer was Dragon 32. two years later during building of a electronic detention card to control ordinary electronic home equipment I managed to burn the Dragon 32 motherboard and had to upgraded to Dragon 64 !

3. All through my years at school I was the tallest person in class. This is why still today I tend to rush to the airport ASAP to get the exit seats during flights whenever I have to get on an airplane.

4. I used to ran a Bulletin Board System (BBS) long long time ago before the Internet area came to our door... it stated with 300boud modem... which was upgraded to 1200boud xt & 40meg disk...

5. For some years I was hall cycling (Spinning) 3 times a week... but since Shira was born I've haven't been cycling for the last 1.5 years and now (after committing here) I'm going to start it up back again.

So lets see...  Eliaz TubaisUdi DahanIdo Samuelson, Manu Cohen Yashir and Guy Burstein You are all it.

Same Assembly Version For All Project

A question I was asked today was how to manage the same Assembly Version for several project I.e. have it managed in one place.

There are several way to accomplish this task... the most simple is as follows:

1 Delete the  AssemblyVersion and  AssemblyFileVersion attributes from the AssemblyInfo.cs file in all the target projects. ( this will remove duplication conflicts)

2. Create a new file to host the version (I've called it FileVersion.cs in this sample) and pate the following code into the new text file:

using System.Reflection;

// Set here the global file version
[assembly: AssemblyVersion("1.2.3.4")]
[assembly: AssemblyFileVersion("1.2.3.4")]

3. Here comes the tricky part... in each of your target projects you would want to add a link to the existing file, note on the word link and not just adding an existing file which will add a copy of the FileVersion.cs file to your project.

In order to add an existing file as link open the Add Existing File Dialog Box (Right Click on the project -> Add -> Existing Item) then choose the file (FileVersion.cs) and before hitting the Add button click on the small arrow on this button and choose add as link.

[ Click on the picture above to see it in large ]

4. Thats it... you have one place to maintain the file version.

The Enterprise Library BeatBox Hit Again Tomorrow

If you want to learn about the Enterprise Library 2.0 and also have glimpse of Enterprise Library 3.0 I'll be presenting tomorrow my TechEd Eilat Session about the BeatBox Drum Machine powered by Enterprise Library at the Microsoft's Jerusalem .Net User Group.

Second chance... If you are in the IDF... on Wednesday I'll have another session of this lecture for the IDF Usergroup.

Registration for tomorrow's meeting is open free of charge of course... over here

Microsoft Developers Academy -- First Promo is on the Air !

The first promo video for the Microsoft Developers Academy is on the Air !

The promo is the first in a series of promos that was filmed by Microsoft Israel for the event. The event will take place at the Cinema City on the 31.1.2007 !

The promo featuring Ami Levin, Avner Kashtan, Yakov Greeshpan and me as the Bad Guys that will do anything to get into the event :-)

During the event i'll be presenting 2CAB||!2CAB session, during this session I will demonstrate how easy it is to integrate win32 app with .net 3.0 technologies in on big distributed composite ui solution.

P.S.  If anyone cares... we had to wake at 5 am to film this promo... and yep it was chilly !

Developer Academy 07 Action Movie
Developer Academy 07 Action Movie
Barcopedia - WebCam = Barcode Reader

Barcopedia cool implementation showing how you can turn your ordinary webcam into barcode reader... try scanning some of your books barcodes and see them apear on the web :-)

This is definatly one of the nices things i've seen for the past week !

[via urig]

CAB - Support for Custom Commands

In my last post I've talked about how to expose an OutlookBar as UIExtensionSite, during this post I would like to cover what are the needed actions needed to be added in order to support also the ability of using the command invokers with our OutlookBar.

The idea is the same... in order for the CAB infrastructure to recognize our OutlookBar we need to introduce to the infrastructure an EventCommandAdapter.

The EventCommandAdapter is used to link an event name like "Click" event to the Button or any other UI Item that you are adapting to.

public class OutlookBarButtonCommandAdapter : EventCommandAdapter<OutlookBarButton>
{
        public OutlookBarButtonCommandAdapter() : base()
        {}

        public OutlookBarButtonCommandAdapter(OutlookBarButton button,string eventName) : base(button, eventName)
        {}

        protected override void OnCommandChanged(Command command)
        {
            base.OnCommandChanged(command);
            foreach (KeyValuePair<OutlookBarButton,List<string>> pair in Invokers)
            {
                pair.Key.Enabled = (command.Status == CommandStatus.Enabled);
            }
        }
}

The constructor passes the call to the base constructor.

The OnCommandChanged method is where you write you specific code for controlling key characteristics of your UI Control such as if the Button should be Enabled or Disabled, the pair.key represent the OutlookBarButton and here you can set various properties of this button.

Note: in order to make the Herre Kuijpers Outlook Bar suitable for attaching event handlers to the buttons I had to do a minor change to the original OutlookBar code, the change was cause because originally the control had a click event on the control which was using event args of the click to find out which button was clicked. The change that I've made was to add a Click event to the OutlookBarButton and expose a public DoClick method that will be invoke from the bar on the selected button.
Normally I would have coded it myself much more clearer but then... my main show here is not about the control itself but how to integrate it with CAB.

public class OutlookBarButton
{
        public event EventHandler Click;

        public void DoClick()
        {
            if (Click!=null)
                Click.Invoke(this,EventArgs.Empty);
        }

// the rest of the code is the same

}

public partial class OutlookBar : UserControl
{

private void OutlookBar_Click(object sender, EventArgs e)

{

     // Same method... Same Code

      SelectedButton.DoClick();

}

}

Ok so you have a patched OutlookBar and OutlookBarButtonCommandAdapter how do you introduce the adapter to the CAB infrastructure ?

You need to register the OutlookBarButtonCommandAdapter at the MappingService, this is being done on the ShellApplication AfterShellCreated or on the layout module Run:

ICommandAdapterMapService mapService = RootWorkItem.Services.Get <ICommandAdapterMapService>();
            mapService.Register(typeof(OutlookBarButton), typeof(OutlookBarButtonCommandAdapter));

In order to attach invoker in your module declare a command name constant such as:

public class CommandNames : Experts4D.SampleModule.Interface.Constants.CommandNames
{
        public const string SampleCommand = "SampleCommand";
}

Register the new command for the button as part as you extension code:

OutlookBarButton btnShowCalendar = new OutlookBarButton();
btnShowCalendar.Text = "New Module Button";
WorkItem.UIExtensionSites[Interface.Constants.UIExtensionSiteNames.MainOutlookBar].Add
                <OutlookStyleControls.OutlookBarButton>(btnShowCalendar);
WorkItem.Commands[Constants.CommandNames.SampleCommand].AddInvoker(btnShowCalendar, "Click");

And then add a command handler in your code:

[CommandHandler(Constants.CommandNames.SampleCommand)]
public void HistCaneldar(object sender, EventArgs e)
{
            MessageBox.Show("Command Clicked");
}

In my next post I'll show you how you can use a simple design solution in order to decouple between the module and the UIExtensionSite as the module doesn't need to be aware that you are implementing your OutlookBar using OutlookBarButtons.

CAB - Support for Custom UIExtensionSites

Almost every client I've been working with on CAB projects wanted the look and feel of Microsoft Outlook where you have a navigation pane on the side of the shell host and a content which is changing on the right pane.

So lets see how we can get this cool look and feel in out CAB application...

Searching over the web you might find an Outlook Bar that you might want to use in your CAB application, In my search I found on CodeProject - Herre Kuijpers Outlook Bar and i'll be using it to demonstrate what are the steps needed to integrate it into your CAB application.

 

You might be thinking ahh... you are going to show me that you just drag and drop it to the CAB shell layout and everything is working ... well I wish it was as simple as that.

First thing that will do is to design our Composite UI shell and yep we will drag the Outlook Bar to the shell layout which is the easy step... the hard step is how to expose this part as UIExtensionSite to the modules of the Composite UI Application.

Note: I am going to use the CAB with the Smart Client Software Factory (SCSF) in my demonstrations as I find it to be a silver bullet in most cases.

 

Now we would like to expose the Shell's Outlook Bar as UIExtensionSite so other modules will be able to add buttons and commands on the fly (I.e. while the module initialize)

First lets expose the new Outlook Bar as an Internal Shell View Property:
internal OutlookStyleControls.OutlookBar MainOutlookBar
{
     get { return _mainOutlookBar; }
}

Next we add a constant for the new Outlook Bar UIExtension name and register it as UIExtensionSite as the Shell Layout View Presenter:
protected override void OnViewSet()
{
            WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.MainOutlookBar, View.MainOutlookBar);
}

You are now probably happy thinking ohh... that was easy but as you run the application you are getting the following exception:

Its time for a little tip: whenever you are working with CAB the exception you will get are most of the time runtime exceptions, its hard to diagnose these exceptions as you have no idea where they came from because most of the exceptions are due to reflection operations inside the Object Builder infrastructure or in other CAB infrastructure. So how do you find easily where the exception came from ?
Ask visual studio to throw the exceptions as they occur and not to bubble them up the stack, you do this by pressing ALT-CTRL-E and choosing to throw CLR Exceptions.

Now when you can stop at the exception you can dig it out... and find out that the problem is that the Object Builder - the infrastructure that creates the instance of the object, doesn't know about the type (OutlookBar) that you want to create and as such throw an exception.

So how do we solve the issue ? We need to introduce to the Object Builder a new Factory that will be used to create the OutlookBar.

What I normally do is open a new project which will host the Adapters for the control which I want to expose as UIExtensionSite this way I'm not touching the control and actually look at it as a black box while supplying the cab infrastructure the ability to create and use the control.

Ok so lets code the OutlookBarAdapterFactory:

public class OutlookBarAdapterFactory : IUIElementAdapterFactory    {
      #region IUIElementAdapterFactory Members
      public IUIElementAdapter GetAdapter(object uiElement)
      {
          if (uiElement is OutlookBar)
              return new OutlookBarUIAdapter((OutlookBar) uiElement);
          throw new ArgumentException("uiElement");
      }
      public bool Supports(object uiElement)
      {
          return (uiElement is OutlookBar);
      }
      #endregion
}

The GetAdapter method is used to return a new Instance of the OutlookBar by using a OutlookBarUIAdapter.
The Supports method is used to check if a uiElement need such type of an adapter (the object builder will use this method to find out how to build a specific uiElement)

As you could have seen the code above uses the OutlookBarUIAdapter to create the new OutlookBar instance, lets code the OutlookBarUIAdapter:

    public class OutlookBarUIAdapter : UIElementAdapter<OutlookBarButton>
    {
        private OutlookBar outlookBar;
        public OutlookBarUIAdapter(OutlookBar outlookBar)
        {
            Guard.ArgumentNotNull(outlookBar,"outlookBar");
            this.outlookBar = outlookBar;
        }
        protected override OutlookBarButton Add(OutlookBarButton uiElement)
        {
            if (outlookBar == null)
                throw new InvalidOperationException();

            outlookBar.Buttons.Add(uiElement);
            return uiElement;
        }
        protected override void Remove(OutlookBarButton uiElement)
        {
            if (outlookBar == null)
                throw new InvalidOperationException();
            outlookBar.Buttons.Remove(uiElement);
        }
    }

The constructor get an OutlookBar instance and save reference for it localy in order to add / remove items (or just call it buttons in this case) from the bar.

The Add and Remove implements the specific implementation of the UI component of adding uiElements to it I.e. how to add/remove buttons from the OutlookBar component.

After we've created the adapters we still need to introduce them to the CAB infrastructure and we do this by adding the specific adapter to the IUIElementAdapterFactoryCatalog, this way the Object Builder will be able to find the missing adapter for the OutlookBar.

Add the following code to the AfterShellCreated of your shell application class or at the load event of your layout module.

IUIElementAdapterFactoryCatalog catalog = RootWorkItem.Services.Get<IUIElementAdapterFactoryCatalog>();
catalog.RegisterFactory(new OutlookBarAdapterFactory());

At last we can now use our new OutlookBar UIExtension through our modules, add the following to the run method of your module:

OutlookBarButton btnShowCalendar = new OutlookBarButton();
btnShowCalendar.Text = "New Module Button";
WorkItem.UIExtensionSites[Interface.Constants.UIExtensionSiteNames.MainOutlookBar].Add
                <OutlookStyleControls.OutlookBarButton>(btnShowCalendar);

We've added a new button through the OutlookBar UIExtension site but we are facing two problems here:

1. We still need to see how we can add also the ability to add command invokers to the buttons - we will cover this on the next CAB post.

2. We have just created a coupling as the module needs to know what is an OutlookBarButton - I will show you how to remove this coupling using a simple design also in one of the next post of out series.

Composite UI Application Block Series

Last week I've delivered 3 days course about the Microsoft Composite UI Application block during the Microsoft's MVPs week which we organized in Israel.

During this course I've covered several undocumented areas regarding the usage and building of CAB enabled applications. In the following weeks till I will post various insights that I've covered while working with clients on Composite UI based applications.

Microsoft Developer Academy - 2 CAB ||! 2 CAB

One Day, 25 Lectures, 5 Lectures per hour !  ( 31.1.2007 )

If you are developer, architect, team leader or project manager in Israel you just can't miss this day in order to get updated of the latest Microsoft Technologies (Vista, .Net 3.0, Team System and more... )

My part in the event will be a session named ' 2 CAB ||! 2 CAB ' - cool session showing how easy it is to leverage your existing application to the latest Microsoft Technologies using Microsoft Composite UI Application Block.

The session is marked as 400 session i.e. we have 60min of pure Visual Studio coding to implement Composite UI based distributed system using CardSpace, Windows Workflow, Windows Communication Foundation, Windows Presentation Foundation, .net 2.0 WinForms & Win32 legacy code.

More Posts