Blend for Visual Studio Workspace (XAML)

In my previous post, I  introduced you to Blend for Visual Studio and talked about Project templates and Item templates. Now that you are set with your templates its time to understand blend workspace better. This is going to be your playground for designing and creating some stunning animations. This post will concentrate on the workspace that Blend provides when your project is in XAML.

 

Blend Workspace:

Blend-for-Visual-Studio-Workspace

There are two default workspaces in Blend

  • Deign Workspace
  • Animation Workspace
  • You can switch between the two by clicking on Window > Workspaces or by Ctrl+F11. These workspaces are customizable so you can change panel orientation, dock or float , or resize panels as per your need. You can also change the theme of the entire workspace by clicking Tools > Options > Workspace > Theme.

Panels:

 

Tools Panel

Tools panel contains the most handy tools for designing the UI elements. Some tools that are included are Selection, Direct Selection, Pan, Zoom, Eyedropper, Paint Bucket, etc.. You will notice that some of the section in tools panel have a small white triangle on the lower right corner. This is an indication that if you click and hold you will get additional option of related tools.

Assets Panel

Assets panel lists all the controls, styles, shapes, media, categories, and locations. Controls in assets also include Windows 8 specific controls like AppBar, GridView, FlipView etc. The search box in the assets panel is a handy feature. Alternatively you can access the Assets panel from the tools panel(the last button), it will contain your recently accessed assets.

Artboard:

Artboard is your work surface where you visually design a page of your application. On the top right corner you will find the view buttons. Use these to switch between Design, Code,  and split views. On the bottom left corner you will find Artboard controls like Zoom, Show snap grid, Snap to gridlines and Turn off snapping to snaplines. Learn more about snapping here.

Objects and Timeline Panel:

Objects and Timeline panel helps you in viewing the hierarchical structure of objects in the artboard. You can modify them directly by dragging them from one position and dropping them to the desired position to form the intended structure. You can add animation to your application by simply creating a new Storyboard by clicking the + button. Storyboards are containers that hold animation timelines. Learn more about adding animations here.

Properties Panel:

If you are a Visual Studio developer then Properties panel is not a new thing to you! It is the place where you view and modify properties of an object that is selected on the artboard.

Few other panels, you should know about:

  • Projects Panel – Lists all the information about your project. Similar to Visual Studio Solutions Explorer
  • Resources Panel – Lists all the resources that are used in the current project. You can drag the resource to the artboard to apply them to an object
  • Results Panel – Results panel consists of two tabs. Error Tab – Displays build and parse errors. Output Tab – Provides build information when you build, rebuild, clean or test a project.

Summary

 

Windows 8 has been reimagined from chipset to the user experience and hence it demands every store app developers to follow strict UI design principles. Blend is a great tool to start with. It helps you design stunning apps and also eases out in wiring up animations. So go ahead sweat the details and create a fast & fluid app.

-Nish-

@nishanil on twitter

Windows 8 Developers – Do you “Blend for Visual Studio”?

Blend-for-Visual-StudioNewest release of Blend now supports UX authoring for Windows 8 store apps both in XAML and HTML. The good news is that if you are a Windows 8 store apps developer then you can make use of Blend for Visual Studio 2012 which is included as part of the Visual Studio 2012 installation. More to it – you get this cake even if you download the Visual Studio Express 2012 for Windows 8 which is of-course free!

Windows 8 store apps much like Windows phone compels a developer to follow the Metro Design Principles. “Metro” as it was formally known as; “Windows 8-style UI” from now on!. With the UX guidelines in place for Windows 8 app development, it is also important to have an UX authoring tool like Blend to be part of the developer’s machine along with Visual Studio.

Blend clearly is a tool for building awesome User Interface Design. Blend lets designers focus on design while letting developers focus on logic of the UI. Blend until the last release was specifically targeted for designing front-end XAML based interfaces for WPF and Silverlight. But “Blend for Visual Studio” has clear targets – Designing Windows 8 Store Apps in XAML/HTML. It adds support to some awesome Win 8 features like App Bars, Grid view and View States. It also supports native C++ app development.

