The official Fatica Labs Blog! RSS 2.0
# Saturday, March 05, 2011

In the previous post we had a look on how to host WF4 designer in pure markup, we continue now to host, always in markup, the toolbar for dropping activities into the designer surface. The ToolboxControl is fortunately a standard WPF control, so it is not a problem to use it in markup, but it is a little difficult to add a list of categorized activities, because we have to add as a content of the control a list of category, each with a list of category. We want to use some sort of activity list source instead. So let’s have a look at the markup that add a ToolBoxControl to our designer:

   1:   <host:MainViewPresenter HostingHelper="{StaticResource wfHost}"  Grid.Column="1" Grid.Row="1"/>
   2:   <toolbox:ToolboxControl Grid.Column="0" Grid.Row="1" host:ToolboxItemSource.CategorySource="{StaticResource GeneralTools}" >

So the line 2 is the markup tag for adding the ToolboxControl, but the interesting part is the:

host:ToolboxItemSource.CategorySource="{StaticResource GeneralTools}"

CategorySource is an attached property of type ToolboxItemSource, an helper class we use to make easier binding to a list of activities. In this particular case we have defined an instance on the resources, called GeneralTools, as below:

   1:   <host:ToolboxItemSource x:Key="GeneralTools">
   2:              <host:ToolboxSource TargetCategory="General" AllSiblingsOf="{x:Type activities:Delay}"  />
   3:              <host:ToolboxSource TargetCategory="Custom" AllSiblingsOf="{x:Type custom:Activity1}"  />
   4:   </host:ToolboxItemSource>

As we can see, we can add to the ItemSource a list of source of type ToolboxSource, an helper class too. That class has the only pourpose of collecting the target category name, and a type of one activity to pick an assembly and contextually add all activities contained in. Most of the job is done by ToolboxItemSource, when the property is actually attached, so the code below:

   1:          protected static void OnCategorySourceChanged(DependencyObject depobj,DependencyPropertyChangedEventArgs dpcea)
   2:          {
   3:              if (null != dpcea.NewValue && dpcea.NewValue is ToolboxItemSource)
   4:              {
   5:                  var tbsrc = dpcea.NewValue as ToolboxItemSource;
   6:                  foreach (var source in tbsrc.Sources)
   7:                  {
   8:                      AddTools(depobj as ToolboxControl, source);
   9:                  }
  10:              }
  11:          }
  13:          private static void AddTools(ToolboxControl toolboxControl, ToolboxSource source)
  14:          {
  15:              if (null != source.AllSiblingsOf)
  16:              {
  17:                  var cat = toolboxControl.Categories.Where(q => q.CategoryName.Equals(source.TargetCategory)).FirstOrDefault();
  18:                  if (null == cat)
  19:                  {
  20:                      cat = new ToolboxCategory(source.TargetCategory);
  21:                      toolboxControl.Categories.Add(cat);
  22:                  }
  23:                  var query = from type in source.AllSiblingsOf.Assembly.GetTypes()
  24:                              where type.IsPublic &&
  25:                              !type.IsNested &&
  26:                              !type.IsAbstract &&
  27:                              !type.ContainsGenericParameters &&
  28:                              (typeof(Activity).IsAssignableFrom(type) ||
  29:                              typeof(IActivityTemplateFactory).IsAssignableFrom(type))
  30:                              orderby type.Name
  31:                              select new ToolboxItemWrapper(type);
  32:                  foreach (var item in query)
  33:                      cat.Add(item);
  34:              }

35: }


Very easy, when we attach the item source, we pump on the control all the required activities, and it’s done. So this is another step on a XAML only re-hosting, let’s see the result:


Well you will probably note the very fancy gear icon that is the “mean nothing” icon that we usually have when we forgot something, and actually we forgot something, but differently from the old workflow is not so easy: a look here could help, and we probably work on that direction in further steps.

All are welcome to grab or cooperate on the source code for this sample here.

Saturday, March 05, 2011 10:37:05 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] - Trackback
Programmin | Recipes | ReHosting | WF4

This post is based on this great post from The Problem Solver, but here we try to use less code behind and more markup language, to let the “host” decide where to put the designer components in his application. Basically there is three main chunk involved in hosting the WF:

  1. The main designer surface
  2. The property view
  3. The toolbox.

Components 1) and 2) are exposed as property of the WorkflowDesigner class, that itself is not a UIElement, but a simple class derived from object. The two property of interest are View and PropertyInspectorView, and both are UIElements. The problem is: how to let’s the host application writer to decide where to place these in XAML ? Lets start creating a class that act as an helper, and provide inside it some initialization code:

namespace WF4Host
    public class HostingHelper:DependencyObject
        public WorkflowDesigner Designer { get { return workflowDesigner;} }
        WorkflowDesigner workflowDesigner;
        public HostingHelper()
            workflowDesigner = new WorkflowDesigner();
            new DesignerMetadata().Register();
            //Creates an empty workflow
            workflowDesigner.Load(new Sequence());

basically we creates an instance of the WorkflowDesigner itself, load a first Sequence activity, and start the designer runtime. In xaml we can declare such an object as a StaticResource:

   1:  <Window x:Class="WF4Host.MainWindow"
   2:          xmlns=""
   3:          xmlns:x=""
   4:          xmlns:host="clr-namespace:WF4Host"
   5:          xmlns:wf="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
   6:          Title="MainWindow" Height="650" Width="825"
   7:          >
   8:      <Window.Resources>
   9:          <host:HostingHelper x:Key="wfHost"/>
  10:          <LinearGradientBrush x:Key="backBrush" StartPoint="0,0" EndPoint="0,1" >
  11:              <GradientStop Offset="0.1" Color="DarkSlateBlue"></GradientStop>
  12:              <GradientStop Offset="0.2" Color="DarkSlateGray"/>
  13:              <GradientStop Offset="0.9" Color="BlanchedAlmond"/>
  14:          </LinearGradientBrush>
  15:      </Window.Resources>


Easy: at line 4 we add the namespace for our project. At line 9 we declare an instance of our HostingHelper and we name it wfHost. Remaining resources are just some beautiful ( ehm ) arts.

Then we need to present the graphical components. Lets declare in our code a control deriving from grid:

   1:  namespace WF4Host
   2:  {
   3:      public class MainViewPresenter : Grid
   4:      {
   5:          public HostingHelper HostingHelper
   6:          {
   7:              get { return (HostingHelper)GetValue(HostingHelperProperty); }
   8:              set { SetValue(HostingHelperProperty, value); }
   9:          }
  11:          public static readonly DependencyProperty HostingHelperProperty =
  12:              DependencyProperty.Register("HostingHelper", typeof(HostingHelper)
  13:              , typeof(MainViewPresenter)
  14:              , new UIPropertyMetadata(null, new PropertyChangedCallback(OnHostingHelperChanged)));
  16:          protected static void OnHostingHelperChanged(DependencyObject dobj
  17:              , DependencyPropertyChangedEventArgs dpcea)
  18:          {
  19:              if (dobj is MainViewPresenter)
  20:              {
  21:                  var mvp = dobj as MainViewPresenter;
  22:                  mvp.Children.Clear();
  23:                  if (dpcea.NewValue != null)
  24:                  {
  25:                      var host = dpcea.NewValue as HostingHelper;
  26:                      host.Designer.View.SetValue(Panel.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
  27:                      host.Designer.View.SetValue(Panel.VerticalAlignmentProperty, VerticalAlignment.Stretch);
  28:                      mvp.Children.Add(host.Designer.View);
  29:                  }
  30:              }
  31:          }
  32:      }
  33:  }


So this class is the MainView presenter. We call the Main View the one in which the WF is actually drawn. This control has a dependency property called HostingHelper, so we can bind it to the current HostingHelper that orchestrates the Workflow design. Let see how to do it in xaml:

   1:  <Grid Name="grid">
   2:              <Grid.RowDefinitions>
   3:                  <RowDefinition Height="32"/>
   4:                  <RowDefinition Height="*"/>
   5:              </Grid.RowDefinitions>
   6:                  <Grid.ColumnDefinitions>
   7:              <ColumnDefinition Width="100"></ColumnDefinition>
   8:              <ColumnDefinition></ColumnDefinition>
   9:              <ColumnDefinition Width="100"></ColumnDefinition>
  10:          </Grid.ColumnDefinitions>
  12:              <host:MainViewPresenter
  13:               HostingHelper="{StaticResource wfHost}"  Grid.Column="1" Grid.Row="1"/>
  15:          </Grid>

So at line 12 we declare our presenter, and we bind his hosting helper property to the hosting helper instance wfHost.

This is the current result:


So we achieved less code behind and more “blendability” by creating a little tool library. We should improve it with others components to complete the designer environment. I decided to publish this example as a project on codeplex, so you can join to use and improve it.

Saturday, March 05, 2011 10:49:00 AM (GMT Standard Time, UTC+00:00)  #    Comments [2] - Trackback
Programmin | Recipes | ReHosting | WF4

# Tuesday, February 15, 2011

Giammai :)

