Category Archives: Uncategorized

Displaying Webcam Preview in a Metro App Using WinRT and XAML

Note: the WinRT XAML Toolkit library that I share here has a CameraCaptureControl that makes it simple to host the camera preview, take pictures or record videos.
Note: This article is based on Windows 8 Developer Preview version and it should still be relevant with Windows 8 RTM, but please let me know if that is not the case.

I was looking at the controls available in WinRT () and I’ve stumbled upon this control called – CaptureElement. What it does is it “Represents a media capture from a capture device, for example recorded video content.” I thought I’d give it a go and see if I can display the output from the webcam on screen – which could be useful for AR (Augmented Reality) applications or even just for fun. This is how you do a preview then…

Continue reading

Advertisements
Tagged , ,

Beginning WinRT development

I finally found some time to take a look at Windows 8 development + a shiny Build edition Samsung Series 7 Slate device, so it is time to start taking apart this WinRT development thing.
I am starting by setting up my development and blogging environment. I installed Live Essentials to use my usual Live Writer, which took a while since it first had to enable .NET 3.5… Well, it is good to know 3.5 is alive and kicking! 🙂

Now I still haven’t figured out the best way to paste code in Live Writer – VS Paste plugins output weird frames, while copying through Word looks nice, but it breaks quotes and some other characters, besides – I don’t have Office on this unit, which also means – I can’t use OneNote to do screen clippings. Well – I’ll figure something out I guess.

Creating a simple Windows 8 app

When you start Visual Studio 11 Express and start a new project you get to choose a couple of things:

image

First – the language – JS/VB/C#/C++. I chose C#. This is what I know best and while I believe it is worth learning something new – I still believe C# and .NET is in many ways better than JS+HTML5+CSS and what these are best is in attracting developers who already know these best.

Then – picking a project template – I just selected Application, since I want to focus on the basics first before I look at the cooler controls, whatever the temptation says.

I end up with the following minus the yellow rectangle that I added to see some content in the window and the one attribute per line formatting that I prefer:

<UserControl
    x:Class="Application1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768"
    d:DesignWidth="1366">
    <Grid 
        x:Name="LayoutRoot" 
        Background="#FF0C0C0C">
        <Rectangle
            Fill="Yellow"
            Width="200"
            Height="200" />
    </Grid>
</UserControl>

When I hit F5 – I get the below image displayed on full-screen:

image

Great! A simple application is indeed very similar to Silverlight or WPF. I wonder why the default background is almost black… It looks pretty cool when I change my rectangle background to black – almost a screen test: Smile

image

I mentioned one attribute per line – this is my preference and recommendation in XAML development as it reduces the need for horizontal scrolling and makes reviewing and merging changes easier. It turns out it works just as well in VS11Express as it does in VS10 for Silverlight and WPF – just go to Tools/Options/Text Editor/XAML/Formatting/Spacing (yeah, just) – and click to “Position each attribute on a separate line” and uncheck “Position attribute on same line as start tag”:

image

Now while at it – also save yourself some time and go to XAML/Miscellaneous and check “Always open documents in full XAML view” – this gives you more space to code your XAML and prevents delays when VS loads the XAML designer.

image

It seems like the root control in XAML of a default screen type in WinRT is a UserControl – just like in Silverlight – another point for compatibility with Silverlight and against WPF where you usually deal with Window objects.

What is a UserControl? According to MSDN – it has same inheritance hierarchy as the one in Silverlight, though it throws in a bunch of interfaces – a side effect of WinRT’s close ties to C++ and cross-language support I guess:

image

Tagged , , , , ,

WordPress and Live Writer

<Rant>I kinda like Live Writer for being a desktop app with rich “WYSIWYG” editing, plug-ins, etc. but it is also pretty limited. I tried updating some old posts to have them all use Calibri and instead of getting the old versions updated – I got new copies of old posts. This sucks. <Rant.Actual>Why is there no option to set the default font in Live Writer? Am I supposed to now change the font in L.W. and then copy&paste the HTML source into the WordPress UI?</Rant.Actual></Rant>

Tagged ,

