Jul 22, 2009

.NET Rocks Interview

 

I just had the pleasure of doing a .NET rocks podcast with Carl and Richard. It will be show #469 and should be available on August 4, 2009 (I will update this post with a link when it becomes available). It is show #469 and you can listen to it here.

The show is about touch based computing, touch based hardware, Surface, Win7, social computing and Richard’s Touchsmart in his kitchen. Good times.

We even dive into the risqué topic of “social touching”…..

Check it out.

Labels: ,

Jul 16, 2009

Blend 3 improvements

I am trying to put Blend 3 through its paces and here are a few random improvements I have found.

I will keep updating this post as I find more

Attribute Defaults

Setting an attribute to its default value (e.g. Setting HorizontalAlignment  to Stretch) will remove the value from the XAML. Previously you had to click on the Advanced Property options and chose reset it you wanted Blend to delete the auto generated XAML. Now, it seems, Blend it smart enough to not explicitly set the attribute.

Padding, Margin etc..

If you set a margin or padding value to all the same value in the Property Panel it will generate the short hand attribute syntax for you. So setting each margin to -10 in the Property panel will generate Margin=”-10” in the XAML. Again, it seems it is getting smarter about generating XAML.

Asset Library

Searching for assets in the library finally searches across multiple categories. The results are nicely displayed so you can see what was found in each category.  So now, for example, you can search for Surface Controls using the library without having to switch to the Custom Controls category first.

Design Time Height and Width

If you set a Width or Height property to Auto it will show you the design time value in parentheses after the word Auto. It will do something like Auto(756).

I find this extremely useful when designing items controls with custom data templates. You can see how much space it thinks it needs to take up to fit the content, while leaving your items control set to Auto.

Pack Syntax for Image Brushes

When you add an image to your project and make an ImageBrush resource from it. Blend with generate the proper pack syntax (component syntax) to reference the image.

ItemContainerStyle

Finally! The gods have spoken. When working with ItemsControls, you can now right click, select “Edit additional Templates” and select ItemContainerStyle. This was one of the most annoying quirks of Blend 2 for me. Previously you had to select the Items control and then go up to the Object menu and select “Edi additional styles, then select item container style. Now that is it in the context menu for ItemsControl it makes the work flow much more fluid.

Also, as a side note, I notice that the navigation in and out of the ItemContainerStyle seems to be improved. In Blend 2 there was strange behavior when you were editing ItemContainerStyle and moving back and fourth between the Style and the ControlTemplate. It doesn’t appear to be entirely fixed, but I am notice less of these weird issues were you are jumped around to the wrong object when trying to switch back and fourth.

Effect

Effect has been moved up to the the top level (above the expander) for the Appearance section. This is a nice touch, as I find myself using Effects often. Still, more times than not I use the search to filter the property list anyway, but having at the top level makes it faster.

That being said, I wish there was a way to customize which properties were shown. Being able to configure my own default property panel view would be great. Then I could put just the properties I use most often in the top panels and hide the other stuff in the expanders. For instance, in brushes panel I very rarely use the OpacityMask brush so I would it to save space, Likewise with the ZIndex in the Layout panel. Maybe in Blend 4?

Tools | Options

There a few new settings you can change under the Tools | Options menu.

Units

You can now change the default unit of measure (between pixels and points). I can this being useful when working with Photoshop or Illustrator files and importing them in to Blend.

Zoom

You can change the default behavior for MouseWheel zoom (between Just mouse wheel, Alt + MouseWheel, and Ctrl+ MouseWheel). I have been waiting for tihs so I can make Blend behave the same as Illustrator in this regard.

Effect Rendering

You can turn on and off the rendering of effects (not sure why you would want to this, except maybe to increase performance?) The other sneaky setting here is the zoom threshold level. Setting this causes effects to not be rendered beyond this threshold. This has tripped me up a few times already. When zooming way in on a button for instance, all of sudden my drop shadow effect disappears? Again, I suppose this feature is for performance reasons.

Annotations

You can now set default annotations properties for your documents, and optionally show them on the Artboard. You can set the Author name and Author initials.

SketchFlow

Finally there settings specific to SketchFlow documents. I haven’t dove too deeply into Skecthflow yet, but I will in the near future and have a new post strictly about SketchFlow.

Labels:

Jul 6, 2009

geekSpeak recording on Channel 9

Recently I recorded a geekSpeak interview on Touch Based computing and the general NUI paradigm shift.

I just noticed that the interview has been uploaded to Channel 9 now so if you missed it you can check it out here

http://channel9.msdn.com/shows/geekSpeak/geekSpeak-Recording-Touch-based-Computing-with-Brad-Cunningham/