Beyond providing simple XAML/HTML designers and editing support, Blend gives you tools that help you configure UI elements, author complex animation sequences(XAML),  create user controls from vector graphics(XAML), customize visual states(XAML) etc. In HTML it provides some cool way of editing Style Rules, CSS Properties, HTML attributes and Live DOM.

Getting Started with Blend:

Start a New Project and choose your design language first. If you are a web developer and starting a hands-on with Windows development then you can choose HTML and Javascript as your language. Like me if you are a XAML developer, then prefer XAML, you will feel at home.

Project Templates:

 

Blend-for-Visial-Studio-New-Project-XAML-HTML

 

Blend provides you with templates to speed up your app development just like Visual Studio. Three important project templates available for both HTML and XAML are:

  • Blank App – As the name – just a blank project. I almost always use this template and then add Item templates based on my project needs.
  • Grid App – A project that displays groups of data in a grid format. If you are creating an app that displays group of items for e.g. a shopping app or a news app then start with this template. A grid app defaults to a home page that shows a list of groups – basically a set of items. When the user selects a particular group another page opens with group details which will have the list of items of the selected group.
  • Split App – A project that displays a master/detail list. For e.g. News app that contains headlines on top and when clicked displays the full content.
    I almost always use Blank App as my project template and then add Item Templates based on my project need.

For HTML project there are two more templates you can make use of:

  • Fixed Layout App – Fixed Layout provides similar template to Blank App except that its viewport is fixed. If you are building apps that has just one interface for e.g. a simple game in Javascript, then make this choice.
  • Navigation App – Navigation App template contains Navigation Model which is recommended for Windows store apps. This template provides a home page by default. You can add more pages to it and make use of the navigation model to navigate between them.
    Item Templates:
    Blend-for-Visual-Studio-Item-Template
    Item templates can be added anytime by clicking Project > Add New Item. Depending on your project type you will presented with items that corresponds to pages in your app.  

You can read more about Project templates and Item templates here.

Now that you have made your project choice, it is time to understand the Blend workspace. In my next blog post I will cover them.

-Nish-

WPF Datagrid – Update Source on fly with BindingList<T>

 

I was under an assumption that ObservableCollection<T> works perfect with WPF DataGrid until my friend wannabeegeek came up with a strange problem. The problem was making ObservableCollection<T> update the ItemSource on fly while editing them. What’s the big deal right? Wrong.

If you are using MVVM you do not want to wire up the event on DataGrid for an updated source. You will very much think that as long as you bind the collection to the ViewModel’s property and the mode is set to TwoWay – the source is updated automatically when items are edited in the DataGrid.

Your ViewModel will fire the property changed when the collection itself changes – that is if you replace the property itself.  So if you want to know the change in items of the collection you need to subscribe to the CollectionChanged event of the ObservableCollection<T> property in your ViewModel.

MSDN says:

Occurs when an item is added, removed, changed, moved, or the entire list is refreshed.

But there is a problem with ObservableCollection.CollectionChanged event –  it does not fire when your data item’s property changes. It fires only if the entire item is replaced. That is if you have a collection of an Entity “Expense” that has properties “Name” and “Amount” and if you simply change the Amount value in the grid it does not work! You need to replace the entire “Expense” object for you to see the collection change firing up. 

After googling and reading msdn forums I gave up on ObservableCollection<T> and picked up BindingList<T> to do the job.  Here is a demo that explains all the stuff:

.. and the screen shot:

ExpenseView

I have a DataGrid that is simply bound to an “BindingList<Expense>”. Right below that I have a Total that is bound to the “TotalExpense” property. Now here is what I wanted to do – Whenever user edits the amount in the Grid the Total should be calculated as he/she tabs out.