Debugging visual tree/layout issues in Silverlight and on Windows Phone

Many times, especially when you are doing dynamic layouts, dealing with bindings and DataTemplates – you start scratching your head trying to figure out why your control is not showing up where you want it to show, how to fix it or simply what are the coordinates of some point. You can look through your code, but sometimes the problem is not in your code or it just is not clear.

In such situations it often helps to debug the visual tree of the application and you can do it by browsing the object tree in Visual Studio, but it is sometimes quite laborious since you would usually have to call VisualTreeHelper.GetParent many times before you get to where the problem lies – if you do not get confused on the way and give up. In WPF – I used to use Snoop or Mole. In Silverlight – I did not hear of such tool (I just found about Silverlight Spy today – but it is not free if you want to do anything with Windows Phone). To help solve it I used to write or copy&paste a small attached dependency property that makes the VisualTreeHelper.GetParent calls for me and outputs the interesting properties when a control gets loaded. Today I finally decided to clean it up a bit, make it better and share it with you, so here it is.

Download the sample project here

http://dl.dropbox.com/u/1192076/VisualTreeDebugger.zip

This is just a Windows Phone (Mango) panorama project straight from the template with my VisualTreeDebugger class added and two breakpoint properties defined on some TextBlocks. One will break each time the DataTemplate that includes the TextBlock is applied and the TextBlock loaded, the other one – when you tap on one of the TextBlocks.

How do I use it?

Simply add the VisualTreeDebugger class to your own project, spacify the xmlns reference in XAML and either set VisualTreeDebugger.BreakOnLoaded="True" on your control to have the debugger break when the control first loads or VisualTreeDebugger.BreakOnTap="True" to break when you tap that control. Then just run it from your Visual Studio with debugger attached (F5).

<!--Panorama control-->
<controls:Panorama
    Title="my application">
    <controls:Panorama.Background>
        <ImageBrush
            ImageSource="PanoramaBackground.png" />
    </controls:Panorama.Background>

    <!--Panorama item one-->
    <controls:PanoramaItem
        Header="first item">
        <!--Double line list with text wrapping-->
        <ListBox
            Margin="0,0,-12,0"
            ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel
                        xmlns:local="clr-namespace:VisualTreeDebugger"
                        Margin="0,0,0,17"
                        Width="432"
                        Height="78">
                        <TextBlock
                            local:VisualTreeDebugger.BreakOnTap="True"
                            Text="{Binding LineOne}"
                            TextWrapping="Wrap"
                            Style="{StaticResource PhoneTextExtraLargeStyle}" />
                        <TextBlock
                            local:VisualTreeDebugger.BreakOnLoaded="True"
                            Text="{Binding LineTwo}"
                            TextWrapping="Wrap"
                            Margin="12,-6,12,0"
                            Style="{StaticResource PhoneTextSubtleStyle}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </controls:PanoramaItem>
</controls:Panorama>

 

What do I get

You get a “path” field which is a list of all dependency objects between your debugged element and the visual tree root. It makes it easy to quickly get access to any of those objects to inspect their properties, when you debug it.

image

image

In the Output/Debug (Ctrl+W, O) window for each of these elements – you get a trace of selected layout properties that may affect the layout, including type, name, actual dimensions and position, logical properties like Width, Height, alignments, Margin and Padding, DataContext and brush information to sweeten the deal.

path[22] is Control: Microsoft.Phone.Controls.Panorama():
    ActualWidth=480
    ActualHeight=800
    Position – X=0, Y=0, Right=480, Bottom=800
    DataContext: VisualTreeDebugger.MainViewModel HashCode: 74304488
    Width=NaN
    Height=NaN
    HorizontalAlignment=Stretch
    VerticalAlignment=Stretch
    Margins=0,0,0,0
    Background=ImageBrush: System.Windows.Media.Imaging.BitmapImage, UriSource: PanoramaBackground.png
    Foreground=SolidColorBrush: #FFFFFFFF

How does it help?

