Archive

Posts Tagged ‘WPF’

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:

WPF NotifyIcon 1.0.1 – Minor Improvements, Major Tutorial

May 15th, 2009

I just posted an upgrade to my WPF NotifyIcon, which adds some minor improvements to the control. The most important one is probably the simplified data binding support for context menus (thanks to Nic Pillinger for the hint), but I also managed to add some polish in a few other areas.

 

image

 

Apart from the updated control itself, I completely revamped the sample project. It’s no longer just a showcase but contains various standalone samples which cover all aspects of the control. And last but not least, I published a complementary tutorial on the CodeProject. One could say I was quite busy ;)

 

Further information and download on the project page:
http://www.hardcodet.net/projects/wpf-notifyicon

Using Attached Events to Trigger Animations in WPF

May 8th, 2009

This is a pattern I applied when implementing the WPF NotifyIcon component in order to provide animation support for popups, tooltips, and balloon messages. The problem I had to solve was the loose coupling between the NotifyIcon and displayed controls:

 

image

Accordingly, I didn’t know anything about these controls at runtime. Nonetheless, I wanted to provide a communication channel to inform that UIElement that it is being displayed. And I wanted to do it declaratively.

Attached Events to the Rescue

Enter attached events. Just like the better known attached properties, they can be declared in a static class and attached to arbitrary dependency objects. Accordingly, a control X does not need to declare an event itself in order to raise it.

If you are working with Expression Blend, chances are high that you are already using attached events quite often. As an example, the Mouse.MouseDown attached event that lets you trigger an animation if the user clicks on an arbitrary control. And nothing stops you from defining your own custom events :-)

Creating a Sample Application

Let’s create a simple sample. The scenario is the following:

  • Sometimes, some kind of critical event occurs (simulated through a button click).
  • Every time this happens, we want a “status control” to show an alarm.

We will implement this status control purely in XAML – an attached event will trigger an animation that displays a warning sign:

image

 

Read more…