App bars in Windows Phone 7 are actually a pretty cool little bit of functionality. They give the user 1-4 instantly accessible options for dealing with the screen the user is on, their buttons auto-animate in, they offer “always on” funtionality that isn’t going to be hidden by the on-screen keyboard, they give designers and developers instant access to a range of default icons in Windows Phone 7 ecosystem and they offer a much wider range of options when the user taps on the ellipses to open more options.
That’s a lot for such a little thing item. So you may be asking yourself, “What the hell is he talking about? What is an ‘App Bar’?” This:
And like this when the ellipses are tapped
But what gets me is the fact that making these things is so damn easy, thanks to the fact that Blend is the single greatest product ever created for people who want to design user interfaces. And you can quote me on that. My crush on the Microsoft Blend team is well documented.
Anyway.
So let’s go about mak
Making the App Bar
ing this app bar. You may be surprised to know that we can do pretty much everything we need to do without a single line of code. Because Blend is so stinking awesome.
First, select the PhoneApplicationPage in your Object and Timeline tab in Blend.
In the “Common Properties” section, you’ll see an “ApplicationBar” property. Click on the “New” button. You should see the following:
Add App Bar Buttons
Click on the “…” button to the right of “Buttons (Collection)”. Up will pop a “Collection Editor: Buttons” pop-up. Click on the “Add another item” button.
Type “Button” and you should see a “ApplicationBarIconButton” option.
Double-click on it. It will add an App bar button to your app bar. You should have a set of “Common Properties” that you can set. Type in the text you want (in our case, “done”) and click on the IconUri box. You will see a list of default Windows Phone 7 icons. Pick the one that works for you (I picked the check mark).
Do that same thing over again, but pick the close icon and give it the text “close”. Hit “OK” to close the app bar pop-up. Believe it or not, we’re done. Yeah, we need to hook up some Click events so they can actually do something, but the rest of it is all taken care of.
If you need to get back to the App Bar design, you can just click on the ApplicationBar in the “Objects and Timeline” and see the options again.
Add App Bar Menu Items
Adding menu items is similarly easy. Under the “Buttons (Collection)” item we clicked on earlier, there is a “MenuItems (Colleciton)” button. Click on it.
We see the same “Collection Editor and we’ll click “Add another item” again. This time, though, we type “menu” and double click on ApplicationBarMenuItem.
Add the text (“do one thing”) and run the process again to add another item. Click “OK” when you’re done.
Colors & the Application Bar
Designing the App Bar is pretty easy. The icons that we assigned to the buttons actually just act as opacity masks (I assume that’s how it works… it seems to make sense) so that they will change to whatever color is assigned to the foreground of the app bar. Warning: they will default to the theme foreground unless you explicitly set them to be another color. If you’ve decided not to work with the default theming engine, you will need to explicitly set the foreground and the background of the App Bar.
I talk about this a little bit more in my post on Windows Phone 7 theming. That might be a good place to go if you’re working on fine-tuning the app bar to fit into a non-themed design.
I’m currently working on porting the run-away hit mobile application ShopSavvy to Windows Phone 7 (sign up to be a beta tester) and one of the things I really wished I had was the WrapPanel.
(For those who are new to Silverlight/WPF/Windows Phone 7, the WrapPanel stacks UI elements either horizontally or vertically like the StackPanel except that, when it hits the panel limit it… wait for it… wraps and starts stacking in a new column/row. Handy.)
I found a way to add it with the Silverlight Toolkit, but doing that added 140 Kb to my application. Maybe I’m just stuck in the world of J2ME, but adding 140 Kb to my mobile app isn’t OK if I can help it. I found this post from Jeff Wilcox on adding the WrapPanel and that didn’t seem to work for me. (My comments are the whiny ones at the end of the post.)
But I finally got it working and I’ll tell you how.
All you have to do is download the DLL, unzip and reference in your app like so:
Right click on the “References” section of your project.
Select the WP7Panels DLL from whatever folder you put it in and see it show up in your References
Open up the “Assets” section and type “wrap” or “dock” the wrap-or-dock panel should show up. Double click it or drag it onto the canvas to add it to your app. Blend will take care of the rest of the namespaces and everything.
And start adding items to your panel. It should work the way it’s supposed to work.
One note with the DockPanel… items placed in the DockPanel need to have the attached property
[xmlns]:DockPanel.Dock=”[something]”
if you want them to do something other than align in the center. The [xmlns] name should be the same thing that is before the “DockPanel” in the XAML. It will most likely be “WP7Panels”. Therefore, the following XAML:
If you want to add the actual files to your Windows Phone 7 app instead of just referencing the DLL (perhaps you are crazy or you have a deep and desperate need to fully understand absolutely everything you touch or you are a C++ developer), you can download the source. I’ve consolidated the DockPanel code into a single file (DockPanel.cs), but you’ll need the following files to get the WrapPanel working (all included in the source).
LengthConverter.cs
NumericalExtensions.cs
OrientedSize.cs
TypeConverter.cs
WrapPanel.cs
Finally, if you need something else for Windows Phone 7 from the Silverlight Toolkit, you can either add the entire toolkit (explained here) or download the source for the latest Silverlight 3 build and open it in Visual Studio 2010 (for some reason, I couldn’t get it to open in Visual Studio 2008). It should update and you should be all set playing around in there to extract the stuff you need.
In case you want to take a look at the unemployment visualization, I’ve added it below. I’m looking for a place to do ASP.Net hosting because my Bing Maps visualization is driven using Twitter data called and served through a WCF service, so if you have a recommendation for a noob ASP.Net guy, let me know. I’d love to host that as well.
(Apparently some people are having trouble with my demo below. I’ll try to get a more compatible version up soon.)
You can copy the code for to embed this with the text below:
CanKeyboardScroll property on the AnimatedScrollViewer so that keyboard scrolling can be turned off
ScrollToSelectedItem property on the AnimatedListBox so that the user can have it automatically scroll to a ListBoxItem
That last one is a little hacky… I use the ListBox ItemContainerGenerator to get the heights of all the items up to the one you want and then scroll it that. I’m almost positive there is a better way and if anyone knows what it is, I’d love to hear it.
OK… this is going to be something of a whirlwind since I’ve never written a post this in-depth before… it will strain the limits of my ADD.
Problem:
The Listbox/ScrollViewer not only doesn’t animate, but it seems impossible to tweak it so that it animates.
The Reason:
The reason has everything to do with the ScrollViewer. Basically, the ScrollContainer and the ScrollBars are very tightly intertwined. There is a lot of code that does all the scrolling calculations and that code needs to apply to the scrolled content as well as the UI for the ScrollBars. If you dig deep enough, you’ll see the reasons. Reasons which I assume for the moment you don’t care about… you’re probably in more of a “make the @#&($ thing work!” mood. I know I was.
The Solution:
My solution was basically to completely bypass the built-in ScrollBars and put in new ScrollBars with new logic. They look and act just like normal ScrollBars, so you should be able to style them just you would any normal ScrollViewer.
OK… how I did it. (I’m going to use both Blend 2 and Visual Studio 2008)
First, create a new custom control for WPF. This can be done by going into Visual Studio and creating a new Project. Select “WPF Custom Control Library”
In Blend:
Add a WPF application to the project too so you have something to test. In the WPF application, get Blend to generate the default template for a normal ScrollViewer, accessible (in Blend) by putting a ScrollViewer into the project and right-clicking on it and selecting “Edit Control Parts (Template) –> Edit a Copy…”
Once have the default ScrollViewer template, select the “PART_VerticalScrollBar” and the “PART_HorizontalScrollBar” and copy and paste them. Rename your new ScrollBars something you like… I used “PART_AniVerticalScrollBar” and “PART"_AniHorizontalScrollBar”. Now, set the Visibility of the original ScrollBars to “Collapsed”. (We can’t get rid of them, because the ScrollViewer will be looking for them and will throw a conniption if it can’t find them.)
Also, change the Value of your new ScrollBars to 0. You’ll probably have to click on the orange box next to Value and select “Reset”.
In Visual Studio, right-click on your WPF Custom Control project and go to “Add –> New Item…” . Then select “Custom Control (WPF)” and name it something you like (mine is named AnimatedScrollViewer). This should add a class to your project as well as a basic template to your Generic.xaml file.
Copy the ScrollViewer template that we just made and paste it into the Generic.xaml. The only change we need to make is to change:
TargetType="{x:Type ScrollViewer}"
to
TargetType="{x:Type local:AnimatedScrollViewer}"
in the Style and the ControlTemplate.
OK… that’s pretty much it with the XAML. Now we get to move into the code.
Right now, our class inherits from Control, but we want it to inherit from ScrollViewer like so:
public class AnimatedScrollViewer : ScrollViewer
Next get some containers for our new spiffy ScrollBars so that we can access them from the custom control code. Type the following before the class:
[TemplatePart(Name = "PART_AniVerticalScrollBar", Type = typeof(ScrollBar))] [TemplatePart(Name = "PART_AniHorizontalScrollBar", Type = typeof(ScrollBar))]
Before we address the three event handlers we added, we need to create the Dependency Properties with which they will be futzing.
(We’re going start going a little bit faster. Please download the code for the excruciating detail.) We need to add the following Dependency Properties. I’m using a “PropertyName (type)”.
Dependency Properties
ScrollingTime (TimeSpan) – This will be an easy way to change the speed of the scrolling. I created mine to default at half a second, but if you changed it to 0 seconds, it would act just like any normal ScrollViewer.
ScrollingSpline (KeySpline) – This property along with the ScrollingTime property is meant to give designers and developers the easiest control possible over the animation. This property describes the spline along which the scrolling will animate. If you don’t know what this means, just leave it alone, you’ll be fine.
TargetVerticalOffset (double) and TargetHorizontalOffset (double) – These are properties that tell the ScrollViewer where it will be animating to. In the PropertyChangedCallback, they kick off a method that starts the animation.
VerticalScrollOffset (double) and HorizontalScrollOffset (double) – For some reason the normal VerticalOffset and HorizontalOffset properties in a ScrollViewer are not capable of animation. So I wrote these properties that can be animated using standard storyboard procedures. If you use them to animate, make sure you also change the TargetVerticalOffset and TargetHorizontalOffset stuff as well… otherwise there will be a disconnect between the two.
Event Handlers
CustomPreviewMouseWheel event handler – This grabs any mouse wheel spinning and uses it to change the TargetVerticalOffset so that the ScrollViewer will still animate the scrolling when the mouse wheel spins.
VScrollBar_ValueChanged and HScrollBar_ValueChanged event handlers – These are called whenever the the ScrollBars are interacted with. There was a really weird problem with some of the interaction (the arrow keys and fast-scrolling buttons weren’t working properly), so these handlers hold logic to try to translate the weirdness into something viable. They then set the Target_Offset properties appropriately.
Methods
animateScroller – This method builds the animation programmatically based off of the appropriate properties and runs it.
And that’s really about it. Once you have the AnimatedScrollViewer working, you can just add use it inside your ListBox templates and it should work. (For those who are averse to doing such a thing, I’ve added extremely simple AnimatedListBox.)
I was working on a project recently and I wanted one of my layout controls to have a different margin based on a certain piece of data.
(It’s a long story… let’s just say that this is a good post if you want to change properties of a control based on a piece of data of a different type.)
So… for the sake of the argument, let’s say that I want my control to have a margin of “4,4,4,4″ if my data returns “dog” and I want it to have a margin of “2,2,2,2″ if my data returns “cat” and a margin of “0,0,0,0″ if the data is anything else.
Normally, I would use a value converter for this. My problem was that I was sick of using value converters for things so specific and using them only a couple times in my application. So I decided I wanted to do this one with styles and triggers.
First thing I did was bind my data to the “Tag” field.
Then, I created a style for my Border layout control. If you’re in Blend, go to Object –> Edit Style –> Create Empty…
Create a new property trigger by clicking on the “+ Property” button and change the property to “Tag”.
I couldn’t find a way to type “dog” into the field value, so I did it in the XAML (full XAML sample below, for those of you who want to cut to the chase… you know who you are).
With the property trigger highlighted, you’ll see a “Trigger recording is on” sign in the corner of your canvas.
Just change all the properties you want. Of course, in this case, I’m just going to change the Margin property. If we do the same thing for the “Cat” contingency, we get the following style.
And we end up with a layout that changes its properties based on a bound value. And we don’t have to write endless value converters. Pretty handy… or at least I thought so.
Fortunately for everyone involved (especially me), this tutorial is much shorter. It is also another in my “without a line of code” series in which you can do everything without even touching the code. Let’s open up our project in Blend and get started. (To see an example what this tutorial makes, scroll to the bottom of this post.)
First of all, I lied. You do have to touch one line of code because you need to get your NYT API key and plug it into the myApiKey variable in the Page constructor (line 26 in the project available for download). The line should look like this:
myApiKey = “&api-key=your_api_key_here”;
Now, right click on the project solution and select “Build Solution” (in Visual Studio or Blend, it doesn’t matter).
This should build the assemblies so that Blend can do a really neat trick. In the Project tab in Blend, you should see a Data panel in the bottom half. Click on the “+ CLR Object” button.
A pop-up will gently encourage you to name your new data source and choose from a list of available data sources. Select “NYTResult” and hit OK.
You will now have your NYTResult data source show up in your Data pane. Before we start building a nice slick looking interface, select your ListBox (named “ResultsDisplay”) and, in the Properties pane, find the “Display Member Path” and reset it by clicking on the little gray box to the right.
Now, right-click on the ListBox in your “Objects and Timeline” panel and select “Bind ItemsSource to Data…”
Select the data source you just created and select “NYTResult”. Then click on “Define DataTemplate” at the bottom. This will take you to the “Create Data Template” panel, where the fun happens. You will see “New Data Template and Display Fields” automatically selected. We like this. This lets us select all the data we want and give it some basic structure and Blend will do all the bindings for us.
Let’s make a few changes from the standard Data Template setup. Expand the Date field and check Day, DayOfWeek, Month, and Year and change the order with the up and down buttons to something you like. Then, change the Url from “StackPanel” to “TextBlock”. I reordered the data a little bit, so my template looks like this:
Hit OK. The point of that whole exercise was so that Blend would build our data template for us. We don’t actually want the data source and we don’t want our ListBox bound to it. So reset the “ItemSource” property on the ListBox and remove the NYTResult data source. If you run the project now, you should get something like this:
At least we’re getting more data now. Doesn’t look that great, but we’re getting there. Go back to your project in Blend and right-click on your ListBox and go to “Edit Other Templates –> Edit Generated Items (ItemTemplate) –> Edit Template”
We’re now in the DataTemplate but we sadly have no visible data, which makes manipulating it a tad difficult. What I have found works best for me is just to build my desired layout with static data and then translate the bindings. (I haven’t mentioned this, but you should be working in Split mode as a general rule, so you should be able to see the bindings in the XAML.)
So… long story short (it’s getting really late here): I changed the layout to replicate the NYT story design… the Title is a hyperlink button that takes us to the full story, followed by a small byline, the beginning of the story and the date on which the story appeared. If you’d like to look at the design itself in more detail, download the project at the end of this post.
I do want to mention one issue… the issue of getting your text to wrap. With my current redesigned DataTemplate, my project looks like this:
It scrolls horizontally to a degree that is certainly unhealthy. What is happening is that the TextBlock in the DataTemplate is making a request for space and when it hits a limit, it will start wrapping. Unfortunately for us, when the ScrollViewer in the ListBox has the HorizontalScrollBarVisibility set to “Auto”, it is telling the TextBlock that it has all the room in the world and that it doesn’t need to wrap. So, let’s just change the HorizontalScrollBarVisibility on the ListBox to “Disabled”.
Summary: In this post, I walk through the basics of using Silverlight to query the New York Times Article API and display the results of the query. You can see the final result below.
You can also download source code for this project here.
This project is somewhat code-intensive (and kind of long, expect 30-60 minutes), so if you just want the utility provided here without any of the work, you can skip over to my post on displaying the results, which is strictly a Blend tutorial.
However, I recommend walking through this one since it will help get you to a point of pulling real data from an API, which I’ve found to be a wonderful help as I practice putting together data-based designs. One of the things I’ve been wanting to be able to do as a designer is to explore a data set easily and quickly so that I can have data to play with in my interfaces. I found exactly what I wanted in the New York Times API, but then I found out I had to learn JSON.
“Oh great,” I said to myself, “another technology for me to learn.” But it turned out that I didn’t actually have to learn that much, because Visual Studio does nearly all the work for me.
Super Quick Introduction to JSON
If you’re not interested and you want to get to the business of grabbing New York Times data, you can skip it . It is helpful, but not strictly necessary.
JSON stands for JavaScript Object Notation and is basically just a really handy way to pass data along in a web service. It is very simple… within a set of curly brackets, you will have name/value pairs separated by a colon with each piece of data.
Example:
{
FirstName : “Matthias”,
LastName : “Shapiro”,
Blog : “Designer WPF”
}
This is a JSON object. Arrays are created by using square brackets and JSON obejcts can be placed into a Javascript var. These things are not really related in anyway, but putting them in the same sentence allows me to only write one more example instead of two
What is so awesome about JSON and Silverlight is that Visual Studio 2008 has a set of JSON-friendly classes that make working with JSON a breeze. Which is really handy because the New York Times, which is a dream come true for the new data-gatherer, delivers JSON results. So let’s walk through making a call to the New York Times Article API, handling the data we get back, and putting it into a Listbox for viewing.
Next, start a new Silverlight project in Visual Studio 2008. I named mine “JSONNewYorkTimesTutorial”.
Open your new project in Blend, pull up Page.xaml and add a TextBlock, ListBox, a TextBox and a Button. Name the ListBox “ResultsDisplay” and the TextBox “SearchText”.
Now, my Page.xaml looks like this.
OK… now let’s go to the code-behind for our project go to the event section of the button in Blend and type “PerformQuery” into the “Click” event.
This will automatically insert the necessary code into the code-behind, so pull up Visual Studio. Before we implement a call to the NYT API, lets add some useful stuff. If you have not yet gone to get your Developer key, do so now.
public Page()
{
InitializeComponent();
myApiKey = “&api-key=(put your api key here. No, you may not have mine)”;
callNYT = new WebClient();
callNYT.OpenReadCompleted += new OpenReadCompletedEventHandler(callNYT_OpenReadCompleted);
}
In the code above, we’ve created a string that we can use to apply our unique NYT API key and we’ve created an instance of WebClient to call and receive information from the NYT API. When an object from the NYT API has been received , it will call the OpenReadCompleted event, which will be handled by our callNYT_OpenReadCompleted method.
(By the way, if you’re not getting the proper intellisense for the “Web Client” part, add “using System.Net;” to the top of your file.)
Now on to our button method. There are tons of things we can add to our query to find the exact information we want. But in the interest of simplicity, this post will deal only with a simple text search. To that end, let’s go to our PerformQuery method and turn it into this:
We’ve done two things here. The first is that we built our search query using the query base, the query string and our API key. That was simple enough.
Next, we’ve going to use the WebClient we created to call our new query. When the query has been completed, our program will run the callNYT_OpenReadCompleted method with its result, which will be a JSON object constructed by the NYT servers. We will get back a JSON object with the following:
offset – We will get 10 results per page. The offset tells us which page of the results we’re on. The default is 0, which gives us results 0 – 9.
tokens – this is a array of our search terms.
total – this is an integer indicating of how many results there were for our search.
results – this is an array of results with the following format
body – a portion of the beginning of the article
byline – the article byline, usually including the author name
date – the date the article appeared, in a “yyyymmdd” format. For example, today would be “20090225”.
title – the article title
url – a url link to the article
A quick note: The NYT API is extremely flexible and we can actually define how we want our results to come back. This is just the default result format for the purposes of demonstration.
Before we handle this object, we want to create a class for the results. Right click on your project and go to “Add –> Class…”. Name your new class “NYTResult.cs” and make sure it looks like this:
public class NYTResult { public string Body { get; set; } public string Byline { get; set; } public DateTime Date { get; set; } public string Title { get; set; } public Uri Url { get; set; }
}
I added the following method to the class to handle the date conversion from the NYT format to a .NET DateTime object.
public DateTime formattedDateTime(string NYT_Time)
{ int year = Convert.ToInt32(NYT_Time.Substring(0, 4)); int month = Convert.ToInt32(NYT_Time.Substring(4, 2)); int day = Convert.ToInt32(NYT_Time.Substring(6, 2)); DateTime finalDateTime = new DateTime(year, month, day); return finalDateTime;
}
OK… now we’re really ready to handle the JSON object. Right click on the references in your project and select “Add Reference…”
In your “Add References” box, select “System.Json” and click “OK”.
Add “using System.Json;” to the references in your Page.xaml.cs file. And, just for good measure, add “using System.Collections.ObjectModel;” as well.
Go to the callNYT_OpenReadCompleted method and enter the following. I’ve tried to comment the code so that I don’t need to further explain it. Side note: I’m not always the best at understanding what is self-explanatory and what I need to elaborate on. If there are any additional questions, post them in the comments and I’ll answer as quickly as I can.
void callNYT_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{ //grab our result and make a JSON Object out of it // then extract the results array from that object JsonObject completeResult = (JsonObject)JsonObject.Load(e.Result); JsonArray resultsArray = (JsonArray)completeResult["results"];
//an observable collection to hold the data and attach it to our ListBox
ObservableCollection<NYTResult> resultCollection = new ObservableCollection<NYTResult>();
//iterate through the results and transfer the data from a // JSON object into our nice pretty .NET object foreach (JsonObject NYTRawResult in resultsArray)
{ NYTResult singleResult = new NYTResult();
//don’t forget to check your results… an article might not have a // byline or a link if (NYTRawResult.Keys.Contains(“body”))
singleResult.Body = NYTRawResult["body"]; if(NYTRawResult.Keys.Contains(“byline”))
singleResult.Byline = NYTRawResult["byline"]; if (NYTRawResult.Keys.Contains(“date”))
singleResult.Date = singleResult.formattedDateTime(NYTRawResult["date"]); if (NYTRawResult.Keys.Contains(“title”))
singleResult.Title = NYTRawResult["title"]; if (NYTRawResult.Keys.Contains(“url”))
singleResult.Url = new Uri(NYTRawResult["url"]);
//add our new result to the collection resultCollection.Add(singleResult);
}
//assign the result as the source for our ListBox ResultsDisplay.ItemsSource = resultCollection;
//take the overall article count and display it resultCount.Text = “Number of articles: ” + completeResult["total"].ToString();
}
Now, we can run our project. Type something into the TextBox and hit the button and we get this:
Not exactly the most readable thing ever. So let’s add the following to the ListBox XAML:
DisplayMemberPath=”Title”
Now we get something a little more like this (go ahead and give it a whirl):
Much better. Remember, this is a simple query, so it’s only looking for items that have that word in the article… it might not be in the title.
My next post builds on this one and I walk through building a more useful display for our results. It will be far less code intensive and far more designer centric.
I’ve made the source available for this project. I’ve taken out my NYT API key, so it will not run unless you get your own and put it in.
I’d been holding out on this post in the interest of getting it just right. I think with more time I would add more stuff, but I stumbled across Scott Barnes’ post “I hate it when a designer touches XAML” and I knew that I need to get this posted. Here we have these fantastic tools for integrating the designer more deeply into the workflow and so few people are using it. That’s got to change.
Confession time… I am not, by trade, a designer in the sense that most people use the word… a graphic designer. I try to keep my focus much more on the Usability/UX/Human Computer Interactions/Whatever-The-Cool-Kids-Call-It-These-Days. I do some graphic design if I must, but the fact of the matter is that I’m not really that good at graphic design.
However, I often step in as a go-between for the designer’s comps and the developers code. And one thing that I’m good at is translating comps from Photoshop or Illustrator into XAML for the actual application.
To all designers… I can see why you are disappointed when you see your beautiful designs slaughtered in the translation process… because your designs are beautiful! And with Silverlight and WPF there is absolutely no reason why your designs should not be under your control pretty much all the way through the process. These tips are designed to help ease the transition from comp to user interface.
Pre-Tip: Work in Blend
All of these tips are assuming that designers are building comps with another design tool like Illustrator or Photoshop and then moving the comps into Blend. If you’re not using Blend, you should be. I am not suggesting that you change your design tools or that you design differently. These are just tips for the translation process.
Tip 1: Two layers of semi-transparent gradients is fine. Twelve layers of semi-transparent gradients is not
Whenever you add a transparency layer, you add another run of rendering to all the pixels in that layer. Doing that once or twice is fine… most machines can handle that. But when you have a bunch of them, you’re begging to bring the machine to a crawl. Look at the two gradients below…
The one on the right is a solid background with two transparent gradients (a light one at the top and a dark one on the bottom). The one on the left is a single gradient. The one on the right required three passes to render. The one on the left requires one.
This does not mean that you can never have transparency in your application. But if you can figure out an economy of layers when using transparency, you’ll save yourself from from developers who are willing to make the design trade off to speed up the application.
Tip 2: The Grid layout is your new best friend. Understand it. Use it. Love it.
I once worked with a designer who used Blend and made the most beautiful screens with it. But when it came to implement his designs, the developers ended up ditching most of his work because every element was inside a layout inside a layout inside a layout… etc. This ends up being a huge performance killer because every layout means another set of layout calculations for the layout manager.
Instead, make creative use of the Grid layout. Within the Grid layout, you can create columns and rows with the following options:
Auto (with Min/Max options) – This column will ask the items inside it how much room they need and will expand or contract to give them exactly the room they need and no more (within the min/max limits).
Fixed Width/Height (“80″) – A fixed height or width will take exactly that many pixels of space. Easy enough.
Star (“*”) (with Min/Max options ) – this can be used as a decimal or a percentage… “.8*” or “80*”. It asks the container holding it how much room it has. After the Auto and Fixed columns or rows allocate their needed space, the “*” ones take up all the remaining available space unless hindered by the min/max limits.
A single grid can use any number of rows and columns using any combination of Auto, Fixed and Star. You would be shocked at how flexible this is. You can build whole screens using a single grid. I don’t recommend that, but keep the idea of fewer layouts in mind when you are translating designs. Not every element in the project needs to be inside its own layout.
Tip 3: Use Borders, not Rectangles
Borders play nice with pretty much anything you want to do with the added benefit of being able to put stuff in it. Additionally, they are really simple layouts, so they don’t use much overhead. Take a border and put a Grid into it and you have a visually compelling and flexible combination.
Tip 4: Draw simple vector art inside Blend.
Mike Swanson has a fantastic Adobe Illustrator-to-XAML plug-in. I’ve heard that some people can use Expression Design quite well. But unless your project is extremely visual in an artsy kind of way, you should just draw simple vector art inside Blend. Not only will you save yourself the exporting-importing trouble, your XAML will look nicer and be easier to change later on.
I usually draw with the pen tool inside a Grid layout and then use the direct selection tool to make the tweaks I need.
Tip 5: (Silverlight Only) Plan on using only a few fonts
Most of my experience with fonts in Silverlight have been somewhat painful. Hopefully we’ll see that change in Silverlight 3, but in the meantime it is something that I’ve seen even experienced developers fight with. Watch this video by Tim Heuer… it will help. () And put this blog on your RSS feed… I’m working on a step-by-step tutorial for this geared at non-developers.
Tip 6: Work in “Split” mode in Blend and goof around with the XAML every now and again
Blend as a drag-and-drop design tool is absurdly powerful. Using Blend, you could build an interactive wireframe prototype in 15 minutes and never touch a line of code.
But as awesome as it is, it will be necessary from time to time to go into the XAML and tweak this or that or comment something out or copy-paste something else. Simply put, understanding XAML will make transitioning your designs a breeze and having Blend in “Split” mode will let you know just what your work in the design space is doing to the XAML. It’s a pretty painless way to start the XAML learning process.
If you’re interested in getting into the XAML a little more, I would recommend using Visual Studio 2008 in tandem with Blend. It offers intellisense (auto-complete for code) and integrates extremely well with Blend.
Hope that helps… If anyone has any questions, feel free to post them here. If you need more in-depth help, ping me at matthias dot shapiro (at) gmail dot com.
Last night I submitted my MIX 10K Challenge piece, so I’m just killing time while I wait for it to get accepted. Please keep me in mind if you plan on voting.
OK… I’ve been excited about this for some time now. I found out (almost completely by accident) that you can animate a mask (also known as a clipping path) in Silverlight without writing code or even typing (much). This is exciting because I think it’s something that might interest our Flash friends who, late at night and in the privacy of their own homes, take a peek to see if Silverlight is worth looking into. When I worked with Flash, mask animations were my bread and butter and they seemed so hard to do in Silverlight.
But they’re not.
First open up your project in Blend. (I always create my project in Visual Studio and then open it in Blend because visual Studio has so much better project debugging and makes testing a breeze.)
Find the item you want to clip (in my case this is an image) and select the pen tool from the toolbar.
And start drawing.I’m a poor artist, so the star I drew looks pretty bad. If you need to change any of the points, use the direct selection tool (the light arrow, second from the top).
OK… now the fun part. Add a storyboard to your project
and you can animate the clipping mask using all the normal animation tools. Use the direct selection tool above to animate the vertices. You’ll get something like this:
Now… if you’re not interested in the details, just skip ahead a little bit. Something important happened the moment we started animating the path. Normally, path data is kept in a single string format that looks something like this:
This is actually a “powerful and complex mini-language that that you can use to describe geometric paths in XAML.” Microsoft uses it by default to handle path data. But it doesn’t work very well for animating paths, so the second you animate a single vertex in your path, it changes the format you see above to the format you see below:
Same data, but only this latter format is appropriate for animation. Remember this, it will come in handy in a second.
OK… now right click on your path and go to “Path –> Make Clipping Path”
You’ll get a dialog pop-up that will ask you which item in the visual tree you would like to clip. I chose my image, but it will work with anything.
And… poof! You have clipping animation.
LIMITATIONS: Here are the limitations to this method:
You need to animate before you make your path into a clipping path. – Remember that little bit above about the data string format vs. path geometry? If you don’t animate before hand, Blend will convert all your beautiful line segments into the un-animate-able data string. Animating the path tells Blend to leave your formatting alone.
Once you make your path a clipping path, animation gets a lot harder – Basically, you can change the time by dragging the key frames around and change the easing. Any other alterations require entering values by hand. So do all your animation first before setting the path. The easiest work around to this is to copy and paste your path out of the Control.Clip section and back into your main XAML and tweak animation from there. But your best option is to just take the time to make your clipping animation perfect before you make it a clipping path.
Seeing as how I’ve already spent far too much time on this little project, barring major problems with this control (please point them out!) this will probably be my last version of the control. My ADD is kicking in and I need to work on something else.
If you’re interested in having the compact version of this control as a gadget, you can find it here.
To add this to your application, just add the DLL above to your application by right clicking on the References folder in your Silverlight app.
Find the DLL and bring it into the application.
Open up the asset library (the bottom of the tool bar on the far left) and go to “Custom Controls”. You should find the ColorPicker in there.
Now you can just draw the whole thing right into your application.
Easy as pie.
You can swap between an extended view and a compact view by changing the “IsCompact” property. Compact view is basically gadget sized and expanded view can be as big as the screen if you want it to be.
Whenever you change the color, the control fires off a “ColorChanged” event. I thought that would be valuable for dynamic interactions. Hopefully you can find some fun uses for it.