You can find that control somewhere in the dozens of elements of your visual tree that has the alignment or margins set incorrectly or screen position of some invisible panel, find the actual dimensions of the element you need to fill with an image, see which element sets the background for all its contents or simply learn about the structure of the UI. It is easy to use and modify.

Why should I care about this project?

On Windows Phone – rather than coding it yourself – the only other option for debugging visual trees I found was to pay for Silverlight Spy.

With the source code – you can easily add more details that you think might be missing or simply browse the Visual Studio “Watch” window to find them.

Full Source Code of VisualTreeDebugger for quick copy & paste

#if DEBUG
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace VisualTreeDebugger
{
    /// <summary>
    /// The class contains an BreakOnLoaded property that
    /// allows to debug a visual tree from the control
    /// it was applied to up to the visual tree root.
    /// </summary>
    /// <remarks>
    /// Just put a breakpoint in ControlLoaded()
    /// and set VisualTreeDebugger.BreakOnLoaded="True"
    /// on any FrameworkElement/Control.
    /// <para/>
    /// Set BreakOnLoaded if you want to put the breakpoint yourself.
    /// <para/>
    /// DebugVisualTree method has a local path variable
    /// that contains a list of all elements from the visual tree root
    /// up to the debugged control.
    /// <para/>
    /// Debug Output window contains common visual tree layout properties
    /// helpful in debugging layout issues.
    /// </remarks>
    public class VisualTreeDebugger
    {
        #region BreakOnLoaded
        /// <summary>
        /// BreakOnLoaded BreakOnLoaded Dependency Property
        /// </summary>
        public static readonly DependencyProperty BreakOnLoadedProperty =
            DependencyProperty.RegisterAttached(
            "BreakOnLoaded",
            typeof(bool),
            typeof(VisualTreeDebugger),
            new PropertyMetadata(false, OnBreakOnLoadedChanged));

        /// <summary>
        /// Gets the BreakOnLoaded property. This dependency property 
        /// indicates whether the debugger should BreakOnLoaded when control is loaded.
        /// </summary>
        public static bool GetBreakOnLoaded(DependencyObject d)
        {
            return (bool)d.GetValue(BreakOnLoadedProperty);
        }

        /// <summary>
        /// Sets the BreakOnLoaded property. This dependency property 
        /// indicates whether the debugger should BreakOnLoaded when control is loaded.
        /// </summary>
        public static void SetBreakOnLoaded(DependencyObject d, bool value)
        {
            d.SetValue(BreakOnLoadedProperty, value);
        }

        /// <summary>
        /// Handles changes to the BreakOnLoaded property.
        /// </summary>
        private static void OnBreakOnLoadedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                ((FrameworkElement)d).Loaded += ControlLoaded;
            }
            else
            {
                ((FrameworkElement)d).Loaded -= ControlLoaded;
            }
        }
        #endregion

        #region BreakOnTap
        /// <summary>
        /// BreakOnTap Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty BreakOnTapProperty =
            DependencyProperty.RegisterAttached(
                "BreakOnTap",
                typeof(bool),
                typeof(VisualTreeDebugger),
                new PropertyMetadata(false, OnBreakOnTapChanged));

        /// <summary>
        /// Gets the BreakOnTap property. This dependency property 
        /// indicates whether the attached debugger should break when
        /// the FrameworkElement on which this property is set is tapped.
        /// </summary>
        public static bool GetBreakOnTap(DependencyObject d)
        {
            return (bool)d.GetValue(BreakOnTapProperty);
        }

        /// <summary>
        /// Sets the BreakOnTap property. This dependency property 
        /// indicates whether the attached debugger should break when
        /// the FrameworkElement on which this property is set is tapped.
        /// </summary>
        public static void SetBreakOnTap(DependencyObject d, bool value)
        {
            d.SetValue(BreakOnTapProperty, value);
        }

        /// <summary>
        /// Handles changes to the BreakOnTap property.
        /// </summary>
        private static void OnBreakOnTapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var frameworkElement = d as FrameworkElement;

            Debug.Assert(frameworkElement != null, "BreakOnTapProperty should only be set on FrameworkElements.");

            if ((bool)e.NewValue)
            {
                ((FrameworkElement)d).Tap += ControlTapped;
            }
            else
            {
                ((FrameworkElement)d).Tap -= ControlTapped;
            }
        }
        #endregion

        /// <summary>
        /// Occurs when the control this behavior is BreakOnLoaded to gets loaded.
        /// Put a breakpoint in here and set ControlDebugOnLoaded.BreakOnLoaded="True"
        /// on any control to debug its visual tree.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private static void ControlLoaded(object sender, RoutedEventArgs e)
        {
            var startElement = (DependencyObject)sender;
            DebugVisualTree(startElement);
        }

        static void ControlTapped(object sender, GestureEventArgs e)
        {
            var startElement = (DependencyObject)sender;
            DebugVisualTree(startElement);
        }

        #region DebugVisualTree()
        public static void DebugVisualTree(DependencyObject startElement)
        {
            var path = new List<DependencyObject>();
            var dob = startElement;

            while (dob != null)
            {
                path.Add(dob);
                dob = VisualTreeHelper.GetParent(dob);
            }

            for (int i = path.Count - 1; i >= 0; i--)
            {
                TraceDependencyObject(path[i], i);
            }

            // Put breakpoint here
            Debug.WriteLine(
                string.Format("Watch path[0] to path[{0}]",
                path.Count - 1));

            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
        }
        #endregion

        #region TraceDependencyObject()
        private static void TraceDependencyObject(DependencyObject dob, int i)
        {
            var frameworkElement = dob as FrameworkElement;

            if (frameworkElement == null)
            {
                Debug.WriteLine(
                    "path[{0}] is Dependency Object: {1}",
                    i,
                    dob.GetType());
            }
            else
            {
                var c = frameworkElement as Control;
                var cc = frameworkElement as ContentControl;
                var panel = frameworkElement as Panel;
                var parentGrid = frameworkElement.Parent as Grid;

                Debug.WriteLine(
                    "path[{0}] is Control: {1}({2}):",
                    i,
                    frameworkElement.GetType(),
                    frameworkElement.Name ?? "<unnamed>");

                // Actual layout information
                Debug.WriteLine("\tActualWidth={0}\r\n\tActualHeight={1}", frameworkElement.ActualWidth, frameworkElement.ActualHeight);
                var pos = frameworkElement.TransformToVisual(Application.Current.RootVisual).Transform(new Point());
                var pos2 = frameworkElement.TransformToVisual(Application.Current.RootVisual).Transform(new Point(frameworkElement.ActualWidth, frameworkElement.ActualHeight));
                Debug.WriteLine("\tPosition - X={0}, Y={1}, Right={2}, Bottom={3}",
                    pos.X,
                    pos.Y,
                    pos2.X,
                    pos2.Y);

                // DataContext often turns out to be a surprise
                Debug.WriteLine("\tDataContext: {0} {1}", frameworkElement.DataContext, frameworkElement.DataContext != null ? "HashCode: " + frameworkElement.DataContext.GetHashCode() : "");

                // List common layout properties
                Debug.WriteLine("\tWidth={0}\r\n\tHeight={1}", frameworkElement.Width, frameworkElement.Height);
                Debug.WriteLine("\tHorizontalAlignment={0}\r\n\tVerticalAlignment={1}", frameworkElement.HorizontalAlignment, frameworkElement.VerticalAlignment);

                if (cc != null)
                {
                    Debug.WriteLine(
                        "\tHorizontalContentAlignment={0}\r\n\tVerticalContentAlignment={1}",
                        cc.HorizontalContentAlignment,
                        cc.VerticalContentAlignment);
                }

                Debug.WriteLine("\tMargins={0}", frameworkElement.Margin);

                if (cc != null)
                {
                    Debug.WriteLine("\tPadding={0}", cc.Padding);
                }

                if (panel != null)
                {
                    Debug.WriteLine("\tBackground={0}", panel.Background);
                }
                else if (c != null)
                {
                    Debug.WriteLine("\tBackground={0}", BrushToString(c.Background));
                    Debug.WriteLine("\tForeground={0}", BrushToString(c.Foreground));
                }

                if (parentGrid != null)
                {

                    var col = Grid.GetColumn(frameworkElement);
                    var row = Grid.GetRow(frameworkElement);

                    if (parentGrid.ColumnDefinitions.Count != 0 || col != 0)
                    {
                        Debug.Assert(
                            col < parentGrid.ColumnDefinitions.Count,
                            string.Format("Column {0} not defined on the parent Grid!", col));
                        Debug.WriteLine(
                            "\tColumn: {0} ({1})",
                            col,
                            parentGrid.ColumnDefinitions[col].Width);
                    }

                    if (parentGrid.RowDefinitions.Count != 0 || row != 0)
                    {
                        Debug.Assert(
                            row < parentGrid.RowDefinitions.Count,
                            string.Format("Row {0} not defined on the parent Grid!", row));
                        Debug.WriteLine(
                            "\tRow: {0} ({1})",
                            row,
                            parentGrid.RowDefinitions[col].Height);
                    }
                }

                if (frameworkElement.Parent is Canvas)
                {
                    var x = Canvas.GetLeft(frameworkElement);
                    var y = Canvas.GetTop(frameworkElement);
                    var zIndex = Canvas.GetZIndex(frameworkElement);

                    Debug.WriteLine("\tCanvas - X={0}, Y={1}, ZIndex={2}", x, y, zIndex);
                }
            }
        }
        #endregion

        #region BrushToString()
        private static string BrushToString(Brush brush)
        {
            if (brush == null)
                return "";

            var solidColorBrush = brush as SolidColorBrush;

            if (solidColorBrush != null)
            {
                return string.Format("SolidColorBrush: {0}", solidColorBrush.Color);
            }

            var imageBrush = brush as ImageBrush;

            if (imageBrush != null)
            {
                var bi = imageBrush.ImageSource as BitmapImage;

                if (bi != null)
                {
                    return string.Format(
                        "ImageBrush: {0}, UriSource: {1}",
                        bi,
                        bi.UriSource);
                }

                return string.Format("ImageBrush: {0}", imageBrush.ImageSource);
            }

            return brush.ToString();
        }
        #endregion
    }
}
#endif
Tagged , , , , ,