.. and the ViewModel with the solution:

  1. public class DataGridDisplayViewModel : ViewModelBase
  2.     {
  3.         private BindingList<Expense> _expenses;
  4.         private double _totalExpense;
  5.  
  6.         public double TotalExpense
  7.         {
  8.             get { return _totalExpense = _expenses.Sum(x => x.Amount); }
  9.             set { _totalExpense = value; }
  10.         }
  11.         
  12.         public BindingList<Expense> Expenses
  13.         {
  14.             get { return _expenses; }
  15.             set
  16.             {
  17.                 _expenses = value;
  18.                 if (_expenses != null)
  19.                 {
  20.                     _expenses.ListChanged += (o, e) => RaisePropertyChanged(() => this.TotalExpense);
  21.                 }
  22.                 RaisePropertyChanged(() => this.Expenses);
  23.             }
  24.         }
  25.  
  26.       
  27.         public DataGridDisplayViewModel()
  28.         {
  29.             Expenses = new BindingList<Expense>
  30.                             {
  31.                                 new Expense() {Name = "Gas", Amount = 1000},
  32.                                 new Expense() {Name = "Electricity", Amount = 1000},
  33.                                 new Expense() {Name = "Internet", Amount = 100},
  34.                                 new Expense() {Name = "Water", Amount = 100},
  35.                                 new Expense() {Name = "Misc", Amount = 1000}
  36.                             };
  37.         }
  38.     }

The TotalExpense getter simply calculates the sum. And the ListChanged event of Expenses property simply notifies the change in TotalExpense.

.. and in the View:

  1. <Grid>
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition/>
  4.         <RowDefinition/>
  5.     </Grid.RowDefinitions>
  6.     <DataGrid ItemsSource="{Binding ExpensesOb, Mode=TwoWay}" AutoGenerateColumns="True" Grid.Row="0"/>
  7.     <TextBlock Grid.Row="1">
  8.         <Run Text="Total: "/>
  9.         <Run Text="{Binding TotalExpenseOb}"/>
  10.     </TextBlock>
  11. </Grid>

 

That’s it!

Download the full code here. The code contains a tiny MVVM framework(inside core folder). – Read the disclaimer of the blog before you play with my code.

If you know to achieve this exact behavior with ObservableCollection do make a comment to this post and let me know!

/*Nish*/

Attached Behaviors & MVVM

When you think of MVVM and other patterns involved, it is often about separation of concerns as much as possible, unit testability and code maintainability. These type of patterns help in high quality of code and efficient development of business functionality. If you are new to MVVM then you may want to check out some of the articles by various intellects like Josh Smith, Laurent Bugnion and few others from XAML Disciples group(or just Google Smile).

There are lot many frameworks on MVVM out there and to be frank there isn’t any right or the wrong one. You need to evaluate and decide on the one that fits your need! Most often people land up writing one on their own and in a way it is good!

I personally like a framework written by Brette Esterbrooks because it is a skeleton of code that you need and helps you get started. I tweaked it a bit(basically removed the ones that I don’t need) and thus the sample attached on this blog will have a tiny little framework of MVVM.

All it has is just a few helper classes:

  1. ViewBase,
  2. ViewModelBase,
  3. RelayCommand,
  4. ObservableObject.

Attached Behaviors

 

Attached behavior is achieved by simply attaching a behavior to a control that otherwise wouldn’t have anything of its own.

And as per Josh Smith-

The idea is that you set an attached property on an element so that you can gain access to the element from the class that exposes the attached property. Once that class has access to the element, it can hook events on it and, in response to those events firing, make the element do things that it normally would not do. It is a very convenient alternative to creating and using subclasses, and is very XAML-friendly.

Ever since I am hooked to MVVM pattern, I try and avoid all the code that usually goes to the code behind. For e.g. a click event handler usually written in the code behind can be omitted and a RelayCommand in the ViewModel be used instead.

