Archive

Posts Tagged ‘WPF’

Announcing Sketchables – Rapid Mockup Creation with SketchFlow

May 24th, 2010

SketchFlow is a great addition to Blend, but I was missing the ability to create quick mockups of user interfaces. I’m a huge fan of productivity tools such as Balsamiq, and I was sorely missing its ease and speed in SketchFlow.

Meet Sketchables. Sketchables is a simple framework complemented by a set of controls that allow you to quickly create common controls in a matter of seconds. Here’s a screenshot from one of the samples, which was created in just a few minutes:

image

 

…and here’s a complementary recording that shows how the above mockup was created:

 

 

 

Sketchables will be free software, requires Blend 4 RTM and fully supports both WPF and Silverlight SketchFlow projects. Version 1.0 is approaching completion, so I hope I’ll be able to release it as soon as Blend 4 goes live.

Still time for you to slip in some last-minute feature requests though ;)

Input Focus from the View Model - Configured via Blend Behaviors

March 17th, 2010

Background / Focus of this Article

WPF wizard and fellow WPF Disciple Josh Smith published an article yesterday that showed how to control input focus from View Model objects using attached properties and a custom binding extension. Prior to the article, there was a discussion in the Disciples group, during which I looked into using Blend behaviors as an alternative configuration approach to Josh’s markup extension – this article here discusses this approach.

Accordingly, this posting is not about controlling input focus. Josh did all the legwork there, and you should check out the article on his blog. Everything that goes beyond the Behavior classes is Josh’s work, not mine  - I merely discuss a different approach regarding the declaration of focus control on the UI using Blend Behaviors.

 

Download Source Code and Sample Application

 

Differences

Let’s start by looking at the difference from a developer’s point of view. Assume you have a simple TextBox control that is bound to a FirstName property on the View Model:

<!-- simple textbox -->
<TextBox Text="{Binding FirstName}" />

 

Markup Extensions – One for the XAML Guys / Gals

Josh’s approach using a markup extension is a very lean way to wire up your control with the focus controller. If you’re used to coding in XAML, this is pretty much the quickest way to get things running. Note that only the Binding keyword was replaced by a the custom FocusBinding markup extension:

<!-- simple textbox -->
<TextBox Text="{jas:FocusBinding FirstName}" />

 

If you’re working in Visual Studio, this is the way to go (even more so if you have ReSharper to take care of the namespace declarations for you). It might become tedious, however, if’ you’re working in a Blend environment: For one thing, there’s the namespace declarations. And then, you can no longer wire up your bindings directly in Blend on the designer surface.

 

Blend Behaviors – Designer’s Flavor

The Blend Behaviors don’t require you to write any XAML at all. The data binding itself remains unchanged, and the TextBoxFocusBehavior was just dragged/dropped on the TextBox in Blend. Accordingly, you can set up both binding and input focus control with a few mouse clicks without having to leave the designer surface:

image

 

If you look at XAML source, you’ll notice that the Behavior above actually produces substantially more markup – this isn’t something you’d want to type in manually:

<TextBox Text="{Binding FirstName}" >
    <i:Interaction.Behaviors>
        <FocusVMLib_Behaviors:TextBoxFocusBehavior/>
    </i:Interaction.Behaviors>
</TextBox>

 

In order to compare the two approaches, just download the attached sample and have a look at the two Window classes. Window1 is the original implementation (using the markup extension), Window2 uses the Blend behaviors. The end result is the same – the only difference is the different declaration approaches.

 

The Behavior Classes

The rest of this blog post discusses the implementation of the behavior classes, and suggests an approach to support different control types.

Read more…

Tags: ,

Making WPF Popups Work in Windowless Applications

September 23rd, 2009

I’ve first encountered this issue with my WPF NotifyIcon, and now again while writing a plug-in for Windows Live Writer: If you try to display a WPF popup without any Windows open (the Popup is the only UI component there is), certain controls such as TextBox, ListView, or ListBox don’t receive proper mouse and/or keyboard input, and cannot be selected.

The reason for this issue is buried in the WPF framework, and how it interacts with Windows. Fellow WPF Disciple Andrew Smith pointed me in the right direction:

 

…because a Popup’s HWND has the WS_EX_NOACTIVATE so the WPF framework will not attempt to actually focus the associated hwnd (because its usually used with a window and you don’t want to deactivate the window when you focus something in the popup).

 

Accordingly, you’ll have to fiddle with Windows Interop to make things work. Here’s the snippet:

 