The quest for a Bindable ApplicationBar – Part 2

Seems like the application bar finally works for predefined buttons. Next step – binding to ItemsSource-like view model collections for buttons and menu items and getting “ElementName bindings” to work…

For now – this will have to be it. I am sharing my library and test projects here.

Continue reading

Tagged , , , , , , , , ,

Workaround for binding not supported on Style/Setter/Value in Silverlight

This morning I was trying to bind the Orientation property of a PanoramaItem to a panorama item view model bound to the Panorama through its ItemsSource property and kept getting this weird exception when Silverlight was parsing the xaml stating that it “Cannot set read-only property”. I tried working around that and have some sort of attached property that would be bound to Orientation property of the view model and update the PanoramaItem’s Orientation property, but that produced the same result…

Well, it just so turns out – it is one of those things that are supported in WPF, but not in Silverlight

As a workaround – I created some attached dependency properties that are not bound to the view model themselves, but specify just the binding path and when set – create a binding to the PanoramaItem properties – as below…

public static class BindingBuilder
{
    #region PanoramaItemOrientation
    /// <summary>
    /// PanoramaItemOrientation Attached Dependency Property
    /// </summary>
    public static readonly DependencyProperty PanoramaItemOrientationProperty =
        DependencyProperty.RegisterAttached(
            "PanoramaItemOrientation",
            typeof(string),
            typeof(BindingBuilder),
            new PropertyMetadata(null, OnPanoramaItemOrientationChanged));

