When you make a screenshot of Expression Blend 4 and paste it in Photoshop CS6 beta, it is hard to see where the Photoshop UI stops and Expression Blend UI starts.
Check this out:
Njoy!
I can’t even find this one in the Keyboard Shortcut list provided in the User Guide of Expression Blend, so I made up a name for it: The Artboard Objects List:
Known from several drawing programs, this list shows the objects under the mouse cursor when you hold Ctrl and Click the Right Mouse Button. It highlights the currently selected object and lists all other objects overlapping each other from the topmost at the top of the list to the one at the bottom on the bottom of the list. Notice that the order of this list is opposite to the default order in de Objects and Timeline Panel (when you have not changed the order of the panel using the Sort by Z-order option at the bottom left of that panel). Actually, this order is logical for what it shows: the stack of objects in the Artboard under your mouse cursor.
Notice also the option to Pin or UnPin the Active Container. This makes is easier to insert newly created objects in a container like the RegularPolygon Shape in the Grid here inside the RadioButton…
Njoy!
[sourcecode language=”XML”]<Style x:Key="CoverFlowSliderThumb" TargetType="Rectangle">
<Setter Property="RadiusY" Value="10" />
<Setter Property="RadiusX" Value="10" />
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stroke" Value="#FF4B4B4B"/>
<Setter Property="Fill">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.43,-0.02">
<GradientStop Color="#FF252525" Offset="1"/>
<GradientStop Color="#FF787878" Offset="0"/>
<GradientStop Color="#FF424242" Offset="0.622"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CoverFlowSliderThumbCover" TargetType="Rectangle">
<Setter Property="RadiusY" Value="8" />
<Setter Property="RadiusX" Value="8" />
<Setter Property="StrokeThickness" Value="0" />
<Setter Property="Fill" Value="#FF404040" />
<Setter Property="Margin" Value="3" />
</Style>
<Style x:Key="ThumbStyle" TargetType="Thumb">
<Setter Property="Margin" Value="0,2" />
<Setter Property="Width" Value="50" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Grid Margin="2,0">
<Rectangle x:Name="Thumb" Style="{StaticResource CoverFlowSliderThumb}"/>
<Rectangle x:Name="ThumbCover" Style="{StaticResource CoverFlowSliderThumbCover}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Direction="360" Opacity="0.5" ShadowDepth="3"/>
</Setter.Value>
</Setter>
</Style>[/sourcecode]
[sourcecode language=”XML”]<Style x:Key="CoverFlowSliderControl" TargetType="Slider">
<Setter Property="Height" Value="24" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Slider">
<Grid x:Name="HorizontalTemplate">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="Track" Grid.ColumnSpan="3" Style="{StaticResource CoverFlowSliderTrackStyle}"/>
<RepeatButton x:Name="HorizontalTrackLargeChangeDecreaseRepeatButton" Grid.Column="0" Style="{StaticResource RepeatButtonStyle}"/>
<Thumb x:Name="HorizontalThumb" Grid.Column="1" Style="{StaticResource ThumbStyle}"/>
<RepeatButton x:Name="HorizontalTrackLargeChangeIncreaseRepeatButton" Grid.Column="2" Style="{StaticResource RepeatButtonStyle}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>[/sourcecode]
When you need to create objects in code, you can actually build up the entire look and feel in code.
This results in large blocks of code that do nothing special, but set the visual properties of an object:
Grid grdNow = new Grid();
//create Circle
Ellipse cirNow = new Ellipse();
cirNow.Height = 25;
cirNow.Width = 25;
cirNow.VerticalAlignment = VerticalAlignment .Center;
cirNow.HorizontalAlignment = HorizontalAlignment.Center;
cirNow.Fill = new SolidColorBrush (Colors.Red);
cirNow.Margin =new Thickness(5,5,5,5);
//create TextBlock
TextBlock txtNow = new TextBlock();
txtNow.VerticalAlignment = VerticalAlignment.Center;
txtNow.HorizontalAlignment = HorizontalAlignment.Center;
txtNow.Foreground = new SolidColorBrush(Colors.White);
txtNow.FontWeight = FontWeights.Bold;
txtNow.FontSize = 14;
txtNow.Margin =new Thickness(0,0,0,2);
txtNow.TextWrapping = TextWrapping.NoWrap;
txtNow.Text="now";
//add objects to grid
grdNow.Children.Add(cirNow);
grdNow.Children.Add(txtNow);
The drawback of this is that it is a lot of code and hard to maintain. The looks are integrated in the code and that is not what you want.
In Silverlight and WPF there is a standard model to separate the code from the look and feel of the application you’re building. It’s called XAML.
XAML is a markup language that’s easily generated by code and easily maintained by non-programmers with tools of even by hand.
When you are creating objects on the fly you should use Styles. These determine the way the object looks. Only keep the properties necessary for dynamically placing your object on the screen in your code:
Grid grdNow = new Grid();
Ellipse cirNow = new Ellipse();
TextBlock txtNow = new TextBlock();
cirNow.Style = App.Current.Resources["NowStyle"] as Style;
txtNow.Style = App.Current.Resources["NowTextStyle"] as Style;
grdNow.Children.Add(cirNow);
grdNow.Children.Add(txtNow);
This is a lot less code. Below is the markup that you shouldn’t have to worry about when you use Styles in your C# code.
You can even just create an empty Style block in App.xaml: <Style x:Key=”NowStyle” TargetType=”Ellipse” /> and thus use it with default values.
The look of these dynamically created objects can be changed later on or even be themed using a separate ResourceDictionary. A designer can come in at any time and change these properties using a Tool like Expression Blend.
<Style x:Key="NowStyle" TargetType="Ellipse">
<Setter Property="Height" Value="25"/>
<Setter Property="Width" Value="25"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Fill" Value="Red"/>
<Setter Property="Margin" Value="5"/>
</Style>
<Style x:Key="NowTextStyle" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="0,0,0,2"/>
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="Text" Value="nu"/>
</Style>
So, when you find yourself creating a lot of C# code to set the visual properties of a dynamically created objects: Stop!
Create a Style in XAML and refer to that Style instead.
Njoy!
Recently we created a demo. It was in SketchFlow, but it was not really a sketchy demo. Some screens are in the typical SketchFlow look, but for three important scenarios we’ve created a Visual Design. For the Homepage and a Product page in the demo we even created a Silverlight Banner, including the navigation inside the banner.
We’ve actually presented it inside the SketchFlow Player with panels collapsed. We gained the ease with which to connect the screens, in combination with the Behaviors the make parts of the demo interactive. And we combined real Silverlight applications inside the SketchFlow demo and they worked just fine. This is a demo that is meant to impress a customer.
I’ve collected some some gothas we run into when creating this demo:
Njoy!
Here are the steps to implement a Expression Design drawing as a Button Control.
I’ve placed a PushButton Design file in the Expression Gallery. A thousand people have actually downloaded the .design file. Only one question rose, asking how to implement that drawing as a Button Control. Here are the steps to do that:
In Design:
– Click the square on the Layer named PushButton to select all elements
– Select File/Export and in the dialog choose XAML Silverlight 4 Canvas, Leave Text Editable, set Live Effects to Convert to XAML, call it PushButtonNormal.xaml, remember where it is located after export. Click Export All.
– Click the square on the second Layer named PushButton Pressed to select all elements
-Select File/Export and use the same settings and location. Name it PushButtonPressed.xaml. Click Export All.
In Blend:
– Start a new Blend Silverlight Application, Call it PushButtonControl
– Open MainPage.xaml in the Code Editor using View/Active Document View/XAML View.
– Create a closing the tag for the Grid Named LayoutRoot.
– Open the PushButtonNormal.xaml file in Notepad. Cut the inner Canvas named PushButton, Paste in inside the LayoutRoot Canvas and remove Width, Height and Canvas.Left and Canvas.Top.
– Open the PushButtonPressed.xaml file in Notepad. Cut the inner Canvas named PushButton_Pressed, Paste it under the PushButton Canvas and remove Width, Height and Canvas.Left and Canvas.Top.
– Resolve naming conflicts for Ellipses, you can only have objects with unique names.
– Switch to Design Vieww using View/Active Document View/Design View.
– Right Click the PushButton Layer in the Objects and Timeline Panel. Select Group into…/Grid from the context menu.
– Right Click the PushButton layer in the Objects and Timeline Panel. Select Make into Control… from the context menu.
– In the dialog select the Button control and name it PushButtonControl. Click OK.
– This will create a Button Control and open ControlTemplate Editing Mode. A ContentPresenter is added to the Button. Because the PushButton container is a Canvas you have to reposition this using the Left and Top properties.
– Click the [Button] button in de Breadcrumbs at the top left of the Artboard to go out of Template Editing Mode.
– Right Click the PushButton_Pressed layer in the Objects and Timeline Panel. Select Cut from the context menu.
– Left Click the [Grid] layer in the Objects and Timeline Panel. Select the [Grid] button in de Breadcrumbs at the top left of the Artboard to go into Template Editing Mode again.
– Right Click the [Grid] layer and select Paste from the context menu. This will place the Pressed state of the button over the Normal state. Remove the top most Ellipse. This is the transparent shadow and should not show twice. Drag the PushButton_Pressed layer up so it is above the [ContentPresenter] layer. The word Button should appear.
– Set the Opacity Property of PushButton_Pressed to Zero (0%).
– Now you should have a [Grid] with 3 layer in it: PushButton, PushButton_Pressed and [ContentPresenter]. The Normal state should be visible. The word Button should be visible in it.
– Open the States Panel (Window/States should have a check before it) and select the Pressed State. The Pressed state recording should go on, showing a red frame around the Artboard.
– Set the Opacity of PushButton_Pressed back to 100%.
– Click the Base layer at the top of the States Panel and switch between the Pressed and Base state. Make sure the Buttons overlap exactly.
– Click the [Button] button in de Breadcrumbs at the top left of the Artboard to go out of Template Editing Mode.
– Select File/Save all
– Press F5 to build the project, so you can test it.
Optimization would include replacing the Canvases with Grid containers while keeping all Ellipses in their places. This would allow for better control of button size and placement of the ContentPresenter.
Njoy!
Now, with the new Pie Shape in Expression Blends 4 this has become a no-brainer. Here’s how.
During the evolution of Silverlight and Expression Blend we’ve had to create Pie Charts for various projects. Often these were to illustrate the state of a percentage value in the application. Thus we’ve build our own a few times over. Now, with the new Pie Shape in Expression Blends 4 this has become a no-brainer. Here´s how:
Of course, you can style a Pie Shape any way you want. Now it is easier than ever to show a percentage Pie Chart…
Njoy!
The FocusVisualElement is the equivalent of the dotted line that you see in Windows interfaces and on browser pages around an object on the page that “has the focus”. This means that it will receive the input a user is giving with a mouse, keyboard or touch. Actually, web designers don’t really like these dotted lines, because they degrade the look of their interface. It may disturb the carefully crafted look and feel of the page. But this FocusVisualElement has a function.
Normally I’m not so eager to use buttons as controls for showing examples. It usually doesn’t lead to an interesting visual result. As a designer my examples should look more interesting. Fortunately in Silverlight you can create other shaped and colored buttons easily using the Make into Control… option in the contextmenu of graphic elements gathered in a Grid. In this case the I’d like to focus on the FocusVisualElement element, so Buttons are my first choice.
In Silverlight the FocusVisualElement is an actual graphical element that is part of a control’s ControlTemplate. In Blend you can access this template by selecting Edit Template/Edit Current (I’d really like a keyboard shortcut here, but there isn’t, yet).
In template editing mode you can find the FocusVisualElement in every Silverlight control. It’s shape depends on the type of control, but in a Button it is a light blue Rectangle. By default this Rectangle has its Opacity set to Zero and the Focused State makes it visible. This leads to the notion that you can change the looks of this Focused State to anything you’d like:
In these images I show how a HyperlinkButton could get a Glow Effect when it is focused. But there’s no reason to leave it at that. The oval Button plays an animation when it is focused. Apart from the Opacity, a TranslationX, Scale and a PointAnimation is applied to a semitransparent Ellipse when the Focused State is triggered. This makes the Ellipse move van left to right. The animation is AutoReversed and repeated Forever.
You can use the VisualStateManager to create the animations. You can also show the TimeLine and create an Storyboard that you paste in de <VisualState x:Name="Focused" /> Visual State. When you create a Button using Make into Control… you can copy the Visual States out of the ControlTemplate of a normal Button and use them in your own.
Make sure your animation for the Focused State of controls are low-key. You don’t want to irritate your users with flashing graphics only because a control is focused!
Working code from these Buttons is on my SkyDrive…
Njoy!
Standard TabItems are not overlapping, but designers like them to. You may encounter a design with overlapping tabs that you have to create and implement. This is not a simple task, certainly when the tabs have a tapered side that overlaps the tab to the right of it. The Z-Index of these tabs are opposite to the standard layout.
Control Vendors have custom versions of a TabControl, that use properties for overlap. The Toolkit TabControl currently doesn’t support overlapping tabs, but by updating templates and a bit of C# code you can get the same effect. Here’s how it’s done:
Creating an overlapping tab in Expression Design:
figure 1: Create a round point at the bottom right corner.
figure 2: Create a smooth corner at the top right corner.
figure 3: Remove a anchor point to create a straight corner at the lower left corner.
Double click the Magnifying Glass Icon at the bottom of the toolbox to show the entire drawing. It helps to place the top right corner of the tab at the 0,0 coordinates using the Action Bar at the bottom of the screen. Check if the Foreground color is white and the border is black. Make sure the tab is selected, showing its bounding box and transformation handles, and select Edit, Copy from the menu.
Implementing overlapping tabs in Expression Blend:
figure 4. Creating a TabItem ControlTemplate
<controls:TabControl x:Name=”TabControl” Width=”500″ Height=”100″
Style=”{StaticResource TabControlStyle1}”
ItemsPanel=”{StaticResource ItemsPanelTemplate1}”
SelectionChanged=”TabControl_SelectionChanged”>
<controls:TabItem x:Name=”Tab_1″ Header=”Tab 1″
Style=”{StaticResource TabItemStyle1}”>
<Grid Background=”#FFE5E5E5″>
<TextBlock Text=”Area 1″ Margin=”20″/>
</Grid>
</controls:TabItem>
<controls:TabItem x:Name=”Tab_2″ Header=”Tab 2″
Style=”{StaticResource TabItemStyle1}”>
<Grid Background=”#FFE5E5E5″>
<TextBlock Text=”Area 2″ Margin=”20″/>
</Grid>
</controls:TabItem>
<controls:TabItem x:Name=”Tab_3″ Header=”Tab 3″
Style=”{StaticResource TabItemStyle1}”>
<Grid Background=”#FFE5E5E5″>
<TextBlock Text=”Area 3″ Margin=”20″/>
</Grid>
</controls:TabItem>
<controls:TabItem x:Name=”Tab_4″ Header=”Tab 4″
Style=”{StaticResource TabItemStyle1}”>
<Grid Background=”#FFE5E5E5″>
<TextBlock Text=”Area 4″ Margin=”20″/>
</Grid>
</controls:TabItem>
</controls:TabControl>
Getting the ZIndex right
All this will create the right shape and states of the the TabControl, but the order of the tabs is still wrong. By default the first tab is selected and a right tab will overlap a left tab. With overlapping tabs this should be the other way around. Setting the Canvas.ZIndex property of the TabItems in XAML won’t help. The control is initialized with the wrong settings at runtime.
A little C# helps. Thanks to Rachel, who solved this problem in WPF, we can set the overlapping tabs in the right order when the SelectionChanged event of the TabControl is fired:
private void TabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
TabControl tabControl = sender as TabControl;
tabControl.Dispatcher.BeginInvoke( new Action(() =>
UpdateZIndex(sender as TabControl)));
}
private void UpdateZIndex(TabControl tc)
{
if (tc != null)
{
foreach (TabItem tabItem in tc.Items)
{
tabItem.SetValue(
Canvas.ZIndexProperty,
(tabItem == tc.SelectedItem ?
tc.Items.Count :
(tc.Items.Count-1) – tc.Items.IndexOf(tabItem)));
}
}
}
The UpdateZIndex method is invoked in a way that updates all the TabItems. This way a left tab will show above a right tab the way you want in overlapping TabItems.
fig 5. Overlapping tabs have a reversed ZIndex.
Working code is at my SkyDrive…
Joe Gershgorin has refactored the code to use a Behavior. This also supp0rts longer text in the headers. You can find his version at: http://www.bitspy.com/OverlappingTabs_Silverlight4.zip
Njoy!