public static class WinApi
{
  /// <summary>
  /// Gives focus to a given window.
  /// </summary>
  [DllImport("USER32.DLL")]
  public static extern bool SetForegroundWindow(IntPtr hWnd);

  public static void ActivatePopup(Popup popup)
  {
    //try to get a handle on the popup itself (via its child)
    HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
    IntPtr handle = source.Handle;

    //activate the popup
    SetForegroundWindow(handle);
  }
}
Tags:

Snippet Time: Helper Libraries for C# / WPF

September 14th, 2009

I just made a few minor updates to two libraries which assemble as set of helper classes for C# and WPF and thought: Why not share them? The libraries aren’t really intended to be used directly in your code, but you might find one or another helper method or snippet that might make a nice addition to your own toolbox :)

 

Hardcodet.Commons (C#, .NET 3.5)

Common helper classes and snippets (simple base classes, file management, weak events, extension methods etc.)

 

Hardcodet.Wpf.Commons (C#, .NET 3.5)

Stuff I commonly use in WPF projects, such as checking for design time, base classes for commands and converters, data binding helpers and other stuff.

 

I’ll keep these libraries up-to-date, version history will be posted here.

 

History:

2009.09.14  Initial blog release

Tags: , ,

Finding Elements in the WPF Tree - Both Ways

June 25th, 2009

A while ago I posted a helper method to traverse a (visual or logical) tree in order to find an element’s parent of a given type. The corresponding blog entry is here.

This time, I needed to search the other way: I wanted to find all descendants (direct or indirect childs) of a given element that match a given type. As a result, I came up with a complementary extension method that does the job for me:

//get all TextBox controls within the grid:
Grid container;
IEnumerable<TextBox> editors = container.FindChildren<TextBox>();

 

Usage Sample

As a sample, let’s use a window dialog which contains several images:

  • Images that were pasted into a RichTextBox control.
  • Images that are part of the UI, nested within the control hierarchy of a ribbon.

editor

 

In order to find all these Image elements you can see on the screenshot, this will do:

//start a the root (the window itself)
Window window = this;
foreach (Image img in window.FindChildren<Image>())
{
  Console.WriteLine("Image source: " + img.Source);
}

 

 

…the above snippet produces the following output:

Image source: pack://payload:,,wpf1,/Xaml/Image1.png

Image source: pack://payload:,,wpf1,/Xaml/Image2.png

Image source: pack://application:,,,/Shared/Images/Ribbon/Paste_32×32.png

Image source: System.Windows.Media.Imaging.FormatConvertedBitmap

Image source: System.Windows.Media.Imaging.FormatConvertedBitmap

Image source: pack://application:,,,/Shared/Images/Ribbon/EditUndo.png

Image source: pack://application:,,,/Shared/Images/Ribbon/EditRedo.png

Image source: pack://application:,,,/Shared/Images/Ribbon/Bold.png

Image source: System.Windows.Media.Imaging.BitmapFrameEncode

[…]

 

Accordingly, in order to analyze only the contents of the rich text editor, just start on a lower level of the tree:

//only examine the contents of the editor
RichTextBox editor = this.txtContent;
foreach (Image img in editor.FindChildren<Image>())
{
  Console.WriteLine("Image source: " + img.Source);
}

 

Implementation


(Download link at the end of the posting)


/// <summary>
/// Analyzes both visual and logical tree in order to find all elements
/// of a given type that are descendants of the <paramref name="source"/>
/// item.
/// </summary>
/// <typeparam name="T">The type of the queried items.</typeparam>
/// <param name="source">The root element that marks the source of the
/// search. If the source is already of the requested type, it will not
/// be included in the result.</param>
/// <returns>All descendants of <paramref name="source"/> that match the
/// requested type.</returns>
public static IEnumerable<T> FindChildren<T>(this DependencyObject source)
                                             where T : DependencyObject
{
  if (source != null)
  {
    var childs = GetChildObjects(source);
    foreach (DependencyObject child in childs)
    {
      //analyze if children match the requested type
      if (child != null && child is T)
      {
        yield return (T) child;
      }

      //recurse tree
      foreach (T descendant in FindChildren<T>(child))
      {
        yield return descendant;
      }
    }
  }
}

/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetChild"/> method, which also
/// supports content elements. Do note, that for content elements,
/// this method falls back to the logical tree of the element.
/// </summary>
/// <param name="parent">The item to be processed.</param>
/// <returns>The submitted item's child elements, if available.</returns>
public static IEnumerable<DependencyObject> GetChildObjects(
                                            this DependencyObject parent)
{
  if (parent == null) yield break;
  

  if (parent is ContentElement || parent is FrameworkElement)
  {
    //use the logical tree for content / framework elements
    foreach (object obj in LogicalTreeHelper.GetChildren(parent))
    {
      var depObj = obj as DependencyObject;
      if (depObj != null) yield return (DependencyObject) obj;
    }
  }
  else
  {
    //use the visual tree per default
    int count = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < count; i++)
    {
      yield return VisualTreeHelper.GetChild(parent, i);
    }
  }
}

 

For your convenience, I’ve put together a simple helper class that contains the helper methods to search for both children and parent elements in the tree:

http://www.hardcodet.net/uploads/2009/06/UIHelper.cs

 

Happy coding :)