    /// <summary>
    /// Gets the PanoramaItemOrientation property. This dependency property
    /// indicates the binding path for the PanoramaItem.Orientation binding.
    /// </summary>
    public static string GetPanoramaItemOrientation(DependencyObject d)
    {
        return (string)d.GetValue(PanoramaItemOrientationProperty);
    }

    /// <summary>
    /// Sets the PanoramaItemOrientation property. This dependency property
    /// indicates the binding path for the PanoramaItem.Orientation binding.
    /// </summary>
    public static void SetPanoramaItemOrientation(DependencyObject d, string value)
    {
        d.SetValue(PanoramaItemOrientationProperty, value);
    }

    /// <summary>
    /// Handles changes to the PanoramaItemOrientation property.
    /// </summary>
    private static void OnPanoramaItemOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        string oldPanoramaItemOrientation = (string)e.OldValue;
        string newPanoramaItemOrientation = (string)d.GetValue(PanoramaItemOrientationProperty);
        var panoramaItem = (PanoramaItem)d;

        panoramaItem.SetBinding(PanoramaItem.OrientationProperty, new Binding(newPanoramaItemOrientation));
    }
    #endregion

    #region PanoramaItemHeader
    /// <summary>
    /// PanoramaItemHeader Attached Dependency Property
    /// </summary>
    public static readonly DependencyProperty PanoramaItemHeaderProperty =
        DependencyProperty.RegisterAttached(
            "PanoramaItemHeader",
            typeof(string),
            typeof(BindingBuilder),
            new PropertyMetadata(null, OnPanoramaItemHeaderChanged));

    /// <summary>
    /// Gets the PanoramaItemHeader property. This dependency property
    /// indicates the binding path for the PanoramaItem.Header binding.
    /// </summary>
    public static string GetPanoramaItemHeader(DependencyObject d)
    {
        return (string)d.GetValue(PanoramaItemHeaderProperty);
    }

    /// <summary>
    /// Sets the PanoramaItemHeader property. This dependency property
    /// indicates the binding path for the PanoramaItem.Header binding.
    /// </summary>
    public static void SetPanoramaItemHeader(DependencyObject d, string value)
    {
        d.SetValue(PanoramaItemHeaderProperty, value);
    }

    /// <summary>
    /// Handles changes to the PanoramaItemHeader property.
    /// </summary>
    private static void OnPanoramaItemHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        string oldPanoramaItemHeader = (string)e.OldValue;
        string newPanoramaItemHeader = (string)d.GetValue(PanoramaItemHeaderProperty);
        var panoramaItem = (PanoramaItem)d;

        panoramaItem.SetBinding(PanoramaItem.HeaderProperty, new Binding(newPanoramaItemHeader));
    }
    #endregion
}