Giacchè il famoso Reflector di Lutz Roeder è diventato un tool a pagamento , e del resto non è mai stato Open Source, quali alternative ci sono  ? A me è piaciuta l’alternativa proposta dal team di SharpDevelop: ILSpy. Usa l’editor interno di SharpDevelop per visualizzare il disassemblato, che può essere C# o IL, il che è più che sufficiente per la stragrande maggioranza dei programmatori .NET. In più è open source, e si può scaricare e compilare da qui.


Tuesday, February 15, 2011 2:04:44 PM (GMT Standard Time, UTC+00:00)  #    Comments [2] - Trackback
Reflector | Deblector

# Sunday, February 13, 2011

Volevo sperimentare un po’ con silverlight, e la prima cosa che mi è venuta in mente è stata fare un bel blog gatget che mostrasse le ultime attività “meritorie” su StackOverflow, utilizzando le Stack Overflow API.

Con un po’ di lavoro il risultato è stato questo:


Ovviamente, anche se il progetto è semplicissimo, non ho saputo rinunciare a Caliburn Micro sia per l’aggancio MVVM che per le action. Ancora un paio di cose, e poi proverò a distribuirlo sul mio blog.  Come visibile nella barra di destra il componentino c’è: Provato sia su firefox che su IE sembra comportarsi bene. Il deploy su Aruba è stato facilissimo, anche perchè non c’è niente da fare a livello permissionWinking smile

Sunday, February 13, 2011 4:40:07 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] - Trackback
Programmin | Silberlight

# Friday, February 11, 2011

Questo può accadere se, e generare dei potenziali super bachi quando…

…in un handler custom hostato in IIS quando si chiama Response.End();. Nel mio caso l’handler faceva, dopo aver scritto I dati nello stream di uscita, la doppia chiamata Response.Flush() e Response.End() che va evitata se si vuole evitare l’eccezione suddetta. Il problema non si verificava sul server di debug integrato di VS.

Friday, February 11, 2011 7:58:02 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] - Trackback

# Wednesday, January 19, 2011

Montare una immagine ISO come disco ci è utile in parecchi casi, ma in particolare per installare I vari componenti di MSDN se non ci arrivano I dischi fisici a casa. La situazione si complica se si vuole uno strumento gratuito e che funzioni pure su windows7. Dopo un po’ di prove fallite I migliori risultati li ho ottenuti con questo:


Una volta installato, basta cliccare con il destro sul file .ISO per “montarlo”, e sul disco montato per smontarlo.

Wednesday, January 19, 2011 3:53:44 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] - Trackback

My Stack Overflow

Send mail to the author(s) E-mail

profile for Felice Pollano at Stack Overflow, Q&A for professional and enthusiast programmers
About the author/Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2019
Felice Pollano
Sign In
Total Posts: 157
This Year: 0
This Month: 0
This Week: 0
Comments: 128
This blog visits
All Content © 2019, Felice Pollano
DasBlog theme 'Business' created by Christoph De Baene (delarou) and modified by Felice Pollano
Nike Winkels Nederland Outlet Nike Nederland Store Outlet Nike Nederland 2015 Outlet Nike Outlet Online Nike Sneakers Outlet