Tags:

Beginner’s Tutorial: 3D Line and Border Effects in XAML

May 28th, 2009

This mini-tutorial might be for you if you’re having troubles finding the right line colors to achieve simple 3D effects like these:

linesamples

 

The solution to this very problem is actually pretty simple, and it always takes the same three ingredients:

  • A white line
  • A black line
  • Reduced opacity

Basically, to get an edged line on a green background, you don’t need to fiddle with different shades of green. Just use white and black lines and play with the opacity. Here’s the settings in Blend for one of the white lines in the above screenshot:

highlighted-line-settings

 

…and this is the corresponding XAML for the two vertical lines:

<Grid Background="Green">
  <Path Stretch="Fill" Stroke="#5A000000" Margin="25,62,0,0"
        Width="1" Height="100" Data="M130,176 L130,303.03543"/>
  <Path Stretch="Fill" Stroke="#5AFFFFFF" Margin="26,62,0,0"
        Width="1" Height="100" Data="M130,176 L130,303.03543"/>
</Grid>

 

Tip: Hiding Blend’s Handles

If you’re trying to format a line, Blend’s handles don’t help much, as the basically hide the whole content:

blend-handles

However - you can easily hide / show them by pressing the F9 button.

 

Tutorial: Creating a 3D Toggle Button Style

Another usage of white and black lines is a 3D effect for borders. Let’s put this to action and create a reusable style that can be applied to a ToggleButton control:

toggle-buttons 

Rather than joining four lines for each button state, I’ll use two Border controls with the same dimensions for each state, taking advantage that the BorderThickness property can be set independently for every edge. Here’s the borders for the unchecked state:

<Grid x:Name="uncheckedState">
  <Border BorderBrush="#49FFFFFF" BorderThickness="1,1,0,0"/>
  <Border BorderBrush="#49000000" BorderThickness="0,0,1,1"/>
</Grid>

 

…and here’s the borders for the checked state. Note that its Visibility property of the surrounding grid is set to Collapsed in order to hide the borders:

<Grid x:Name="checkedState" Visibility="Collapsed">
  <Border BorderBrush="#49000000" BorderThickness="1,1,0,0"/>
  <Border BorderBrush="#49FFFFFF" BorderThickness="0,0,1,1"/>
</Grid>  

 

 

I put these borders together in a simple style, which uses a trigger to switch the visibility of the two borders as soon as the IsChecked property of the ToggleButton changes:

<Style TargetType="{x:Type ToggleButton}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type ToggleButton}">
        <Grid x:Name="mainGrid" Margin="0,0,1,1">

          <Grid x:Name="uncheckedState">
            <Border BorderBrush="#49FFFFFF" BorderThickness="1,1,0,0"/>
            <Border BorderBrush="#49000000" BorderThickness="0,0,1,1"/>
          </Grid>

          <Grid x:Name="checkedState" Visibility="Collapsed">
            <Border BorderBrush="#49000000" BorderThickness="1,1,0,0"/>
            <Border BorderBrush="#49FFFFFF" BorderThickness="0,0,1,1"/>
          </Grid>   

          <!--
            WPF needs a background to toggle IsChecked
            if the ContentPresenter does not fill the whole area
          -->
          <Border Background="#00000000" />

          <ContentPresenter VerticalAlignment="Center"
                            HorizontalAlignment="Center" />

        </Grid>

        <!-- triggers toggle visual appearance -->
        <ControlTemplate.Triggers>
          <Trigger Property="IsChecked" Value="True">
            <Setter TargetName="checkedState"
                    Property="Visibility"
                    Value="Visible" />
            <Setter TargetName="uncheckedState"
                    Property="Visibility"
                    Value="Collapsed" />
            <Setter TargetName="mainGrid"
                    Property="Margin"
                    Value="1,1,0,0"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

 

 

With the style in place, you can easily declare a ToggleButton like this:

<ToggleButton Width="100" Height="24" Content="hello world" />

Tags: