Expression Blend’s Sketchflow diagrams with G2

A short sample demonstrating that it’s a piece of cake to mimic the latest Expression Blend diagrams (part of Sketchflow) in G2.

Expression Blend 3 with SketchflowOne of the aims of G2 is to provide a framework for any type of intelligent diagram (see also the database diagram sample, the mindmapping sample, the class diagram sample…). The ‘intelligent’ refers here to highly interactive diagrams with databinding, animations and adorners in constrast with ‘data visualization’ diagrams where the focus is more on getting a bird’s eye view (many nodes and edges) on the data rather than seeing all the details to the lowest level.

In the past week I had a look at Expression Blend 3 and was impressed with the amount of new features both for WPF and Silverlight. The application is a delight! I’m not so sure that Sketchflow (see screenshot on the left in case you have no idea what it’s all about) will replace paper and pencil but it does offer a new approach which might suit some workflows in companies. In any case, I was seduced by the diagrammatic representation of the screen-flow which allows you to visualize/change and beautify (screen transitions etc.) the flow of the various WPF/Silverlight forms you hook up together. Obviously it came to my mind to mimic it in G2 and…presto, I had it done in the course of an evening. The most difficult part in the process was actually not the diagramming bit but the definition of the shifting tray which shows up when one hovers over the nodes. The situation is very common and with customers we always have this kind of discussion: the gizmo’s and bells should be shown at all time or is usability increased by popups, sliding panels and expanding trays? Expression Blend is in this context different from other Microsoft application where usually the buttons and gears are fixed (cfr. class designer, SQL designer, DSL designers etc.). Well, this is not a bad things since Expression is aimed at designers and people who are looking for cool effects. In fact, WPF and Silverlight offer much effcts and sparkles which are hardly used in line of business applications nowadays. Personally, I continue to be amazed how much one can achieve with WPF (and G2) without much programming and this little sketchflow proof of concept on the basis of G2 was huge fun.

G2 Sketchflow Sample

Below is a short sequence demonstrating the sample. Sorry for not delivering the sample code, G2 is a commercial component (see however the control template below for an idea of what it involves). If you buy G2 the sample comes with the box together with many other (and ever growing set of) samples.

<style TargetType="{x:Type Sketchflow:SketchFlowShape}">
  <setter Property="MinWidth" Value="130"/>
  <setter Property="MinHeight" Value="25"/>
  <setter Property="Background" Value="Blue"/>
  <setter Property="Foreground" Value="White"/>
  <setter Property="SnapsToDevicePixels" Value="True"/>
 
  <setter Property="Template">
    </setter><setter .Value>
      <controltemplate TargetType="{x:Type Sketchflow:SketchFlowShape}">
        </controltemplate><controltemplate .Resources>
          <storyboard x:Key="SBExpand">
            <doubleanimationusingkeyframes BeginTime="00:00:00" Storyboard.TargetName="tray" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)">
              <splinedoublekeyframe KeyTime="00:00:00" Value="0"/>
              <splinedoublekeyframe KeyTime="00:00:01" Value="20"/>
            </doubleanimationusingkeyframes>
            <doubleanimationusingkeyframes BeginTime="00:00:00" Storyboard.TargetName="tray" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
              <splinedoublekeyframe KeyTime="00:00:00" Value="0" KeySpline="0,0,0.625,1"/>
              <splinedoublekeyframe KeyTime="00:00:01" Value="20" KeySpline="0.11,0.99,1,1"/>
            </doubleanimationusingkeyframes>
 
          </storyboard>
          <storyboard x:Key="SBCollapse">
            <doubleanimationusingkeyframes BeginTime="00:00:00" Storyboard.TargetName="tray" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)">
              <splinedoublekeyframe KeyTime="00:00:00" Value="1"/>
              <splinedoublekeyframe KeyTime="00:00:01" Value="20"/>
            </doubleanimationusingkeyframes>
            <doubleanimationusingkeyframes BeginTime="00:00:00" Storyboard.TargetName="tray" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
              <splinedoublekeyframe KeyTime="00:00:00" Value="20"/>
              <splinedoublekeyframe KeyTime="00:00:01" Value="0" KeySpline="0.08,1,1,1"/>
            </doubleanimationusingkeyframes>
 
          </storyboard>
          <objectdataprovider x:Key="Tags" ObjectType="{x:Type Sketchflow:Stuff}" MethodName="get_VisualTags"/>
          <style x:Key="TagButton" TargetType="{x:Type Button}">
            <setter Property="Background" Value="Transparent"/>
            <setter Property="Button.Command" Value="{x:Static Sketchflow:Window1.ChangeBackgroundCommand}"/>
            <setter Property="Button.CommandParameter" Value="{Binding}"/>
            <setter Property="Button.Cursor" Value="Hand"/>
            <setter Property="Template">
              </setter><setter .Value>
                <controltemplate TargetType="{x:Type Button}">
                  <stackpanel x:Name="line" Orientation="Horizontal" Background="{TemplateBinding Background}">
                    <rectangle Width="5" Height="5" Fill="{Binding Color}" VerticalAlignment="Center" Margin="5,3,0,0"/>
                    <textblock Text="{Binding Title}" HorizontalAlignment="Stretch" Margin="7,0,0,0" VerticalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                  </stackpanel>
                  </controltemplate><controltemplate .Triggers>
                    <trigger Property="IsMouseOver" Value="True">
                      <setter Property="Background" Value="Silver"/>
                    </trigger>
                  </controltemplate>
                </setter></style></controltemplate>
              </setter>
 
            <setter Property="FontSize" Value="10"/>
            <setter Property="Foreground" Value="White"/>
          </style>
          <datatemplate x:Key="TagTemplate">
            <button Margin="-2,0,0,0" Style="{DynamicResource TagButton}" Width="79.5" Content="{Binding }"/>
          </datatemplate>
 
        <grid x:Name="PART_maingrid" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
          <border x:Name="tray" Margin="8,0,0,1.046" VerticalAlignment="Bottom" Height="20" BorderBrush="{TemplateBinding Background}" BorderThickness="1" CornerRadius="0,0,5,5" Background="#FF333333" RenderTransformOrigin="0.5,0" Width="83.737" HorizontalAlignment="Left">
            </border><border .RenderTransform>
              <transformgroup>
                <scaletransform ScaleX="1" ScaleY="1"/>
                <skewtransform />
                <rotatetransform />
                <translatetransform />
              </transformgroup>
            </border>
            </grid><grid>
              </grid><grid .RowDefinitions>
                <rowdefinition Height="Auto"/>
              </grid>
              <grid .ColumnDefinitions>
                <columndefinition />
                <columndefinition Width="Auto" MinWidth="17.053"/>
              </grid>
              <stackpanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,3,0,0">
                <popup x:Name="TagPop" AllowsTransparency="True"   PopupAnimation="Slide"       HorizontalOffset="0"  VerticalOffset="-112">
                  <border Background="#FF333333" CornerRadius="3" HorizontalAlignment="Left" Width="84" Height="111">
                    <listbox x:Name="TagList" ItemsSource="{Binding Source={StaticResource Tags}}"  SelectedIndex="-1" ItemTemplate="{DynamicResource TagTemplate}" Background="{x:Null}" />
                  </border>
                </popup>
                <!--<Image Source="Images/ConnectExistingScreen.png" Width="12" Height="12" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0"/>-->
                <button Style="{StaticResource ConnectNewScreen}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Width="12" Height="12" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0"/>
                <image Source="Images/ConnectNewScreen.png" Width="12" Height="12" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0"/>
                <image Source="Images/InsertComponentScreen.png" Width="12" Height="12" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0"/>
              </stackpanel>
              <!--<Image Source="Images/ChangeVisualTag.png" Width="Auto" Height="12" Grid.Column="1" Margin="0.872,3,5,0" HorizontalAlignment="Stretch"/>-->
              <button Style="{StaticResource ChangeVisualTag}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Width="Auto" Height="12" Grid.Column="1" Margin="0.872,3,5,0" HorizontalAlignment="Stretch"/>
 
 
 
          <rectangle x:Name="PART_rec" RadiusX="2" RadiusY="2" Stroke="{x:Null}"  StrokeThickness="2" Width="{TemplateBinding Width}" Fill="{TemplateBinding Background}"/>
 
          <textblock Text="{TemplateBinding ContentControl.Content}"  HorizontalAlignment="Center"
                         VerticalAlignment="Center" Foreground="White" FontWeight="Bold" />
          <!-- PART_DragThumb -->
          <core :TranslationThumb x:Name="PART_DragThumb" Cursor="SizeAll"/>
          <!-- PART_ConnectorDecorator -->
          <core :ConnectorDecorator x:Name="PART_ConnectorDecorator"
                       Visibility="Hidden"
                       Template="{StaticResource ConnectorDecoratorTemplate}"/>
          <rectangle x:Name="Arrow" Visibility="{TemplateBinding ShowArrow, Converter={StaticResource BoolToVisibilityConverter} }"  Stroke="{x:Null}" HorizontalAlignment="Left" Width="21" Height="21" Fill="{DynamicResource LitlArrow}" Margin="-7,0,0,14"/>
 
 
        <controltemplate .Triggers>
          <datatrigger Value="True" Binding="{Binding RelativeSource={RelativeSource Self},Path=IsSelected}">
            <setter TargetName="PART_rec" Property="Stroke" Value="#83EEEEEE"/>
            <setter Property="BitmapEffect" TargetName="PART_rec">
              </setter><setter .Value>
                <outerglowbitmapeffect GlowColor="White" GlowSize="7" Noise="0" Opacity=".41" />
              </setter>
 
          </datatrigger>
          <trigger Property="IsMouseOver" Value="true">
            <!--<Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible"/>-->
            <setter TargetName="PART_rec" Property="Stroke" Value="#83EEEEEE"/>
            </trigger><trigger .ExitActions>
              <beginstoryboard Storyboard="{StaticResource SBCollapse}"/>
            </trigger>
            <trigger .EnterActions>
              <beginstoryboard Storyboard="{StaticResource SBExpand}"/>
            </trigger>
 
          <datatrigger Value="True" Binding="{Binding RelativeSource={RelativeSource Self},Path=IsDragConnectionOver}">
            <setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible"/>
          </datatrigger>
        </controltemplate>
Tagged with:
 

Leave a Reply