It is a talk show based podcast so there isn’t much video to pay attention too but you can listen to it while you work (if you are that geeky :) )

If you listen to it and think it is awesome let me know (if you think it really sucks you can let me know too :( )

Labels: ,

Jul 3, 2009

TextTrimming in Silverlight 2

In a previous post I found myself hacking around in the Silverlight 2 trying to emulate drop shadows on text blocks (something that is natively supported in WPF but missing in Silverlight 2)

Once again, I find myself trying to emulate functionality that is natively supported in WPF and again it is related to TextBlocks.

In WPF when you have a TextBlock whose text could extend beyond the available space you have the option to trim the text using a specified TextTrimming setting. To do this in WPF you would set the TextTrimming property of the TextBlock element and be done. Something like this:

<TextBlock Text="A really really long string that should be trimmed"
TextTrimming="CharacterEllipsis" />


In Silverlight there is no such property on a TextBlock. So I created a quick and dirty implementation that works (for the most part)



I created a new UserControl called TrimmingTextBlock. The XAML for this control looks like this:



<UserControl x:Class="TextTrimming.TrimmingTextBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<TextBlock x:Name="TrimmedTextBlock" />
</UserControl>


All the “magic” (a.k.a hacking) happens in the code behind. I wanted the consumer of the control to be able to bind to a Text property, just like a normal TextBlock so I created a custom dependency property called Text



private static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text",
typeof(String),
typeof(TrimmingTextBlock),
new PropertyMetadata(String.Empty,OnTextChanged));


I need to display trimmed text but I still wanted the “Text” property of my control to maintain the original string. Trimming is only a display issue and shouldn’t impact the underlying data. So I created a second private dependency property called TrimmedText where I will store the display version of the string.



private static readonly DependencyProperty TrimmedTextProperty = DependencyProperty.Register(
"TrimmedText",
typeof(String),
typeof(TrimmingTextBlock),
new PropertyMetadata(String.Empty, OnTrimmingTextChanged));


So the first step is to make sure the TrimmedText property gets the value that is bound to the Text property. I do this in the OnTextChanged method (this is fired whenever the Text dependency property is changed). In the changed method I am getting an instance of my control and finding the TextBlock element and setting it’s text property to the new value.



private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var tb = d as TrimmingTextBlock;
if (tb != null)
{
tb.TrimmedTextBlock.Text = e.NewValue.ToString();
}
}


Now that the data is wired up correctly I have to do the actual trimming. In the ArrangeOverride method of my control I call my TrimText method



protected override Size ArrangeOverride(Size finalSize)
{
TrimText(this);
return base.ArrangeOverride(finalSize);
}


In TrimText I get the ActualWidth of the TextBlock. Since I have set the Text property already the ActualWidth will be the width in pixels that is needed to display the specified string of text.



I compare this ActualWidth to the DesiredWidth, that is the width that is available to the TextBlock. If the text is larger then the available space, that is if the ActualWidth is greater than the DesiredWidth, I need to trim.



My trimming implementation is simplistic but seems to work. I chop off one character at a time from the end of the string and then update the TextBlock with the new value. This causes a measure and arrange pass to fire which will call my trim method again and we can re-check the width.



I continue cutting off one character at time until the text will fit. Here is what the Trim method looks like:



private static void TrimText(TrimmingTextBlock block)
{
//Check the desired size of the text block and the actual size and trim accordingly
var actualWidth = block.TrimmedTextBlock.ActualWidth;
var desiredWidth = Double.MinValue;

if (desiredWidth == Double.MinValue)
{
desiredWidth = block.TrimmedTextBlock.DesiredSize.Width;
}

if (desiredWidth < actualWidth)
{
//Trim
String trimmedText = block.TrimmedTextBlock.Text;

if (!trimmedText.Contains("…"))
trimmedText += "…";

trimmedText = String.Concat(trimmedText.Substring(0, trimmedText.IndexOf("…") - 1), "…");
block.SetValue(TrimmedTextProperty, trimmedText);
}

}


This approach seems to work in most cases. For my purposes it does the job. This isn’t the most optimized code as it can cause a ton of Measure and Arrange operations. In fact in Silverlight 2 there is a known bug (which is fixed in SL3 beta1) that you cannot have more than 250 layout operations on one page. See this thread



Because of this bug this solution doesn’t really scale that nicely if you have the need for a bunch of TrimmingTextBlocks on one page. Or if you have a really long string that could cause more than 250 layout recursions.



This code could be optimized so that large strings cause fewer layout passes by intelligently removing more than one character at a time. But for me this works for now.



You can get the code with a few examples of usage from here