But what would happen if you want to handle a double click or a focus event of a control? Just retaining those kind of events to the code behind defeats the pattern itself. And thus Attached Behavior comes to rescue! Demo included in this post explains the DragDropBehavior.

Before you go further with this approach, I just want you to know that you can achieve this by Behavior<T> class included in the system.windows.interactivity.dll. However this dll is available only through Expression Blend installation.

In my demo I have explained both of the implementation and it’s usage. Here we go!

Screenshot of the Demo:

 

AttachedBImage

 

IBehavior

 

The view models can hold the reference of this contract and change at runtime if needed:

  1. public interface IBehavior
  2.     {
  3.         void OnEnabled(DependencyObject dependencyObject);
  4.         void OnDisabling(DependencyObject dependencyObject);
  5.     }

 

 

AttachedBehavior – A static class!

 

A static class AttachedBehavior is introduced which holds the attached properties “Behavior” and “IsEnabled”.

When toggled from Enabled state to Disabled State – OnDisabling() method of the IBehavior is called. Use this method to unwire your event handlers.

 

  1. /// <summary>
  2.         /// Attach a Behavior of type IBehavior
  3.         /// </summary>
  4.         public static readonly DependencyProperty BehaviorProperty = DependencyProperty.RegisterAttached("Behavior", typeof(IBehavior), typeof(AttachedBehavior), new UIPropertyMetadata(null));
  5.  
  6.         /// <summary>
  7.         /// Is Enabled, when set to true, fires Behaviors OnEnabled Method
  8.         /// </summary>
  9.         public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(AttachedBehavior), new UIPropertyMetadata(false, OnIsEnabledChanged));
  10.  
  11.         /// <summary>
  12.         /// Handles IsEnabledChanged
  13.         /// </summary>
  14.         /// <param name="d"></param>
  15.         /// <param name="e"></param>
  16.         private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  17.         {
  18.             if (d == null)
  19.                 return;
  20.             var behavior = GetBehavior(d);
  21.             if (behavior == null)
  22.                 return;
  23.             if ((bool)e.NewValue)
  24.                 behavior.OnEnabled(d);
  25.             else
  26.                 behavior.OnDisabling(d);
  27.         }

 

DragDropBehavior Class

 

DragDropBehavior class implements the IBehavior. Have a look at the OnEnabled and OnDisabling methods.

  1. public class DragDropBehavior : IBehavior
  2.     {
  3.         #region Private Fields
  4.         private Point _startPosition;
  5.         private Point _mouseStartPosition;
  6.         private TranslateTransform _translatetransform;
  7.         private UIElement _associatedObject = null;
  8.         private Window _parent = null;
  9.         #endregion
  10.  
  11.         #region IBehavior Members
  12.         public void OnEnabled(DependencyObject dependencyObject)
  13.         {
  14.             var uiElement = dependencyObject as UIElement;
  15.             if (uiElement == null)
  16.                 return;
  17.             
  18.             _associatedObject = uiElement;
  19.             //TODO: set the parent accordingly
  20.              _parent = Application.Current.MainWindow;
  21.             _translatetransform = new TranslateTransform();
  22.             _associatedObject.RenderTransform = _translatetransform;
  23.             _associatedObject.MouseLeftButtonDown += AssociatedObjectMouseLeftButtonDown;
  24.             _associatedObject.MouseLeftButtonUp += AssociatedObjectMouseLeftButtonUp;
  25.             _associatedObject.MouseMove += AssociatedObjectMouseMove;
  26.         }
  27.         
  28.         public void OnDisabling(DependencyObject dependencyObject)
  29.         {
  30.             _associatedObject.MouseLeftButtonDown -= AssociatedObjectMouseLeftButtonDown;
  31.             _associatedObject.MouseLeftButtonUp -= AssociatedObjectMouseLeftButtonUp;
  32.             _associatedObject.MouseMove -= AssociatedObjectMouseMove;
  33.             _translatetransform = null;
  34.         }
  35.         #endregion
  36.  
  37.         #region Event Handlers
  38.         void AssociatedObjectMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
  39.         {
  40.             _startPosition = _associatedObject.TranslatePoint(new Point(), _parent);
  41.             _mouseStartPosition = e.GetPosition(_parent);
  42.             _associatedObject.CaptureMouse();
  43.         }
  44.         
  45.         void AssociatedObjectMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
  46.         {
  47.             var positionDifference = e.GetPosition(_parent) – _mouseStartPosition;
  48.             if(_associatedObject.IsMouseCaptured)
  49.             {
  50.                 _translatetransform.X = positionDifference.X;
  51.                 _translatetransform.Y = positionDifference.Y;
  52.             }
  53.         }
  54.  
  55.         void AssociatedObjectMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
  56.         {
  57.             _associatedObject.ReleaseMouseCapture();
  58.             
  59.         }
  60.         
  61.         #endregion
  62.  
  63.  
  64.     }

 