Now I can have my Panorama built dynamically from its ItemsSource binding while still supporting setting of the PanoramaItems’ orientation and header through binding:

<Controls:Panorama
    DataContext="{Binding Panorama}"
    ItemsSource="{Binding Items}"
    Title="{Binding Title}"
    Background="{Binding Background}">
    <Controls:Panorama.ItemContainerStyle>
        <Style
            TargetType="Controls:PanoramaItem">
            <Setter
                Property="CacheMode"
                Value="BitmapCache" />
            <Setter
                Property="HorizontalContentAlignment"
                Value="Stretch" />
            <Setter
                Property="VerticalContentAlignment"
                Value="Stretch" />
            <Setter
                Property="local:BindingBuilder.PanoramaItemOrientation"
                Value="Orientation" />
            <Setter
                Property="local:BindingBuilder.PanoramaItemHeader"
                Value="HeaderText" />
            <Setter
                Property="Template">
                <Setter.Value>
                    <ControlTemplate
                        TargetType="Controls:PanoramaItem">
                        <Grid
                            Background="{TemplateBinding Background}"
                            Margin="12,0,0,0″>
                            <Grid.RowDefinitions>
                                <RowDefinition
                                    Height="auto" />
                                <RowDefinition
                                    Height="*" />
                            </Grid.RowDefinitions>
                            <ContentControl
                                x:Name="header"
                                ContentTemplate="{TemplateBinding HeaderTemplate}"
                                Content="{TemplateBinding Header}"
                                FontSize="{StaticResource PhoneFontSizeExtraExtraLarge}"
                                FontFamily="{StaticResource PhoneFontFamilySemiLight}"
                                HorizontalAlignment="Left"
                                Margin="10,-2,0,26″>
                                <ContentControl.RenderTransform>
                                    <TranslateTransform
                                        x:Name="headerTransform" />
                                </ContentControl.RenderTransform>
                            </ContentControl>
                            <ContentPresenter
                                Content="{TemplateBinding Content}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                Margin="{TemplateBinding Padding}"
                                Grid.Row="1″
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Controls:Panorama.ItemContainerStyle>
</Controls:Panorama>