HelloView

 

Attach is the behavior to the control that you want to drag:

  1. <ToggleButton Name="dragDropToggleButton" Command="{Binding ToggleDragDropBehavior}" Width="200">
  2.                 <ToggleButton.Style>
  3.                     <Style TargetType="{x:Type ToggleButton}">
  4.                         <Setter Property="Content" Value="Start Dragging"/>
  5.                         <Style.Triggers>
  6.                             <Trigger Property="IsChecked" Value="True">
  7.                                 <Setter Property="Content" Value="Stop Dragging"/>
  8.                             </Trigger>
  9.                         </Style.Triggers>
  10.                     </Style>
  11.                 </ToggleButton.Style>
  12.             </ToggleButton>
  13.  
  14.  
  15.    
  16.               <TextBlock Background="Gold"
  17.                        Text="dragMe using attached behavior"
  18.                        Behaviors:AttachedBehavior.IsEnabled="{Binding IsDragBehaviorEnabled}"
  19.                        Behaviors:AttachedBehavior.Behavior="{Binding DragDropBehavior}"
  20.                        Canvas.Left="32"
  21.                        Canvas.Top="31" />

 

HelloViewViewModel

 

And finally the ViewModel that set’s the DragDropBehavior:

  1. public class HelloViewViewModel : ViewModelBase
  2.     {
  3.         private IBehavior _dragDropBehavior;
  4.         private bool _isDragBehaviorEnabled;
  5.  
  6.         public bool IsDragBehaviorEnabled
  7.         {
  8.             get { return _isDragBehaviorEnabled; }
  9.             set { _isDragBehaviorEnabled = value; RaisePropertyChanged(()=> this.IsDragBehaviorEnabled); }
  10.         }
  11.  
  12.         public IBehavior DragDropBehavior
  13.         {
  14.             get { return _dragDropBehavior; }
  15.             set { _dragDropBehavior = value; RaisePropertyChanged(() => this.DragDropBehavior); }
  16.         }
  17.  
  18.         public RelayCommand ToggleDragDropBehavior { get; set; }
  19.  
  20.         public HelloViewViewModel()
  21.         {
  22.             DragDropBehavior = new DragDropBehavior();
  23.             ToggleDragDropBehavior = new RelayCommand(() =>
  24.             {
  25.                 IsDragBehaviorEnabled = !IsDragBehaviorEnabled;
  26.             });
  27.  
  28.         }
  29.     }

 

That’s It – you are done!! Refer DragDropBehavior2 class for implementation using Behavior<T>.

Download the Code – Read the Disclaimer of this blog before you work with this code!

/*Nish*/

Windows 8 on VirtualBox– File Sharing(Guest Additions doesn’t work)

Guest Additions on Virtual Box can be installed by changing compatibility to Windows 7 but that doesn’t mean it can be made to work. Yeah that’s where I too got stuck and my hunt for a fix to it also stopped when I read this forum.

I found few others who have tried complicated file sharing techniques, for e.g. they  created a secondary virtual hard drive and put files into it. However being working on Windows for more than a decade, I do believe there should be a simple way to achieve it. After all they are two different windows machines on the network.

Well what would you do to access a share drive on another system? Start->Run-> and type “\\machine-name\share” and hit enter?  That wouldn’t work because your host machine name will not be recognized by your virtual machine since they are on a different network group.

Now here is the solution: Go ahead and figure out the IP address of your host machine(ipconfig) and try accessing the share by its IP address instead of the machine name. That works!

 

Access

Things are simple, we complicate it most of the time.

 

/* Nish */

WPF XML Browser Control

Ever wondered how to get a IE like look and feel of the xml in the default WPF web browser control? If your answer is – “Just navigate the Web Browser to the xml path”; You are right! But if you have to navigate to a in-memory xml? Read on to know and apply IE like styling for xml stored in a string variable.

Idea of writing a custom based xml browser control came in because I had a requirement to edit the xml on fly and validate it against a specified schema. User is allowed to edit only the standard xml(compiled as an embedded resource) that the tool provides and not navigate to any path.

This control helps you:

  1. Load the xml from the string and apply IE like styling
  2. Edit the xml
  3. Validate the xml against the defined schema

Before I go further, here is what you get:

image

The problem with web browser when navigating to a string is that it does not load the style for it. Hence the work around is to transform the xml and navigate to it. To do so you need the Xslt that IE uses. After googling for “xml pretty print”, I finally got one originally written by Jonathan Marsh of Microsoft for IE5 and modified by Steve Muench for conversion to XSLT 1.0 REC.  Copy the xml from here.

And here is the code to transform it:

/// <summary>
        /// Executes when XmlDoc DP is changed, Loads the xml and tranforms it using XSL provided
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        public static void OnXmlDocChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var browserControl = d as XmlBrowserControl;
            if (browserControl == null) return;
            var xmlString = e.NewValue as string;
            
            try
            {

                var xmlDocument = new XmlDocument();

                var xmlDocStyled = new StringBuilder(2500);
                // mark of web – to enable IE to force webpages to run in the security zone of the location the page was saved from
                // http://msdn.microsoft.com/en-us/library/ms537628(v=vs.85).aspx
                xmlDocStyled.Append("<!– saved from url=(0014)about:internet –>");

                var xslt = new XslCompiledTransform();
                //TODO: Do not forget to change the namespace, if you move the xsl sheet to your application
                var xsltFileStream =
                    typeof(XmlBrowserControl).Assembly.GetManifestResourceStream(
                        "WPFXmlBrowser.Controls.XmlBrowser.Resources.xml-pretty-print.xsl");
                if (xsltFileStream != null)
                {
                    //Load the xsltFile
                    var xmlReader = XmlReader.Create(xsltFileStream);
                    xslt.Load(xmlReader);
                    var settings = new XmlWriterSettings();
                    // writer for transformation
                    var writer = XmlWriter.Create(xmlDocStyled, settings);
                    if (xmlString != null) xmlDocument.LoadXml(xmlString);
                    xslt.Transform(xmlDocument, writer);

                }

                browserControl.EditText.Text = xmlString;
                browserControl.WebBrowser.NavigateToString(xmlDocStyled.ToString());
                browserControl.EditButton.Visibility = System.Windows.Visibility.Visible;
                browserControl.CopyClipButton.Visibility = System.Windows.Visibility.Visible;
            }
            catch (Exception ex)
            {
                browserControl.WebBrowser.NavigateToString("Unable to parse xml. Correct the following errors: " + ex.Message);
            }
        }

 

XSLT is provided as an embedded resource and it is loaded from the code. If you are moving the xslt to your project, make sure to change the namespace in the calling code.

image

You can download the code from my share here. This code works on my machine!

Feel free to modify the code, but as usual you don’t get warranty!

/*Nish*/