Then again – you could use the generic solution…

Tagged , , , , , , , ,

The quest for a Bindable ApplicationBar – Part 1

The funny thing about MVVM is that you might get so hooked on it that when you find something that just does not work with MVVM – you start trying to figure out how to bend it to the right path. One of such things is the ApplicationBar on Windows Phone.

Continue reading

Tagged , , , , , , , , ,

Image.NineGrid in WinRT

WinRT adds this sweet new property for an Image control called NineGrid. It simplifies using images as frames around a content that does not have predefined dimensions or when you want to use a simple image that is smaller than the end result frame, but is stretched in some parts.

 

The below sample has a reference, Image control with unscaled bitmap – a white 100×100 rectangle with a big circle aligned to all its borders and small circles in each of the corners. It also has a Grid with some sample controls within it, layed out with a margin of 50 on each side and an Image control as a background with the same bitmap used as in the reference image, but stretched in such a way, that the quarters (50×50) of the original big circle form corners of a frame and the frame sides are just stretched pixels from the vertical and horizontal cross sections of the bitmap crossing in the middle of the source bitmap.

<Grid
    x:Name="LayoutRoot">
    <!– Background –>
    <Rectangle
        Fill="White" />
       
    <!– Reference Image –>
    <Image
        Source="/Images/Frame.png"
        VerticalAlignment="Top"
        HorizontalAlignment="Left"
        Stretch="None" />
       
    <!– Grid containing the frame in the background and some controls inside –>
    <Grid
        VerticalAlignment="Center"
        HorizontalAlignment="Center"
        MinHeight="100"
        MinWidth="100">
        <!– Reference image –>
        <Image
            Source="/Images/Frame.png"
            NineGrid="50" />
        <!– Sample controls –>
        <StackPanel
            Margin="50"
            VerticalAlignment="Top"
            HorizontalAlignment="Left">
            <TextBlock>TextBlock</TextBlock>
            <TextBox
                Text="TextBox"/>
        </StackPanel>
    </Grid>
</Grid>

Result:

image

As you can see – the ornaments at the corners of the source image have preserved dimensions, while the frame can stretch to any size as long as it is bigger than 100×100. Note the MinWidth and MinHeight properties on the Grid – the image won’t stretch to be smaller than the frame of the nine grid!

Another place to look at a good description of a nine-grid is in another SDK – for Windows Media Center, that has a similar control – here.

Tagged , , , ,

Windows RunTime – Timeline of Influences

(Note – while I work for Microsoft, my team was not involved in developing the technologies mentioned below and the thoughts and opinions on this blog are mine only)

This is what Microsoft showed at Build:

image

Microsoft at its spirit – really trying to support everything and everyone – the slide is actually oversimplified, but the Desktop Apps part seems to encompass and indicate support for all the legacy apps, languages and APIs, while Metro style (or Immersive) Apps support the same languages on top of a new set of APIs. Whichever language you used before – you can still use it to create desktop or web applications as well as the new Metro style apps. The APIs are different, but seem to be highly influenced by the .NET technologies.

Thinking about the above made me think about all the influences that brought the above to life. Here’s a timeline I came up with:

image

Complicated? You bet!

Timeline: the blocks should be placed fairly chronologically top to bottom.
Dates: were picked arbitrarily from Wikipedia based on dates of initial public appearance or if available – on release dates of the APIs/frameworks/host environments.
Colors:
L
ight blue (aqua) blocks represent languages, with the shaded ones being the languages available for use with WinRT.
Purple blocks represent Windows API and frameworks that wrap its UI components.
Dark blue blocks show DirectX, DX-based WPF and WPF derived Silverlight (desktop and mobile).
Arrows indicate successors (eg. Winforms –> WPF), dependencies (eg. DX –> WPF) or influences successors (eg. VCL –> WinForms).

Tagged , , , , , , , , ,

Batch script to compile pixel shaders + mixing batch & C#

If you want to build a pixel shader for WPF there are some good examples and tools – some of which are:

  • NShader – that lets you edit HLSL code in VS with syntax highlighting
  • Shazzam – that helps edit and quickly test HLSL code + provides a few samples + generates WPF C#/VB wrapper classes automatically
  • Shader Effect BuildTask – that makes the shader build automatically when you build your project

The build task is a helpful thing, since it builds the effect every time you build your project, so your shader source code is treated the same way your C# source is but not really so helpful if you want to share your code with someone who does not necessarily have DirectX SDK or the build task installed – since it will break their build. That is why I usually include both the fx source code and the compiled shader in my VS projects – this also lets me dig up my old WPF projects and build them without the need for having DirectX SDK installed, since I write shaders less frequently than I set up new dev. machines.

Now, I do not want to remember the fxc.exe build commands or manually compile each shader, so I also include a batch script in the shaders folder that I can manually trigger when I modify and want to recompile a shader.

Since even minor changes in your shader files are error prone – I wanted to have a clear message in my script to so I know if my compiler worked without having to read all output. When I first wrote it I thought I could use colors – green for success and red for failure, but I found setting these on a per-line basis is not supported in regular command-line windows, so I just used full screen color changes “color 0A” for green and “color 0C” for red.

Today I wanted to play with shaders again and as I looked at that script I remembered I found some interesting code here (copied from here) one day, that allows you to have a single file with batch script and C# code. I found a few lines of C# code on StackOverflow that let you change the colors in the console window and here is what I have:

Note 1: This script requires DirectX SDK to be installed.

Note 2: This would probably be easier in PowerShell and I might port it one day, but it was just more interesting to me to do it this hacky way. + I don’t really know PowerShell or if it is available everywhere yet.

/* >NUL
@REM Open the containing folder in Windows Explorer and double click this file to compile shader
CLS
@CALL :COMPILE_CECHO %0
@CALL :COMPILE_FX HueEffect.fx HueEffect.ps
@DEL /q cecho.exe
@GOTO :EOF

*/
using System;
using System.Linq;

class cecho
{
    static void Main(string[] args)
    {
        try
        {
            Console.BackgroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), args[0], true);
            Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), args[1], true);
            Console.WriteLine(string.Join(" ", args.Skip(2)));
            Console.ResetColor();
        }
        catch
        {
            Console.WriteLine("Usage: cecho background foreground text\r\nColors:");
            foreach (var name in Enum.GetNames(typeof(ConsoleColor)))
                Console.WriteLine(name + @": " + (int)Enum.Parse(typeof(ConsoleColor), name));
            return;
        }
    }
}

/*
More batch code follows:

:COMPILE_CECHO
@SET WinDirNet=%WinDir%\Microsoft.NET\Framework
@IF EXIST "%WinDirNet%\v2.0.50727\csc.exe" set csc="%WinDirNet%\v2.0.50727\csc.exe"
@IF EXIST "%WinDirNet%\v3.5\csc.exe" set csc="%WinDirNet%\v3.5\csc.exe"
@IF EXIST "%WinDirNet%\v4.0.30319\csc.exe" set csc="%WinDirNet%\v4.0.30319\csc.exe"
@%csc% /nologo /out:"cecho.exe" %1
@GOTO :EOF

:COMPILE_FX
@SET fxc="%DXSDK_DIR%Utilities\bin\x86\fxc.exe"
@SET FXCPARAMS=/nologo /T ps_2_0 /E main /Fo%2 %1
@REM ECHO %FXC% %FXCPARAMS%
@%FXC% %fxcparams% 1> NUL
@IF [%ERRORLEVEL%] EQU [0] (cecho 0 10 %1 - COMPILATION SUCCESSFULL!) ELSE (cecho 0 12 %1 - ERROR! FIX SHADER!)
@GOTO :EOF
*/

Tagged , , , ,
Advertisements